* Sat Dec 4 14:45:00 JST 2004 Naoyuki Sawa
- ADPCMの仕組み#4
(...前回からの続き)
前回は、P/ECE方式のADPCMのADPCM→PCM変換(デコード)の手順を追ってみました。
今回は、P/ECE方式のADPCMのPCM→ADPCM変換(エンコード)の手順を追ってみます。
P/ECE方式のデコード処理手順は、YM2608方式のデコード処理手順とほとんど同じでした。
同様に、P/ECE方式のエンコード処理手順は、YM2608方式のエンコード処理手順とほとんど同じです。
厳密に比較すると、P/ECE方式のエンコード手順の方が、やや作業内容は多いです。
前回の最後に述べた通り、P/ECE方式のデコード処理手順はYM2608方式よりも単純化されていて、その代わりにエンコード処理での作業が増えています。
増えているといってもわずかですから、YM2608方式のエンコード処理を理解していれば、P/ECE方式のエンコード処理を理解するのは簡単だと思います。
P/ECE方式のADPCMエンコード処理のフローチャートを示します。
PDF・Visio
あれ?さきほど「P/ECE方式のエンコード手順は、YM2608方式よりもやや複雑」と書きましたが、あまり複雑には見えませんね。
実は、上に示したフローチャートは、完全なものではありません。
説明を簡単にするために、わざと一部の処理を省略してあります。
省略した処理については、あとで付け加えて説明することにします。
それでは、一手順づつ追ってみます。
初期状態では“前のデータ”がありませんので、適切な初期値を定める必要があります。
規定の初期値はデコード処理の場合と同じで、(仮想的な)前回のPCM値を0、予測変化単位量を16とします。
まず、(仮想的な)前回のPCM値と予測変化単位量によって、PCM入力値の範囲を15個の領域に区分します。
YM2608方式では16個の領域に区分しましたが、P/ECE方式ではADPCM値0を使わないので、一つ少ない15個の領域となります。
PDF・Visio
最初のPCM入力値を75、としましょう。
上図より、PCM入力値75は、ADPCM値13の領域に含まれることがわかります。
最初のADPCM値は13、と決定しました。
PDF・Visio
YM2608方式の場合と同じく、エンコード特有の処理はここまで。
ここからあとは、デコード処理と同じ手順です。
いま生成したADPCM値13をデコーダが読み込んだときに、デコーダはどのような処理を行うでしょうか?
一回目のPCM出力値として80を出力し、次回の予測変化単位量を23に更新するはずです。
(なぜそうなるかは、前回のデコード処理の説明を参照してください。)
というわけで、エンコーダが読み込んだ本当のPCM入力値75はもう忘れて、一回目のPCM値は80だったことにしてしまいます。
さらに、デコーダと歩みを合わせるように、次回の予測変化単位量も23に更新します。
PDF・Visio
二回目の手順も、一回目と同様です。
まず、一回目のPCM値と更新された予測変化単位量によって、PCM入力値の範囲を15個の領域に区分します。
PDF・Visio
二回目のPCM入力値を40、としましょう。
上図より、PCM入力値40は、ADPCM値6の領域に含まれることがわかります。
二回目のADPCM値は6、と決定しました。
PDF・Visio
一回目と同様、エンコード特有の処理はここまで。
ここからあとは、デコード処理と同じ手順です。
いま生成したADPCM値6をデコーダが読み込むと、二回目のPCM出力値として34を出力し、次回の予測変化単位量を20に更新するはずです。
(なぜそうなるかは、前回のデコード処理の説明を参照してください。)
エンコーダが読み込んだ本当のPCM入力値40はもう忘れて、二回目のPCM値は34だったことにします。
また、次回の予測変化単位量も20に更新します。
PDF・Visio
以上のような手順の繰り返しでPCM→ADPCM変換(エンコード)を行うのが、P/ECE方式のADPCMです。
P/ECE方式のADPCMを使って、単純な波形をいったんADPCMに変換し、PCMに戻した場合に、どのぐらい正確に元の波形を復元できるのかを見てみます。
まずは、正弦波です。
Excel
グラフ上の黒い線が元のPCM波形、紫色の線がADPCM変換→PCMに戻した後のPCM波形です。
二色の線はぴったり重なっていて、黒い線は紫色の線の下に隠れてほとんど見えません。
正弦波をADPCM変換した場合は、元の波形をとても高い精度で再現できることがわかります。
次に、矩形波です。
Excel
問題発生です!
最初の立ち上がりは再現できていますが、それ以降、PCM出力値がまったく変化しなくなってしまいました。
なぜこのような結果になってしまったのでしょうか?
原因は、予測変化単位量が小さくなりすぎてしまったためです。
矩形波では、PCM値が変化しない区間が長いので、その間、予測変化単位量は次の式で更新されつづけて、
予測変化単位量←予測変化単位量×233÷256
どんどん小さな値になって行き、いずれ0になります。
いったん0になってしまうと、どんな係数を掛けても0ですから、その後、予測変化単位量はずっと0のままです。
PCM出力値を変化させるための変化量は、(予測変化単位量×変化率)で指示されます。
ところが、予測変化単位量が0ですから、どんな変化率を掛けても変化量は0になります。
つまり、予測変化単位量がいったん0になると、その後、PCM出力値は変化できなくなってしまうのです。
先ほどのグラフに加えて、予測変化単位量の推移もグラフ化してみました。
矩形波の平らな部分の途中で、予測変化単位量が0になってしまっているのがわかると思います。
Excel
YM2608方式では、予測変化量の下限(127)を定めて、デコード・エンコード処理の両方で予測変化量のクリッピングを行っていました。
しかしP/ECE方式では、デコード処理中に予測変化単位量のクリッピングを行わない仕様、と決まっているので、この手は使えません。
前々回に説明した通り、エンコード処理の後半はデコード処理と同じ手順を踏むことが重要ですから、エンコード側だけクリッピング処理を追加するわけにはいかないのです。
では、P/ECE方式はどうやってこの問題を解決しているかと言うと、大胆にも、予測変化単位量が減らないようなウソのADPCM値に置き換えてしまいます。
ADPCM値が5〜11のときに範囲予測変化単位量がより小さい値に更新されるわけですから、もしも予測変化単位量が1→0になりそうになったら、
ADPCM値を1〜4または12〜15のいずれかの値に置き換えてしまえば、とりあえず予測変化単位量が0になることは防げるわけです。
実際のP/ECE方式のエンコード処理では、予測変化単位量が0付近まで小さくなるよりももう少し先に、16未満になりそうになった時点でADPCM値を置き換えます。
以上の処理を追加した、完全なエンコード処理のフローチャートを示します。
PDF・Visio
青い線で囲った部分が、新しく追加した処理です。
新しく追加した部分の処理を少し追ってみることにします。
まず、前回のPCM値を50、予測変化量単位を17と仮定します。
PDF・Visio
PCM入力値を読み込むと、80でした。
上図より、PCM入力値80は、ADPCM値10の領域に含まれることがわかります。
ADPCM値は10、と決定しました。
PDF・Visio
いま生成したADPCM値10をデコーダが読み込むと、PCM出力値として84(50+17×2)を出力し、次回の予測変化単位量を15(=17×233÷256)に更新するはずです。
ここで、次回の予測変化単位量に注目!
次回の予測変化単位量が16未満になってしまいました。
前述の通り、P/ECE方式のADPCMエンコード処理では、予測変化単位量が16未満になるようなADPCM値を生成しないことになっています。
そこで、先ほど決定したADPCM値10を取り消します。
取り消したADPCM値の代わりにどんな値を使うかは、次のように定められています。
取り消したADPCM値が5〜 7ならば、代りにADPCM値12を使う。
取り消したADPCM値が8〜11ならば、代りにADPCM値 4を使う。
いま取り消したADPCM値は10なので、代りにADPCM値4を使います。
PDF・Visio
あらためて、デコーダがADPCM値4を読み込んだときのPCM出力値と、次回の予測変化単位量を計算します。
PDF・Visio
ADPCM値を10→4に置き換えたことにより、予測変化単位量が16以上になりました。
以上で、一回分のエンコード処理が完了です。
しかし、確かに予測変化単位量が16未満になることは防げたものの、エンコーダへのPCM入力値が80だったのに対して、デコーダからのPCM出力値は-18です。
こんなアバウトな方法で大丈夫なのでしょうか?
・・・大丈夫です。問題ありません。
まずは問題ないことを示すため、先ほど正しい波形が復元されなかった矩形波のグラフに、上述の処理を組み込んだ結果を示します。
Excel
デコード処理はそのまま、エンコード処理に前述のADPCM値置き換え処理を追加しただけで、おおよそ正しい波形が再現されるようになりました。
矩形波の平らな部分を一部拡大してみると、次のようになっています。
Excel
上下にとんがっている部分が、ADPCM値置き換え処理の影響です。
本来のPCM入力波形からは、かなり離れてしまっているのがわかります。
しかし、これらの細かな値の変化は、音として聴くと人の耳ではほとんど認識できない成分となり、音声データを再現する用途では問題にならないのです。
前々回、YM2608方式のエンコード処理の説明の中で、
ADPCMエンコーダは、デコーダと同じ処理を行う部分のコードこそが重要なのです。
極端な話、デコーダと同じ部分のコードさえ正しければ、PCM入力値からADPCM値を生成する部分のコードが多少間違っていても構わないぐらいです。
と述べて、実際に、わざと間違ったADPCM値を出力して、全体への影響が少ないことを示しました。
P/ECE方式のエンコード処理は、まさにこの特性を利用しています。
さて、矩形波が正しく再現できることがわかりましたので、次はノコギリ波です。
Excel
ノコギリ波も、おおむね問題なく再現できました。
YM2608方式では角の部分で行き過ぎが発生していたのに較べ、P/ECE方式では角が欠けているなど、やや違った傾向が見られます。
ADPCM値置き換え処理について余談、細かな話です。
あまり重要ではないので、細かな話に興味がなければ読み飛ばしてください。
前述のADPCM値置き換え処理での、置き換え基準は次のようなものでした。
取り消したADPCM値が5〜 7ならば、代りにADPCM値12を使う。
取り消したADPCM値が8〜11ならば、代りにADPCM値 4を使う。
ADPCM値5〜 7は、PCM入力値が微減傾向であることを意味します。
ADPCM値5〜 7の代わりとなるADPCM値12は、PCM値をやや大幅に増加させます。
ADPCM値8〜11は、PCM入力値が微増傾向であることを意味します。
ADPCM値8〜11の代わりとなるADPCM値 4は、PCM値をやや大幅に減少させます。
つまり、
本当のPCM入力値が減少傾向ならば、ADPCM値を置き換えた結果のPCM値は増加方向に大きくずれる
本当のPCM入力値が増加傾向ならば、ADPCM値を置き換えた結果のPCM値は減少傾向に大きくずれる
というわけです。
試行錯誤と調整によって上述のような仕様が最良と判断されたのだと思いますが、直観的には逆のような気がしないでもありません。
本当のPCM入力値が減少傾向ならば、減少方向に大きくずらした方が誤差は少ないはずですし、増加傾向についても同様だからです。
どちらにせよ、耳で聴く分には違いはわからないのですけれど、なぜわざと逆方向にずらしているのか、ちょっと疑問が残りました。
以上、ADPCM値置き換え処理について余談、細かな話でした。
ちょっと長くなったので、今回はここまでです。
次回は、P/ECE方式のエンコード処理の続きを少しと、YM2608方式とP/ECE方式の比較を行ってまとめたいと思います。
(続きます...)
nsawa@piece-me.org