黙々と進めた。残タスクは、
- コマンドラインの整備:DONE
- 残差出力モードの追加(-e):DONE
- 統計情報出力モードの追加(-c):DONE
- テストケース追加:DONE
- 白色雑音入力(randで生成したものでよい):DONE
- リリース実行確認:DONE
- 先頭で一発空エンコードして適応を早める:DONE
- コード整理
- エンコーダとデコーダを分ける: DONE
- ブロックデータエンコード/デコード関数が大きいので関数化: 小さくまとまったのでいいかな。
- 音質向上への工夫
- MS処理の再興。MS処理のスイッチオプションを追加
- もう一度試してみたらRMSEが悪化していることが分かった。(BGMとアイカツ音源で調べた)
- 実際に聞いてみるとパチパチ言ってる。不連続点が出ている。パチパチ言ってた記憶はないので、何かがおかしい。デバッグ。
- デコード時にLRに戻す前にオーバーフローしていた。
- バグや。ブロックヘッダにLRが入っているが、フィルタはMSで予測していた。そらパチパチ言うわ。
- パチパチは直したが、得られた結果は微妙と言わざるを得ない。最大誤差は減ってるけど、平均誤差は増大した傾向。 オプションにしてもデフォルトでオフかなあ。
- MSでうまく行かない例としては、振幅が大きい振動波で、side成分が割れている場合。(ピエトロの気絶の55秒付近)そこをADPCM化すると、エフェクターを通したように割れてしまう。
- ロスレスではないから、エンコード時にsideも右シフトすることで、sideが割れる問題は緩和した。採用。しかしMSはオプションとする(デフォルトOFF)。
- 振幅がでかいときに誤差が大きくなる。じゃあ、入力を1bit右シフトして、出力時に1bit左シフトしていいんじゃない。
- 純粋に情報量が落ちそう。試してみるが。→うん、だめ。1bitぶん何かがわからなくなるのはつらい。
- NG的なアイデア入らないか?
- プリエンファシスを掛けたもので勾配計算する。重いか…?
- 爆裂に精度悪化。とりやめ。時間切れ。
- IIR的(出力)の適応: ダメだった。負荷も増えるし、やらん。
- モーメンタムみたいに、前の勾配を使えないか?
- やってみたが微妙。たいていRMSEが悪くなる。良くなっても劇的じゃない。
- SLAのLogSignを強引に入れてみたけど良くない。
- その他、残差と履歴をlog/sign化したけど芳しくなかった。
- コードを2の補数にしたい。
- 上位ビットを埋めるのが帰って辛いように思えた。保留。
- ノイズシェーピングが芳しくない。
- ちょっと考えると、品質の低いフィルター突っ込んでんのと同じに思えた。実際外すとRMSEが向上した。
- 廃止の方向で検討。
- 負荷 instruments -t "Time Profiler" ./aad ... でいける。
- 今更だが、 資料1 , ffmpeg
- MS処理の再興。MS処理のスイッチオプションを追加
- Macでinstrumentsが廃止されたようだ。 xcrun xctrace record --template 'Time Profiler' --target-stdout - --launch -- ./aad -e ManiMani.wav a.aad で計測を行っている。
感想・展望
- うーん、性能が良くない。IMA-ADPCMに毛が生えた程度か。XMAみたく、ブロック区間の残差の最大振幅値を計測して割った方がええのかな。
- 4bitのときは、残差を max(-最小残差/8, 最大残差/7) で割れば、残差が4bit収まる。
- 3bitならば max(-最小残差/4, 最大残差/3), 2bitならば max(-最小残差/2, 最大残差/1) となるはず。
- 一般化すると max(-最小残差/(1 << (bits-1)), 最大残差/((1 << (bits-1)) - 1))
- ブランチ切ってやってみたい...と思ったらできないことがすぐに分かった。量子化誤差が適応中にわからない。
- LPCを使うのもありだな。係数の絶対値が1を超えるから係数のスケール情報を入れる必要があるが。
- 量子化誤差が適応的に出る(しかも、エンコード/デコードで全く同じ値が出る)から、これに応じてステップサイズ、もしくは符号化値を変えられないか。
- 複数回エンコードを回すの有効かも。少なくともファイル先頭では効いた。
- 単純に単一ブロックを繰り返しエンコードするのは効果が薄かった。
- 次(前)の区間と合わせてエンコードするのもいいかも。オーバーラップする形。これは効いたので取り入れた。
- テーブルの見直し。急激に振幅がかわる(2〜3サンプルで-1から1に近づくときがある)ので、おそらく、テーブルの150以降の要素はもっと大きい値をとってもいいと思う。
- ステップサイズを適応的に計算するyamaha形式を試してみたい。IMAではテーブルの256階調に限られるが、こちらはより柔軟に思える。 * ADPCMの仕組み#1 や rockbox や ffmpeg が参考になる。 * やっつけでやってみた。音圧の低い音源では少しよくなったが、りんごの木など音圧が大きい音源で軒並みRMSEが2割ほど悪化。取り下げていく。逆に考えると、低音圧音源で現在の実装があんまり良くないともいえる結果やな。
- 残差波形を見ているとピッチの残差立ち上がりが大きくて、また、それによって聞こえやすいノイズが発生している。周期は170サンプル=282Hz(@48k)とか。
- ピッチを潰すのは有効かも。自己相関を計算して周期を解析して、その一点で潰しにかかる。
タイムオーバー。現実にもどりましょ。