たま日記

たまに書く

FM音源チップを動かしてみた(2)

YM2151が出力するデジタル音声データを受け取り発声するプログラムを作った。VGMデータを演奏することができた。プログラムと回路図はGitHubに。


参考にしたサイト

  • YM2151からの左右チャンネルの切り替え信号(SH1, SH2)をI2Sフォーマットに変換する方法。EXORゲートとJK-FFを使ってWSEL信号を作り出すことができる。

pcm1723.hateblo.jp

  • YM2151が出力する音声信号(指数部3bit + 仮数部10bit)をI2S 16bitに変換する方法。

kikb.web.fc2.com

  • VGMファイルやその演奏方法については以下より(ほぼ丸パクリ…)。素敵な曲とプログラムに感謝!

github.com

接続

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

電圧

YM2151は5V、ESP32は3.3Vで動くので、レベル変換が必要になる。これを使ったけどこっちでも動くと思う。ESP32→YM2151への向き(L→H)の場合は不要(知らなかった!)。

クロック

前回は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に送って波形を観察したい。