[ トップページ ]

« Perl によって UDP ポートを “たたく” プログラム | メイン | Linux のためのイーサネット・ハブもどきのプログラム »

マルチメディア

Perl による G.711 の処理

音声にしろ動画にしろ,おおくのコーデックの処理は複雑で,ライブラリのお世話にならなければならない. しかし,電話などでつかわれる G.711 という ITU-T 標準のコーデックは非常にかんたんであり,ほとんどテーブル引きだけで実現することができる. ここでは Perl による G.711 の変換・逆変換のプログラムをしめす. もちろん,Perl の特殊機能はつかっていないので,他の言語に容易にかきかえることができる.

G.711 は対数圧縮によって 16 bit の音声を 8 bit に圧縮するコーデックである. G.711 には u-Law (正確には μ-Law) と a-Law という 2 種類があるが,変換のてまはあまりかわらない. ここでは u-Law だけをあつかう.

基本的には,あらかじめつぎのようなテーブルを用意しておけば,これらのテーブルをひくだけで uLaw から線形への変換ができる (ただし,添字の範囲が 0..255 からはずれないようにクリップする必要がある).

# ULAW-to-linear conversion table for upper digit
my @ULAW_H =
   (130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 
    170, 174, 178, 182, 186, 190, 193, 195, 197, 199, 
    201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 
    221, 223, 224, 225, 226, 227, 228, 229, 230, 231, 
    232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 
    241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 
    246, 247, 247, 248, 248, 248, 249, 249, 249, 249, 
    250, 250, 250, 250, 251, 251, 251, 251, 252, 252, 
    252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 
    253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 
    254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
    255, 255, 255, 255, 255, 255, 255, 0, 126, 121, 
    117, 113, 109, 105, 101, 97, 93, 89, 85, 81, 
    77, 73, 69, 65, 62, 60, 58, 56, 54, 52, 
    50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 
    31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 
    21, 20, 19, 18, 17, 16, 15, 14, 14, 13, 
    13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 
    8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 
    5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 
    3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0);

# ULAW-to-linear conversion table for lower digit
my @ULAW_L =
   (0, 4, 8, 12, 17, 21, 25, 29, 33, 38, 
    42, 46, 50, 55, 59, 63, 66, 68, 71, 73, 
    75, 77, 79, 81, 83, 85, 88, 90, 92, 94, 
    96, 98, 228, 229, 230, 231, 232, 233, 234, 235, 
    236, 237, 238, 239, 240, 241, 243, 244, 180, 53, 
    181, 54, 182, 55, 184, 56, 185, 57, 186, 58, 
    187, 59, 188, 60, 157, 221, 29, 94, 158, 222, 
    30, 95, 159, 223, 31, 96, 160, 224, 32, 97, 
    145, 177, 209, 241, 17, 50, 82, 114, 146, 178, 
    210, 242, 18, 51, 83, 115, 139, 155, 171, 187, 
    203, 219, 235, 251, 11, 28, 44, 60, 76, 92, 
    108, 124, 136, 144, 152, 160, 168, 176, 184, 192, 
    200, 208, 216, 224, 232, 240, 248, 0, 0, 252, 
    248, 244, 239, 235, 231, 227, 223, 218, 214, 210, 
    206, 201, 197, 193, 190, 188, 185, 183, 181, 179, 
    177, 175, 173, 171, 168, 166, 164, 162, 160, 158, 
    28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 
    18, 17, 16, 15, 13, 12, 76, 203, 75, 202, 
    74, 201, 72, 200, 71, 199, 70, 198, 69, 197, 
    68, 196, 99, 35, 227, 162, 98, 34, 226, 161, 
    97, 33, 225, 160, 96, 32, 224, 159, 111, 79, 
    47, 15, 239, 206, 174, 142, 110, 78, 46, 14, 
    238, 205, 173, 141, 117, 101, 85, 69, 53, 37, 
    21, 5, 245, 228, 212, 196, 180, 164, 148, 132, 
    120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 
    40, 32, 24, 16, 8, 0);

しかし,テーブルの数値をいれなくても,プログラムでそれを生成することができる. つぎにしめすのは初期設定時につぎの 2 つのサブルーティンをよびだすことによってテーブルを生成し,それをつかって変換をおこなうプログラムである.

  • gen_u2l() (uLaw から線形への変換 (デコード) テーブルを生成)
  • gen_l2u() (線形から uLaw への変換 (エンコード) テーブルを生成)

#=============================================================================
# ulaw <-> linear conversion table generator
#=============================================================================

my $QUANT_MASK = 0xf;
my $BIAS = 0x84;
my $SEG_MASK = 0x70;
my $SEG_SHIFT = 4;
my $SIGN_BIT = 0x80;

my (@l2u, @u2l);

### u2l($uval)
#   convert ulaw value to linear value.
#
sub u2l($) {
    my ($uval) = @_;
    $uval = ~$uval;
    my $t = (($uval & $QUANT_MASK) << 3) + $BIAS;
    $t <<= ($uval & $SEG_MASK) >> $SEG_SHIFT;
    return ($uval & $SIGN_BIT) ? ($BIAS - $t) : ($t - $BIAS);
}

### gen_u2l()
#   generate ulaw-to-linear conversion table (@u2l)
#
sub gen_u2l() {
    for (my $i = 0; $i < 256; $i++) {
        $u2l[$i] = u2l($i);
    };
}

### gen_l2u()
#   generate linear-to-ulaw conversion table (@l2u)
#   (This method might not generate an optimum converter.)
#
sub gen_l2u() {
    for (my $i = 0; $i < 256; $i++) {
        my $j = $u2l[$i];
        if ($j < 0) {
            $j += 65536;
        };
        $l2u[$j] = $i;
    };
    for (my $i = 1; $i < 65536; $i++) {
        if ($l2u[$i] == 0) {
            $l2u[$i] = $l2u[$i-1];
        };
    };
}
Keywords:

トラックバック

このエントリーのトラックバックURL:
http://www.kanadas.com/mt/mt-tb.cgi/1616

コメントを投稿

このページについて

2007-11-14 23:31 に投稿されたエントリーのページです。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Creative Commons License
このブログは、次のライセンスで保護されています。 クリエイティブ・コモンズ・ライセンス.
Powered by
Movable Type 3.36