* Wed Dec 1 00:00:00 JST 2004 Naoyuki Sawa
- ADPCMの仕組み#2
(...前回からの続き)
前回は、YM2608方式のADPCMのADPCM→PCM変換(デコード)の手順を追ってみました。
今回は、YM2608方式のADPCMのPCM→ADPCM変換(エンコード)の手順を追ってみます。
エンコード処理はデコード処理の逆手順・・・と考えてしまいそうですが、ADPCMに関して言えば、両者の手順はほとんど大部分が同じです。
エンコード処理を実装してみると、デコード処理全部そっくりそのままのコードがエンコード処理にも含まれて、コード全体の70%ぐらいを占めます。
残り30%ぐらいがエンコード処理特有のコードで、PCM入力値からADPCM値を生成する部分ですが、それはとても簡単なコードです。
ADPCMエンコーダは“デコーダの気持ちになって”処理を行うことが重要で、つまり、デコーダと同じ処理を行う部分のコードこそが重要なのです。
極端な話、デコーダと同じ部分のコードさえ正しければ、PCM入力値からADPCM値を生成する部分のコードが多少間違っていても構わないぐらいです。
なぜ以上のような点を強調したかについては、最後に述べようと思います。
それでは、YM2608方式のADPCMエンコード処理のフローチャートを示します。
処理の手順は『YM2608 ADPCM』の記事と同じですが、用語は僕の独断で日本語に置き換えてみました。
PDF・Visio
それでは、一手順づつ追ってみます。
初期状態では“前のデータ”がありませんので、適切な初期値を定める必要があります。
規定の初期値はデコード処理の場合と同じで、(仮想的な)前回のPCM値を0、予測変化量を127とします。
まず、(仮想的な)前回のPCM値と予測変化量によって、PCM入力値の範囲を16個の領域に区分します。
PDF・Visio
最初のPCM入力値を160、としましょう。
上図より、PCM入力値160は、ADPCM値5の領域に含まれることがわかります。
最初のADPCM値は5、と決定しました。
PDF・Visio
エンコード特有の処理はここまで。たったこれだけです!
ここからあとは、デコード処理と同じ手順です。
ここからは、“デコーダの気持ちになって”考えてみます。
いま生成したADPCM値5をデコーダが読み込んだときに、デコーダはどのような処理を行うでしょうか?
一回目のPCM出力値として174を出力し、次回の予測変化量を202に更新するはずです。
(なぜそうなるかは、前回のデコード処理の説明を参照してください。)
というわけで、エンコーダが読み込んだ本当のPCM入力値160はもう忘れて、一回目のPCM値は174だったことにしてしまいます。
さらに、デコーダと歩みを合わせるように、次回の予測変化量も202に更新します。
PDF・Visio
二回目の手順も、一回目と同様です。
まず、一回目のPCM値と更新された予測変化量によって、PCM入力値の範囲を16個の領域に区分します。
PDF・Visio
二回目のPCM入力値を70、としましょう。
上図より、PCM入力値70は、ADPCM値10の領域に含まれることがわかります。
二回目のADPCM値は10、と決定しました。
PDF・Visio
一回目と同様、エンコード特有の処理はここまで。
ここからあとは、デコード処理と同じ手順です。
いま生成したADPCM値10をデコーダが読み込むと、二回目のPCM出力値として48を出力し、次回の予測変化量を179に更新するはずです。
(なぜそうなるかは、前回のデコード処理の説明を参照してください。)
エンコーダが読み込んだ本当のPCM入力値70はもう忘れて、二回目のPCM値は48だったことにします。
また、次回の予測変化量も179に更新します。
PDF・Visio
以上のような手順の繰り返しでPCM→ADPCM変換(エンコード)を行うのが、YM2608方式のADPCMです。
前回と今回で、YM2608方式のADPCMの、ADPCM→PCM変換(デコード)とPCM→ADPCM変換(エンコード)の手順を追ってみました。
YM2608方式のまとめとして、単純な波形をいったんADPCMに変換し、PCMに戻した場合に、どのぐらい正確に元の波形を復元できるのかを見てみます。
まずは、正弦波です。
Excel
グラフ上の黒い線が元のPCM波形、紫色の線がADPCM変換→PCMに戻した後のPCM波形です。
・・・が、二色の線はぴったり重なっていて、黒い線は紫色の線の下に隠れてほとんど見えませんね。
正弦波をADPCM変換した場合は、元の波形をとても高い精度で再現できることがわかります。
次に、矩形波です。
Excel
立ち上がり・立ち下がりエッジのところで、元の波形とのズレが生じています。
急激な値の変化に追い付いて行けていない感じです。
また、立ち上がり後・立ち下がり後のところで、少し行き過ぎが発生しています。
次は、ノコギリ波です。
Excel
ノコギリ波をADPCM変換→PCMに戻した結果のグラフにも、矩形波の場合と同じ傾向が見られます。
正弦波は高い精度で再現でき、矩形波とノコギリ波は急激な値の変化がある部分でやや誤差が生じることがわかりました。
矩形波・ノコギリ波に限らず、波の傾きがいきなり変わるようなデータにADPCMを適用すると、元の波形を正確に再現することができません。
が、一般的な音声データでは、波の傾きがいきなり変わるような部分はさほど重要ではなく、多少不正確でも耳で聴く分にはさほど違いが感じられません。
そんなわけで、音声データのサイズを小さくする方法として、ADPCMの手法が有効に利用できるのです。
今回の最初に、
ADPCMエンコーダは“デコーダの気持ちになって”処理を行うことが重要で、つまり、デコーダと同じ処理を行う部分のコードこそが重要なのです。
極端な話、デコーダと同じ部分のコードさえ正しければ、PCM入力値からADPCM値を生成する部分のコードが多少間違っていても構わないぐらいです。
と書きました。
今回の最後として、上述の件について確かめてみることにします。
先ほどの正弦波のグラフを生成するExcelシートに、わざとエンコードエラーを混入してみました。
具体的には、本当はADPCM値3を生成しなければいけないところで、ADPCM値8を生成するように変更します。
逆に、本当はADPCM値8を生成しなければいけないところで、ADPCM値3を生成するように変更します。
変更したのはエンコード特有のコードだけで、エンコード処理の中のデコーダと同じ部分のコードは正しいまま、デコード処理のコードも正しいままです。
結果は次の通り。
Excel
正しい処理による正弦波のグラフと比較すると、ところどころにややズレが生じていますが、大枠は問題ないように見えます。
ところどころでズレているのが、エンコードエラーが発生している部分です。
しかしながら、少しぐらいのズレが生じても、次第に正しい波形に近づいて行くのがわかると思います。
結局のところADPCMの手法そのものが“ズレを修正する”技術で、エンコード処理のズレはエンコーダ自身によって補正されて行きます。
それがプログラムエラーによるズレであっても、多少ならばカバーできてしまうわけです。
(もちろん限度はありますし、プログラムエラーを許容しているわけでもありませんけれど・・・)
エンコード特有のコードはさほど重要でない(と言うと語弊がありますが(^^;)ことがわかりました。
それでは次に、エンコード処理の中の、デコーダと同じ部分のコードが重要であることを確認してみます。
前回、予測変化量を更新するための係数を説明しました。こういうのです。
変化率 | 予測変化量を修正する計算式
|
---|
0 | 次回の予測変化量←今回の予測変化量× 57÷64
|
1 |
|
2 |
|
3 |
|
4 | 次回の予測変化量←今回の予測変化量× 77÷64
|
5 | 次回の予測変化量←今回の予測変化量×102÷64
|
6 | 次回の予測変化量←今回の予測変化量×128÷64
|
7 | 次回の予測変化量←今回の予測変化量×153÷64
|
デコード処理のコードは、これらの係数を使って次回の予測変化量を更新します。
エンコード処理の中のデコーダと同じコードも、これらの係数を使って次回の予測変化量を更新します。
エンコード特有の処理(PCM値からADPCM値を生成する処理)の中では、これらの係数を利用しません。
さて、係数のうちひとつを、わざと間違った値に変えてみることにします。
変化率 | 予測変化量を修正する計算式
|
---|
0 | 次回の予測変化量←今回の予測変化量× 57÷64
|
1 |
|
2 |
|
3 | 次回の予測変化量←今回の予測変化量× 58÷64
|
4 | 次回の予測変化量←今回の予測変化量× 77÷64
|
5 | 次回の予測変化量←今回の予測変化量×102÷64
|
6 | 次回の予測変化量←今回の予測変化量×128÷64
|
7 | 次回の予測変化量←今回の予測変化量×153÷64
|
係数を間違った値(58)に変えるのは、エンコーダから利用する場合だけです。
デコーダから利用する場合は、正しい値(57)を使います。
つまり、エンコーダとデコーダとで、わずかに処理の内容を変えてみるわけです。
結果はこうなります。
Excel
ほんの少し係数を変えただけで、全然違う波形になってしまいました。
エンコーダとデコーダの処理のズレは、どちらのプログラムによっても認識できないため、修正されずにどんどん蓄積されていくからです。
以上のように、“エンコード処理のプログラムにおいても、デコーダと同じ処理を行う部分のコードが重要”ということが確認できました。
次回は、P/ECE方式のADPCMについて見ていこうと思います。
(続きます...)
nsawa@piece-me.org