電話

図書館へ行ったら、『電話はなぜつながるか』なんて本が有ったので借りてきた。姉妹編で、 『携帯電話はなぜつながるか』は、既に読んだ記憶があるな。(けど、内容忘れたよ、トホホ)

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