電話
図書館へ行ったら、『電話はなぜつながるか』なんて本が有ったので借りてきた。姉妹編で、 『携帯電話はなぜつながるか』は、既に読んだ記憶があるな。(けど、内容忘れたよ、トホホ)
3部構成で、1部は、NTTの電話網の解説、2部はIP電話の解説、3部は携帯電話の解説に分かれて いる。3部はおまけみたいなもんで、詳しくは姉妹編へと言う誘導作戦だったよ。
この3部は、メタル回線、TCP/IP網、電波網って具合にユーザーからは見える。技術進化の歴史 でもある訳だな。当然、メタル回線での電話網が基本になるんで、一番詳しく解説されてる。 後は、diffを取った説明で、圧縮してるんだな。これぞ、RCS方式なんちゃってね。
あれ? 世の中を席巻してるGITは、イニシャルバージョンからのdiffを保持してるんだっけ? もう、そんな細かい事は忘れてしまったわい。
ついつい横道に逸れるな。電話網は、電子交換機(NTTの呼称では、D60とかD70って言うらしい) が、回線通しを繋ぐかなめになっている。電話局から個人宅の電話までは48Vの電圧がかかった 2本の線が配線されてて、そこを信号が通るって訳。だから、盗聴は簡単。ああ、話が逸れた。
電子交換機の所には、A/D変換器とD/A変換器、送信と受信の線を2本ー4本に変換する回路が 入ってる。アナログ信号をデジタルに変換するには、1秒間に8000回音声信号を測定してる。 分解精度は14ビットとか。でも、人間の耳の特性を考慮して、それを8ビットに圧縮してる。
よって、ビットレートに直すと、8000/秒 X 8ビット つう事で、64kbpsになる。これが、悪名 高いISDNの売りだったのだ。NTTにしたら、電話の音声もデジタル通信も64kBPSって言っちゃえば、 設備が共用できて好都合。だから、ADSLは普及して欲しくなかったのよ、ってのは、おいらの 深読みです。
電話交換機は、どこへ信号を流したら(接続)したらいいかなんて知らないので、電話案内に 頼ってる。これ、DNSだね。 そして、接続先が分かるとその方面の局に信号を送るとな。
そうすると、音声の流れるラインと、制御に使うライン(共通線と言うらしい)が必要になる。 これってFTPの21番ポート(制御ポート)と20番ポート(データポート)の考え方そのものじゃん。
そして電子交換機ってルーターみたいな ものです。(時間空間の交換をやるんで、ちょっと違うか) IP電話は、電子交換機の制御の代わりにSIPプロトコルなのね。データ交換自体はルーターに お任せってわけだな。
u-law
電話の音声信号は交換機の間をデジタル信号として伝播してく。伝播の効率を上げるには、なるべく 通信量が少ない方が良い。 アナログの音声信号をデジタル化する時、余り荒く行うと、音声品質が低下する。そこで考えられた のが、品質にかかわらない部分をカットしちゃえって事。
人間の耳は、大きな音がしてる時、多少変化してもそれを察知出来ないと言う特性がある。逆に、 小さい音の時は多少の変化も敏感に察知するようになっている。要するに、刺激量の対数に 反応するって事。
この特性を利用して、品質の低下を損なう事なく、信号を圧縮してるんだな。圧縮(伸張も)の 方式には、アメリカ方式(u-law,mu-law)とヨーロッパ方式(A-law)がある。日本は、アメリカに 右に倣えしてる。
折角なので、この変換がどうなってるかsoxのソースを紐解いてみる。 u-lawで検索してみると、g7xx.cってのがそれっぽい。早速、 g711.cを観賞してみる。
const int16_t lsx_ulaw2linear16[256] = { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812, : /* * ulaw2linear() - Convert a u-law value to 16-bit linear PCM * * First, a biased linear code is derived from the code word. An unbiased * output can then be obtained by subtracting 33 from the biased code. * * Note that this function expects to be passed the complement of the * original code word. This is in keeping with ISDN conventions. */ int16_t sox_ulaw2linear16( unsigned char u_val) { int16_t t; /* Complement to obtain normal u-law value. */ u_val = ~u_val; /* * Extract and bias the quantization bits. Then * shift up by the segment number and subtract out the bias. */ t = ((u_val & QUANT_MASK) << 3) + BIAS; t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); } : printf("\n};\n\nint16_t lsx_ulaw2linear16[256] = {\n "); y = 0; for (x = 0; x < 256; x++) { printf("%8d,", sox_ulaw2linear16(x)); y++; if (y == 7) { y = 0; printf("\n "); } }
これは、変換に必要なテーブルを作ってるだけだね(A-lawのも造ってる。そして、逆変換用のテーブルも ここで作っている。)。
変換のアルゴリズムについての説明も有ったよ。
/* * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data * stored in a unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 14-bits. * * In order to simplify the encoding process, the original linear magnitude * is biased by adding 33 which shifts the encoding range from (0 - 8158) to * (33 - 8191). The result can be seen in the following encoding table: * * Biased Linear Input Code Compressed Code * ------------------------ --------------- * 00000001wxyza 000wxyz * 0000001wxyzab 001wxyz * 000001wxyzabc 010wxyz * 00001wxyzabcd 011wxyz * 0001wxyzabcde 100wxyz * 001wxyzabcdef 101wxyz * 01wxyzabcdefg 110wxyz * 1wxyzabcdefgh 111wxyz * * Each biased linear code has a leading 1 which identifies the segment * number. The value of the segment number is equal to 7 minus the number * of leading 0's. The quantization interval is directly available as the * four bits wxyz. * The trailing bits (a - h) are ignored. * * Ordinarily the complement of the resulting code word is used for * transmission, and so the code word is complemented before it is returned. * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */
これを見ると、元データの大きさで8つのグループに分けているな。そして、データは 上位の4ビットのみ残して、下位は捨ててる。この説明には無いけど、圧縮されたコード の最上位ビットは、元データの正負を表すサインビットが追加されるとな。
実際にこれらのテーブルが使われるのは、別の場所だった。
[sakae@secd ~/sox-14.3.2/src]$ grep sox_ulaw2linear16 *.[ch] g711.c:int16_t sox_ulaw2linear16( g711.c: printf("%8d,", sox_ulaw2linear16(x)); g711.h:#define sox_ulaw2linear16(uc) (lsx_ulaw2linear16[uc]) g721.c: sl = sox_ulaw2linear16(sl) >> 2; g723_24.c: sl = sox_ulaw2linear16(sl) >> 2; g723_40.c: sl = sox_ulaw2linear16(sl) >> 2; g72x.c: dx = (sox_ulaw2linear16(sp) >> 2) - se; /* 16-bit prediction error */ raw.c:#define SOX_ULAW_BYTE_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(sox_ulaw2linear16(d),clips) voc.c:#define SOX_ULAW_BYTE_TO_SAMPLE(d) ((sox_sample_t)(sox_ulaw2linear16(d)) << 16)
電話は、これぐらいにしとくか。
SIP
名前は知ってた。インターネットと言えば、RFCです。早速引いてみます。
[sakae@secd ~]$ rfc -s sip The Result: 1169 Explaining the role of GOSIP. V.G. Cerf, K.L. Mills. August 1990. (Format: TXT=30255 bytes) (Status: INFORMATIONAL) 1304 Definitions of Managed Objects for the SIP Interface Type. T. Cox, K. Tesink, Eds.. February 1992. (Format: TXT=52491 bytes) (Obsoleted by RFC1694) (Status: PROPOSED STANDARD) 2543 SIP: Session Initiation Protocol. M. Handley, H. Schulzrinne, E. Schooler, J. Rosenberg. March 1999. (Format: TXT=338861 bytes) (Obsoleted by RFC3261, RFC3262, RFC3263, RFC3264, RFC3265) (Status: PROPOSED STANDARD) : 6468 Sieve Notification Mechanism: SIP MESSAGE. A. Melnikov, B. Leiba, K. Li. February 2012. (Format: TXT=21331 bytes) (Status: PROPOSED STANDARD)
最初の2つは違うみたいなので、RFC2543を取り寄せてみる。(rfcってコマンドは、 ports/miscに入ってたかな。こやつ、上記のような検索と、見つかったのをw3mで 閲覧する機能が入ってて、なかなか便利)
+....... cs.columbia.edu .......+ : : : (~~~~~~~~~~) : : ( location ) : : ( service ) : : (~~~~~~~~~~) : : ^ | : : | hgs@lab : : 2| 3| : : | | : : henning | : +.. cs.tu-berlin.de ..+ 1: INVITE : | | : : : henning@cs.col: | \/ 4: INVITE 5: ring : : cz@cs.tu-berlin.de ========================>(~~~~~~)=========>(~~~~~~) : : <........................( )<.........( ) : : : 7: 200 OK : ( )6: 200 OK ( ) : : : : ( work ) ( lab ) : : : 8: ACK : ( )9: ACK ( ) : : ========================>(~~~~~~)=========>(~~~~~~) : +.....................+ +...............................+ ====> SIP request ....> SIP response
苦労してアスキーアートを書いてますなあ。これ、ベルリン大学のczさんが、大西洋を渡った 米国のコロンビア大学のhenningさんと連絡を取ろうとした時の信号の流れです。
コロンビア大学内でhenningさんを検索してhgsさんを見つけ(内線に繋ぎますってやつだ)、ベルを鳴らしてるって 事だな。200 OKは、お約束って事で。
他にどんなコマンドが有るかと言うと、
Method = "INVITE" | "ACK" | "OPTIONS" | "BYE" | "CANCEL" | "REGISTER"
片言の英語で通じちゃうってのが、ありがたいな。NTTの電話網だと、バイナリーデータに よるやり取りになってて、人間には不親切。
ざっと見ると、このRFCは150ページぐらいあった。電子交換機の仕様としては大きいんだか 小さいんだか? どうなんだろう。
RFC6468ってのは、SIPでメッセージも送れたら便利じゃんって提案だな。まあ、誰でも 考え付くアイデアだな。そんなのいらないって無視する事が出来るのがお約束。ゆるく出来て いるのがこの世界だったりします。
FreeBSDのportsにsip関連の何かがあるかと探してみたら
Sipsak is a small command line tool for developers and administrators of Session Initiation Protocol (SIP) applications. It can be used for some simple tests on SIP applications and services. WWW: http://sipsak.berlios.de/
Siproxd is a proxy/masquerading daemon for the SIP protocol. It handles registrations of SIP clients on a private IP network and performs rewriting of the SIP message bodies to make SIP connections possible via a masquerading firewall. It allows SIP clients (like kphone, linphone) to work behind an IP masquerading firewall or router. WWW: http://siproxd.sourceforge.net/
とかの、小さいSIPが有るみたいだな。試してみるか。本格的に使うなら、こちらかな。 まあ、NTTに対抗しよって訳でもないけど。
Asterisk is an Open Source PBX and telephony toolkit. It is, in a sense, middleware between Internet and telephony channels on the bottom, and Internet and telephony applications at the top. WWW: http://www.asteriskpbx.com