FPGA 版 FM 音源 (23) -- YMF262 測定 (15)

前回の EG プログラムを Arduino 上の「スケッチ」として実現してみました。
スケッチ自体は長くなるので、次回に回し、今回は簡単な説明のみ行います。
今回は、「音」や「EG 波形」の出力をメインに考え、Arduino に接続したノン・オーバーサンプリング・ディジタル・オーディオ DAC (ROHM BU9480F) の L ch に EG リニア出力、R ch に EG アキュムレータの lb 値を出力します。
EG アキュムレータ値の出力は、以前のノートン・アンプを使った OVCE タイプの VCA (→こちら) に入力し、機能させることを考えています。 VCA 回路の実験はブレッド・ボード上で行ったので、回路は現存せず、これから新たに製作するところです。
EG のリニア出力も、EG アキュムレータ出力も 12 ビット分解能が必要なので、PWM で発生させると PWM の繰り返し周波数が数 kHz と低くなりすぎてしまうので、今回はディジタル・オーディオ DAC 出力のみをサポートしています。
サンプリング周波数はなるべく高くしたいところですが、16 ビット・ステレオで約 44.2 kHz 程度が限界でした。 プログラムの効率化を図れば、48 kHz サンプリングに手が届くかもしれませんが、今回は見送りました。
BU9480F との接続は、「FMmelody」スケッチと同様に下の図のようになります。

このなかで、「IDLE」の LED は使っていないので、配線の必要はありません。
スケッチ冒頭の「#define」の設定により、プログラムの動作を変えることができます。

    #define PRINT_FLAG 1

これを有効にすることにより、前回のプログラムと同様の EG のリニア出力値と EG アキュムレータの値をシリアル経由で「プリント」することができます。
出力は、たとえば次のようになります。

# ar=12, rof=2
0  0  32760
1  0  29711
2  0  26926
3  1  24405
4  2  22124
5  4  20059
6  8  18186
7  15  16481
8  25  14944
9  41  13551
10  63  12302
11  94  11149
12  133  10116
13  183  9179
14  243  8338
15  315  7569
16  399  6872
17  494  6247
18  600  5670

    ...

この設定では、Arduino 本体だけで機能し、外付けの回路を必要としません。
ターミナル・ソフトでキャプチャしてデータファイル化すれば、GNUPLOT でプロットすることができます。
シリアルのボーレイトは「COM_BPS」の #define で指定します。 デフォルトでは 115200 bps の指定になっています。
「プリント」を有効にすると、後述する DAC 出力は強制的に無効にされます。

    #define USE_LCD 1

これを有効にすると、Arduino に接続された 16 文字 x 2 行のキャラクLCD に表示を行います。
LCD との接続については、スケッチを参照してください。
LCD_EN」や「LCD_D7」などの定義を変えることにより、違うピンとの配線にも対応できます。

    #define LCD_PRINT 1

これを有効にすると、LCD 上に EG リニア出力や EG アキュムレータの値の表示を行います。 シリアルの場合と同様、「プリント」を有効にすると DAC 出力は無効にされます。
この状態での LCD 表示は、たとえば次のようになります。

「AR=」と「DR=」は、それぞれ、「アタック・レート」と「ディケイ・レート」の値で、「音」として聴くことを主に考えているので、ディケイ・タイムを長く取って「減衰音」的にするために、DR = AR - 3 として、アタック・タイムの 8 倍に設定しています。
Rof の値はアタック、ディケイ両者に共通なので、DR の方にコロン「:」で区切って付加してあります。
表示の右側の「Lin=」と「Acc=」は、それぞれ、EG リニア出力値 (10 進)、EG アキュムレータ値(16 進) です。
LCD_PRINT」を指定しない場合には、右側の部分はブランクになります。
また、16 文字 x 1 行タイプの LCD (秋月 DMC16117A / S-10551D など) の場合には下のような表示となります。

この場合、「LCD_PRINT」を指定しても、当然のことながら、「Lin=」と「Acc=」の部分は表示されません。

  #define USE_NOSDAC 1

これを有効にすると、シリアル・インターフェースの、ディジタル・オーディオ用ノン・オーバーサンプリング・ステレオ DAC (ROHM BU9480F) の L ch に EG リニア出力、R ch に EG アキュムレータの値を出力します。
それぞれ、分解能は 12 ビットなので、3 ビット左シフトして、2 の補数 16 ビットのオーディオ・データ・フォーマットに合わせています。 当然、「正」の側にだけ振れます。
DAC とのインターフェースには SPI を利用しているので、接続するピンを自由には選べず、前の回路図に示した配線に限られます。
サンプリング周波数は
16 [MHz] / 181 / 2 = 41.198895... [kHz]
となります。
波形写真を下に示します。 

上のトレースが EG のリニア出力 (DAC L ch) で、下のトレースが EG アキュムレータ出力 (DAC R ch) です。
次の写真は、ディジタル・オシロの蓄積モードを利用し、EG リニア出力のピーク付近をトリガ・レベルとして設定し、複数のエンベロープ・カーブを重ね描きしたものです。

#define USE_SOUND 1

これを有効にすると、DAC L ch は EG リニア出力の DC 値ではなく、VCA に約 442 Hz の方形波を入力し、CV 入力に EG 出力を接続したものに相当する波形となります。
具体的には、lb 値からリニア値へ変換する部分の、符号ビットを 442 Hz で変化させているだけです。
次回示すスケッチでは、

    #define USE_LCD 1
    #define USE_NOSDAC 1
    #define USE_SOUND 1
    //#define PRINT_FLAG 1
    //#define LCD_PRINT 1

という設定になっており、

  • シリアル・プリント : なし
  • LCD プリント : なし
  • LCD 表示 : あり
  • DAC : あり
  • サウンド : あり

の状態になっています。