Pakurino (2)

Arduino IDE 付属のサンプル・スケッチ「Melody」を FM 音源版にしたスケッチ「FMmelody」を (→こちら) におきました。
解凍してできた「FMmelody」フォルダ (とそれに含まれるファイル) をご使用中の「スケッチ・ブック」のフォルダにコピーしてご利用ください。
現状では 16 MHz クロックの ATmega88 / ATmega168 / ATmega328 の系列にしか対応していません。 確認しているのは ATmega168 だけです。
ATmega168 の TIMER1 を使った 9 ビット PWM 8 ビット Phase Correct PWM 出力と、ディジタル・オーディオ用 16 ビット DAC (ノン・オーバーサンプリング・タイプ) 出力に対応しています。 (6/29 訂正) 
スケッチを実行すると、音色を下の順番で変えながら「きらきら星」のメロディーを演奏し続けます。

  • Acoustic Piano
  • Electric Piano
  • Tubular Bells
  • Marimba
  • Jazz Guitar
  • Finger Bass
  • Slap Bass

FM 音源のオペレータの仕様は OPL3 のサブセットで、音色パラメータはオペレータ当り FB、MULT、DR、TL の4個しかありません。 
プログラムの簡略化のため、EG で可変できるのはディケイ・レートだけで、減衰音のエンベロープしか発生できません。 そのため、音色にはあまり変化がつきません。

ハードウェア

デフォルトでは PWM の方が有効になっています。 スケッチ中のコメント・アウトしてある一行のコメント記号を削除してコンパイルするとディジタル・オーディオ用 DAC を使うモードになります。
PWM 出力を利用する場合の結線図は次のようになります。

ディジタル 9 番ピン (OC1A 出力) から LPF を介して出力を取り出します。 PWM 周波数は 16 MHz / 512 = 31.25 kHz となっています。 音源としてのサンプリング周波数はその 1/2 の 15.625 kHz です。
Arduino 基板上でディジタル 13 番ピンに接続され、表示が「L」となっている LED を CPU 負荷量の表示に使っています。
アイドル状態が多いほど LED は明るく光り、CPU が忙しくなるほど LED は暗くなります。
ディジタル 13 番ピンを周波数カウンタで測ると (平均で) サンプリング周波数の 15.625 kHz を示し、デューティー測定可能なテスタでデューティーを測ると、アイドル状態の大体のパーセンテージが分かります。
PWM モードで実測すると、アイドル率が約 50 %、つまりビジー率も 50 % 程度です。
LPF の具体的な回路は次のようになります。

(a) は OP アンプを使ったアクティブ・フィルタで、(b) はパッシブ LC フィルタで、カットオフ周波数 8 kHz 程度の 3 次バタワース特性の LPF を実現したものです。
LM358/LM324/LM2904/LM2902 タイプの OP アンプを使ってもクロスオーバー歪が出ないように配慮してあります。
(c) と (d) は、圧電スピーカー (圧電サウンダ、Piezo Speaker) を使う場合で (d) は直結した場合です。
(c) は抵抗を挿入して、圧電スピーカーの容量分と組み合わせてカットオフ周波数 4 〜 8 kHz の1次 LPF を構成したものです。
当然 (d) ではノイズが多く、(c) では音が小さくなってしまいますが、ノイズは減って聞きやすくなります。
ノン・オーバーサンプリング・タイプのディジタル・オーディオ用 DAC を使う場合の回路図は下のようになります。
DAC 出力はステレオですが、左右チャンネルともに同じデータを出力しているので、モノラルにしかなりません。
ATmega168 の内蔵モジュールの SPI と TIMER2 を使っています。

ここで、「ノン・オーバーサンプリング・タイプ」というのは、オーバーサンプリング用のディジタル・フィルタに使われる 256 fs や 384 fs のクロックを必要としないタイプのことを表しています。
具体的には、

  • シリアルクロック (ビットクロック)
  • シリアルデータ
  • LR クロック

の 3 本の信号線でインターフェースし、

  • 16 ビット
  • MSB ファースト
  • 右詰め

の、いわゆる「標準フォーマット」のデータ形式のものです。
安価で入手可能なものとしては、毎度おなじみ ROHM BU9480F や、NEC μPD6376 などがあります。
実際に接続して音を出して確認しているは BU9480 だけで、それ以外については実際には確認していません。
LRCK をプルアップしているのは、ISP 時にレベルを確定させ、DAC から異音が出力されるのを防止するためのものです。
SPI のピンは ISP 用のピンと共用されているので、ISP により ATmega168 にプログラムを書き込むと DAC の SCK、SDAT もドライブされ、LRCK 入力が浮いていると、異音が出力されてしまいます。
Arduino として USB/シリアル書き込みしかしないのであれば、必ずしもプルアップは必要ありません。
ディジタル・オーディオ DAC モードではアイドル LED をディジタル 8 番ピンに接続することを想定しています。 
LED を接続するピンは、スケッチ中の定義を変更すれば変えることができます。 ただし、ディジタル 3, 11, 13 番ピンは回路動作のために必要なので、これらのピンに割り当てることはできません。
また、ディジタル 12 番ピン (MISO) はマスター・モードの SPI 動作では強制的に入力にされるので、LED 出力としては機能しません。
Arduino 基板上の「L」LED は SCK であるディジタル 13 番ピンに接続されているので、SCK 信号により薄暗く点灯します。
DAC モードでのアイドル率の実測値は約 30 % で、つまり、ビジー率は約 70 % ということになります。
長くなりましたので、スケッチの説明は次回にまわします。