FM音源チップを動かしてみた(2)
YM2151が出力するデジタル音声データを受け取り発声するプログラムを作った。VGMデータを演奏することができた。プログラムと回路図はGitHubに。
参考にしたサイト
- YM2151からの左右チャンネルの切り替え信号(SH1, SH2)をI2Sフォーマットに変換する方法。EXORゲートとJK-FFを使ってWSEL信号を作り出すことができる。
- YM2151が出力する音声信号(指数部3bit + 仮数部10bit)をI2S 16bitに変換する方法。
- VGMファイルやその演奏方法については以下より(ほぼ丸パクリ…)。素敵な曲とプログラムに感謝!
接続
ESP32の2つのI2Sを使う。1つはYM2151の出力を受け取る。1つはUDA1334Aに送り出して音を出す。
[YM2151] [ESP32] clock1 -> |5->3.3V| -> BCLK_0 SO -> |5->3.3V| -> DIN_0 SH1 -> |EXOR &| -> |5->3.3V| -> WSEL_0 SH2 -> | JK-FF| [UDA1334A] BCLK_1 -> BCLK DOUT_1 -> DIN WSEL_1 -> WSEL clockM <- |JK-FF| <- MCLK_1 D0~D7 <- GPIO ~iC <- GPIO A0 <- GPIO ~WR <- GPIO ~CS -> GND ~RD -> 5V
クロック
前回は3.579545MHzのクリスタルオシレータでクロックを与えていた。このままESP32で受け取ろうとする場合、
- I2S SLAVE RX(受信):うまく受け取れる
- I2S SLAVE TX(送信):なんかうまくいかなかった。SLAVEでTXの場合、MCLKを作る必要があるとか見たような気も。APLLを使えばOKという記事も。位相が合わない?同期がとれない?よく分からない…
そこで今回はESP32のI2Sが出力するMCLK信号を1/2に分周してYM2151のΦMとした。SAMPLE_RATE = 55930Hzで、これの128倍の1/2倍 = 3.579520MHz。ちと足りないがこれで行く。
左右チャンネルの区別
SH1とSH2を等価に扱っているので、こちらでも指摘されているように左右が正しく一致する確率は50%となる。初期化時に左チャンネルだけ音を出して、それを確認することで整合性を取れそう(そのうちやる)。
プログラム
2つのタスクをCore1で並行動作させた。
- YM2151からの信号を受け取り、16bitの2の補数に変換し、UDA1334Aに送り出す、というのをひたすら繰り返すタスク。
- VGMデータを順に読み取り、YM2151のレジスタに書き込むタスク。
某所よりダウンロードしたGalaga'88のVGMを演奏させてみた。うまく動いているようだ。耳も記憶もあやふやだが何とも懐かしい音がする。試しにYM2414に付け替えたところ、音が消えるはずなのに消えない箇所がいくつか見られた。
まとめ
YM2151のデジタル音声データを取得することができた。次は、これをPCに送って波形を観察したい。