シグマデルタ変調 PWM (1)

「FMmelody」のプログラムの説明を書くのをサボって、主に「MIDI2CV」用途を目的とした、シグマデルタ変調 (以下「ΣΔM」、「ΣDM」あるいは「SDM」と略記) により PWM 出力の分解能を上げる実験をしています。
PC 上でプログラムによるシミュレーションを行う一方、Pakurino (Arduino) 上で実際に PWM 信号を出して、「WaveSpectra」による波形観察および FFT 解析を行っています。
「MIDI2CV」(MIDI to CV) とは、MIDI メッセージを受信して、アナログシンセ用のピッチ CV (制御電圧) とゲート信号を作り出す装置のことです。
MIDI ノート・オン・メッセージでは、0 から 127 までのディジタル・データによって、半音単位でピッチを指定します。
これをアナログ電圧であるピッチ CV に変換するには 7 ビット DAC を使えば良いわけですが、実際には (マルチビット方式の) 通常の DAC は使われません。
それは、128 値なので「分解能」は 7 ビットですが、「精度」として要求されるビット数はもっと大きくなるからです。
普通、DAC の「精度」は 1/2 LSB 程度で、ローコスト品では「精度」が「分解能」を下回るものも珍しくありません。
もちろん、「高分解能」で「高精度」の DAC を使えば良いのですが、コストが高くなってしまいます。
ローコスト・マイコンで MIDI2CV を実現する場合には、そもそも DAC は内蔵されていないことが多く、内蔵 PWM (Pulse Width Modulation) で CV のアナログ電圧を作り出すことが現実的です。
PWM では「2 値」からアナログ電圧を作り出すので、原理的には直線性は良好です。 それは、2 点を通る直線は、2 点が重ならない限りどんな配置になっても必ず引けるのに対し、3 点以上では全ての点が直線上にない限り、ひとつの直線が全ての点を通ることはないからです。
PWM の欠点としては、2 値の時間平均によりアナログ電圧を作り出すので、実際の回路としては PWM 出力を LPF でフィルタしますから、当然、信号帯域がせまくなり、応答時間が遅くなることです。
MIDI メッセージでノート・オン以外でピッチに関わるものとしては、「ピッチベンド」、「ポルタメント」、「モジュレーション」、「チューニング」などがありますが、これらを表現するには半音以下のピッチを表現することが必要です。
そのため、音階用の CV、ピッチ・ベンド用の CV、ポルタメント時間コントロール用の CV など、複数の CV を作り出して VCO のサミング・アンプ部で加算する方法が良く使われます。
ここでは、MIDI2CV での CV 出力の分解能を上げて、MIDI メッセージ中のピッチ関連の情報を MIDI2CV 内で合成し、ひとつの CV 出力にまとめて出すことにします。
MIDI メッセージには含まれませんが、シンセ内部のモジュレーションとして、「ピッチ EG」が使われることがあります。
PWM 利用の CV では応答速度が限られるので、速い変化をする「ピッチ EG」については別系統とし、VCO 部で合成する形にします。
変化の速くない「ピッチ EG」については、たとえば、音の出だしで毎回ピッチベンドを入力する代わりに、ゲート・オンで作動する「自動ピッチベンド」的な使い方をする場合は MIDI2CV 内部に取り込むことは可能だと思います。
CV 出力の分解能と応答速度の兼ね合いから、分解能は 13 ビットとし、下の図のように上位 8 ビットと下位 5 ビットに分けて扱うことにしました。

上位 8 ビットを「整数部」、下位 5 ビットは「小数部」と呼ぶことにします。 b2, b1, b0 の 3 ビットは常にゼロとして扱います。
この整数部を 8 ビット Phase Correct PWM で出力し、小数部は ΣDM により PWM の数値を変化させて表現します。 PWM ハードウェア部単体では、分解能は 8 ビットですから、半音の 1/2 ステップの分解能ということになります。
いま、整数部を n、小数部を f として、n.f と表現すると、ハードウェア PWM だけでは n あるいは (n+1) しか表現できませんが、時間平均として、それぞれ (1 - 0.f) および 0.f の重みを付けたとすると、


n * (1 - 0.f) + (n + 1) * 0.f
= n - n*0.f + n*0.f + 0.f
= n + 0.f
= n.f
となり、n.f が表現できることがわかります。
1次 ΣDM では、このように n, n+1 の 2 値により小数部を表現します。 
2次 ΣDM では、n-1, n, n+1, n+2 の最大 4 値により小数部を表現します。
ΣDM によるノイズ・シェーピング効果を得るには、(ΣDM の次数 + 1) 次以上の減衰特性を持つ LPF が必要です。
ここでは TGmega でエンベロープ出力用として作成したカットオフ周波数約 8 kHz の 3 次バタワース LPF のコンデンサの値を 103 (0.01 μF) から 104 (0.1 μF) に変更してカットオフ周波数を 800 Hz 程度にしたものを使用しています。
回路図を下に示します。

実際には 103 のコンデンサは除去せずに 104 のコンデンサを並列に接続しているので、コンデンサの容量は 0.11 μF となっています。
また、OP アンプに LM358 を使った場合には CV 出力の上限付近の電圧 (約 3 V) での精度が悪くなったために、回路はいじらずに、単に OP アンプを TLC272 に交換しています。
LM358 を使う場合には、LPF の入力側でもう少し PWM 信号を減衰させたほうが良いでしょう。
2次 ΣDM の実現には、モジュレータ内に直列に積分器を2個配置する方法ではなく、いわゆる「MASH」(Multi-stAge noise SHaping) 方式を使い、2個の1次 ΣDM の出力を合成して2次の出力を得ています。
この方法では1次の出力と2次の出力が同時に得られるので、PWM 回路の 2 つの出力端子にそれぞれ出しています。
下のブロックダイアグラムは、プログラムが書きやすいような表現になっていて、原理が分かりやすいような表現にはなっていません。

具体的な話については次回以降に回します。