忙しく、だいぶ間が空いてしまった。まだ忙しい状態は続くが、研究は地味にエンジンをかけていきたい。

Macが故障してpelican環境が壊れたのでブログを刷新。

これまでの動きをまとめる。まず12月下旬〜年明けは符号に突っ込んでいた。

  • 例の卒論 の結果から、再帰的Golomb-Rice符号の符号パラメータの最適化ができそうというところに目をつけて、できたのでコーデックに組み込んでいた。圧縮率はわずかに上がったし、何より、指数移動平均による更新処理がなくなりデコード速度が上がったのが大きい。
  • Flake(FLACの最適化エンコーダ)( 公式, GitHub )に割と衝撃を受けている。最大圧縮設定で当時のTAKに迫っている。やっていることはブロック単位で符号長さが最小になるようにGolomb-Rice符号のパラメータとLPC次数を定めている。
    • 次数が意外に重要な要因なのかも。多すぎて悪化要因になっている?
    • Partitioned-Rice(ブロックを分けてその範囲でパラメータを設定するアイデア)はいままで懐疑の目で見ていたけど、性能の良さから採用に傾いた。
    • また、 32bitのbitioもここに実装がある。 参考にすべき。

その後1月下旬は研究会があったのでその準備。そのあたりで並行してRustのお勉強、とても素晴らしい言語。商業的にも意味があると思うし、是非ともマスターしたい。

引き続き符号に着手。まずは近いと指摘があったblock Gilbert-Mooreの詳細を見ていく。記憶上ではレンジコーダの一種だと思ったが…?

  • まずGilbert-Mooreはレンジコーダと思ってもらっていいはず。
  • CODING OF PREDICTION RESIDUAL IN MPEG-4 STANDARD FOR LOSSLESS AUDIO CODING (MPEG-4 ALS) 再帰的Golomb-Riceに似ている。小さい残差ではblock Gilbert-Moore、大きければ普通のGolomb-Rice。
    • これをBGMC(Block Gilbert-Moore Codes)と呼ぶらしい(Data Compresssion - The complete reference本より)
    • 論文では、LSB部分を直接送ることもしている。
    • MPEG4-ALSの実装も多分この論文のとおりになっている。

公開されているコードを見ると、やはりレンジコーダに見える。 LSB部分を直接送ることで、頻度テーブル s_freq が大きくなりすぎないようにしている。

/*
 * Encode a symbol using Gilbert-Moore code.
 * delta -- step size in the s_freq[] distribution.
 */
static void bgmc_encode (unsigned int symbol, int delta, unsigned short *s_freq, BITIO *p)
{
    register unsigned int high, low, range;

    /* get current range: */
    high = p->high;
    low = p->low;
    range = high - low + 1;

    /* narrow the code region to that allotted to this symbol: */
    /* aiki: ここがまさにレンジコーダ. 下限と上限をテーブル引きで高速に計算できるようにしている */
    high = low + ((range * s_freq [symbol << delta] - (1 << FREQ_BITS)) >> FREQ_BITS);
    low  = low + ((range * s_freq [(symbol+1) << delta]) >> FREQ_BITS);

    /* renormalize interval: */
    for ( ; ; ) {

        if (high < HALF) {
            put_bit_plus_follow (0, p); /* output 0 if in low half  */
        } else
        if (low >= HALF) {              /* output 1 if in high half */
            put_bit_plus_follow (1, p);
            low -= HALF;
            high -= HALF;               /* move down by half        */
        } else
        if (low >= FIRST_QTR && high < THIRD_QTR) { /* middle  */
            p->bits_to_follow += 1;     /* output an opposite bit   */
            low -= FIRST_QTR;           /* move down by a quarter   */
            high -= FIRST_QTR;
        } else
            break;                      /* otherwise exit the loop  */

        /* scale interval up: */
        low = 2 * low;
        high = 2 * high + 1;
    }

    /* update encoder's state: */
    p->high = high;
    p->low = low;
}

s_freq を眺めていると、指数的に減少していく頻度テーブルで(おそらく幾何分布orラプラス分布から来ている)、TAKの xcodes に似ているなと思う。TAKはレンジコーダを使っていたのか??