* Sun Dec 5 16:00:00 JST 2004 Naoyuki Sawa

- ADPCMの仕組み#5




(...前回からの続き) 前回は、P/ECE方式のADPCMのPCM→ADPCM変換(エンコード)の手順を追ってみました。 今回はまず、P/ECE方式のエンコードの手順についてもう少しお話しします。(検証だけです。エンコード手順は前回示したもので全部です) その後、YM2608方式とP/ECE方式のADPCMを比較して、まとめにしたいと思います。
前回の最後に、P/ECE方式のADPCMエンコードにて、予測変化単位量が小さくなりすぎないための処理を説明しました。 YM2608方式では、エンコーダ・デコーダ両方で明示的に予測変化量を下限値(127)でクリッピングしていたのに対して、 P/ECE方式では、エンコーダがあらかじめADPCM値を調整しておき、デコーダでのクリッピング処理は不要、という方法でした。 さて、予測変化単位量が小さくなりすぎないための対策が施されていることはわかりましたが、では、大きくなりすぎないための対策はあるのでしょうか? YM2608方式では、小さくなりすぎないための処理と同様、エンコーダ・デコーダ両方で明示的に予測変化量を上限値(24576)でクリッピングしていました。 P/ECE方式のエンコード処理フローチャートを見ると、予測変化単位量が大きくなりすぎないための対策が見当たりません。 P/ECE方式では、予測変化単位量が大きくなりすぎないための対策が施されていないのでしょうか? 結論を言うと、P/ECE方式では、予測変化単位量が大きくなりすぎないための『明示的な』処理は行っていません。 しかし、予測変化単位量がオーバーフローするほどに大きくなることも絶対にありません。 従って、予測変化単位量が大きくなりすぎないための『明示的な』処理が無くても問題ありません。 本当に「予測変化単位量がオーバーフローするほどに大きくなることも絶対にない」と言い切れるのか、検証してみましょう。 予測変化単位量がより大きく更新されるのは、現在の予測変化量よりも実際の変化量の絶対値が大きかった場合です。 言い換えると、現在の(予測変化単位量×3.5)よりも実際の変化量の絶対値が大きかった場合です。 PDFVisio 予測変化単位量をできるだけ大きく更新するには、最大振幅で触れつづけるようなPCM入力データを与えればいいことがわかります。 すなわち、次のようなデータです。 32767, -32768, 32767, -32768, 32767, -32768, ... こんな音声データを実際に利用することはまずないのですけれど、あくまでテスト用ということで。 まず、最大振幅で触れつづけるPCM入力データが与えられたときに、どのような出力波形が得られるか、グラフに表してみました。 Excel いくぶん元の波形からのズレはあるものの、まあまあいい感じに再現できています。 それでは、予測変化単位量はどのように推移しているのでしょうか? Excel 予測変化単位量は、約16000〜24000の間を行ったり来たりしているようです。 P/ECEカーネルのADPCMデコーダは、予測変化単位量を16bit符号付き整数で保持しているので、32767よりも大きくならなければオーバーフローしません。 まだまだ余裕があります。 なぜ、予測変化単位量は約24000よりも大きくならないのでしょうか? ちょっと予測変化単位量の推移を追いかけて見ましょう。 前回のPCM値を-32768、予測変化単位量を24000と仮定します。 今回のADPCM値でカバーできる範囲は、次のとおりです。 PDFVisio PCM入力データは前述のとおり{ 32767, -32768, 32767, -32768, ... }ですから、今回のPCM入力値は32767です。 上図より、PCM入力値32767は、ADPCM値11の領域に含まれることがわかります。 PDFVisio いま生成したADPCM値11をデコーダが読み込むと、PCM出力値として39232を出力し、次回の予測変化単位量を21843に更新するはずです。 PDFVisio 予測変化単位量が、24000→21843 と減少に転じました。 PCM入力データが常に最大振幅を繰り返していても、予測変化単位量はある一定の値以上に大きくならないことがわかりました。 予測変化単位量の上限に関しては、明示的にクリッピング処理を行わなくてもオーバーフローの心配はないのです。 以下、ちょっと細かな話です。興味が無ければ読み飛ばしてください。
なぜこうなるかというと、予測変化単位量がより大きな値に更新されるためには、|変化量|が予測変化単位量の3.5倍以上であることが条件だからです。 実際の|変化量|が最大となるのは、PCM入力値が -32768→+32767 または +32767→-32768 へ変化した場合で、いずれも65535です。 |変化量|が予測変化単位量の3.5倍以上であるためには、予測変化単位量は(65535÷3.5 = 18724)以下でなければいけません。 予測変化単位量が18724を超えると、次回は必ず予測変化単位量が減少に転じます。 予測変化単位量18724未満から、一回の更新で符号付き16bit整数の最大値32767を超えるには、 |変化率|:6 (予測変化単位量←予測変化単位量×453÷256) ・・・ 予測変化単位量>18517ならば32767を超える |変化率|:7 (予測変化単位量←予測変化単位量×549÷256) ・・・ 予測変化単位量>15279ならば32767を超える のいずれかのケースしかありません。 しかし実際には、|変化量|の最大値は65535ですから、これらのケースはありえません。 |変化率|:6のケースについて言いますと、予測変化量18517に対して|変化率|:6となることはありえません。必ず|変化率|<4となるはずです。(65535÷18517 = 3.53) |変化率|:7のケースについて言いますと、予測変化量15279に対して|変化率|:7となることはありえません。必ず|変化率|<5となるはずです。(65535÷15279 = 4.28) 以上より、予測変化量18724未満から一回の更新で符号付き16bit整数の最大値32767を超えるようなケースも、絶対にありえないと保証できます。 以前に述べたとおり、P/ECE方式における予測変化量は予測変化単位量の3.5倍に相当します。 予測変化単位量の上限値が約24000ですから、予測変化量の上限値は約84000と考えられます。 YM2608方式では予測変化量の上限値が24576であったことに較べると、P/ECE方式の予測変化量の上限値は三倍以上大きな値です。 予測変化単位量が大きくなるほど細かな変化への追従が遅れることになるため、P/ECE方式はYM2608方式よりもこの点においてやや不利かも知れません。 実際の音声データではどの程度の違いが現れるのかわからないのですけれど・・・試行錯誤と調整によって“問題ない”と判断されたのでしょう。 P/ECE方式においても、予測変化単位量の上限値を設けることは簡単です。 エンコード時に、予測変化単位量が下限値(16)を下回らないようADPCM値を調整していたのと同じ方法で、上限値を上回りそうになったらADPCM値を調整すればいいだけです。 エンコーダ(P/ECE用PCMデータ作成ツール)に上限値の処理を追加するだけで、デコーダ(P/ECEカーネル)への変更は不要です。 自作のPCMデータ作成ツールを作る場合は、ちょっと試してみると面白いかも知れません。
細かな話でした。 以上で、P/ECE方式のADPCMエンコード処理の説明を終わります。
「ADPCMの仕組み#1」〜「ADPCMの仕組み#5」まで、五回をかけて、YM2608方式とP/ECE方式のADPCMの仕組みを見てきました。 両者ともエンコード・デコード手順はほとんど同じで、細かな部分の手順や係数にやや違いがある程度、ということがわかりました。 しかしながら、ADPCMにおいてはこれらの微妙な違いが重要で、細かな手順や係数が音質の良し悪しに大きく影響するのだそうです。 そのため、各社のADPCM LSIやソフトウェアの処理内容は「秘密」にされている場合が少なくないです。(建前上だけで、公然の秘密っぽいものもありますが…) その中で、YM2608方式のADPCMは、具体的な処理内容に関する資料がもっとも見つけ易いADPCM方式のひとつです。 1992年発行の書籍「Inside X68000」でも、X68000に搭載されているADPCM LSI「MSM6258」の仕様が公開できないため、代りにYM2608方式を用いて説明されていたりします。 ソフトウェアによる一般的なADPCM方式として、ITU-T(国際電気通信連合)のG.726方式や、Microsoft ADPCM方式などがありますが、これらの仕様も入手困難みたいです。 現在、Web上の資料からADPCM方式を学ぼうとすると、YM2608方式がいちばんメジャー、という感じです。 推測ですけれど、P/ECE方式のADPCMが、P/ECEだけのためにいちから調整されたとは考えづらいです。 たぶん、既存のADPCM方式の処理手順や係数を流用したか、やや変更して適用したのだと思います。 でも前述の通り、既存のADPCM方式に関する資料がほとんど見つけられないため、どのADPCM方式に近いのか判断できませんでした。 もし、ご存知の方いらっしゃいましたら、教えていただけると嬉しいです。(ホントにP/ECEオリジナルだったらごめんなさい) YM2608方式とP/ECE方式を比較すると、デコーダの処理はP/ECE方式の方がやや簡単です。 ・ADPCM値から変化量を求めるときに、増加・減少の場合分けが不要 ・変化量の計算が掛け算一回で済むのでやや簡単 (YM2608方式では掛け算一回と右シフト一回) ・予測変化単位量の上限・下限クリッピングが不要 YM2608方式はハードウェアデコードを前提としているのに対し、P/ECE方式はソフトウェアデコード前提であることが、デコーダ簡略化が追求されている理由だと思います。 P/ECEではCPU割り込み処理の中でADPCMデコードを行うため、デコード処理が複雑になればなるほど、アプリケーションの実行速度が遅くなってしまうからです。 音質は、YM2608方式の方がやや有利です。(実際に聴いてみて気になるほどの違いではないと思いますけれど…) P/ECE方式はADPCM値0を使わない分、YM2608方式に較べて一回のADPCM値でカバーできるポイントがひとつ少ないからです。 ADPCM値0を使わないのは、前述の利点「変化量の計算が掛け算一回で済むのでやや簡単」とのトレードオフですから、音質よりも速度を優先した調整の結果と言えます。 「ADPCMの仕組み#2」で示したYM2608方式のノコギリ波出力波形と、「ADPCMの仕組み#4」で示したPIECE方式のノコギリ波出力波形を較べると、角の部分に違う傾向が見られます。 YM2608方式では行き過ぎが発生しているのに対して、P/ECE方式では角が欠けています。 この違いの原因も、P/ECE方式がADPCM値0を使わないことに起因します。 YM2608方式はADPCM値によって16通り(偶数)のポイントをカバーするので、たとえ本当の変化量が0であったとしても、最低(予測変化量×1÷8)の変化をしてしまいます。 従って、行き過ぎが発生します。 P/ECE方式はADPCM値によって15通り(奇数)のポイントをカバーするので、どんなに予測変化単位量が大きくても、ADPCM値8が与えられれば変化量0を取ることが常に可能です。 ある程度予測変化単位量が大きくなると、(予測変化単位量×1)よりも0の方が実際の変化量に近くなってしまい、ADPCM値8が選択されることが多くなります。 従って、角が欠けます。 ニ方式の違いは、どちらが良いというものではなく、それぞれの特性によるものです。 実際に耳で聴く分には、たぶん違いはわからないでしょう。
「ADPCMの仕組み#1」の最初に書いたとおり、僕はこれまでADPCMの仕組みについてぜんぜん理解していませんでした。 今回、YM2608方式とP/ECE方式のADPCMを勉強したことで、だいたいADPCMの仕組みを理解できたと思います。 現在のADPCM LSIやソフトウェアには、音質改善のために、もう少し複雑な方法が採用されているようです。 YM2608やP/ECE方式以外のADPCMに関する資料が入手できたら、それらの方式についても勉強してみたいと思いました。

nsawa@piece-me.org