以下の内容はhttps://yokomumu.hateblo.jp/entry/2025/10/01/235852より取得しました。


レトロゲームのBGMを再現する装置~制作に取りかかったぞ

以下の記事は、ここまでのあらましです。

yokomumu.hateblo.jp

そして何はともあれ、ブレッドボードに回路を組み立ててみました。

ESP32マイコンとI2S DAC、それにスピーカーアンプです。実際の基板を起こす時にはもう少しデバイスを追加する予定ですが、これが今回の中核部です。

音出し実験!

試しに正弦波を生成してI2S DACに送るサンプルを作ってみたところ、澄み切った音で「ポー」とか「ピー」とか音が鳴りました。聴力検査の音に似ています(笑)

ESP32マイコンはDual-Coreなので、Core0で演奏制御やWi-Fiなどのメインの処理、Core1で音声の処理(音源チップのエミュレーション)をするように実装しました。音声データのサンプル周期は22KHzで行い、その1/10の周期(0.45ms)でまとめて10サンプル分をレンダリングして共有メモリに置き、それをメインタスクでDMAを使ってタイミングを見ながらI2S DACに転送する処理をします。

PlatformIOのArduino環境を使っているのですが、せっかくFreeRTOS動いているならばと、タスク分割やタスク間通信などをシステムコールを使うようにしたところ、かなりスマートに書けましたよ。

音源チップのエミュレーション

試しにYM2149(PSG音源)のエミュレーションをしてみました。MAME由来のemu2149というモジュールを使います。

そのまま組み込んだだけでも音は出るのですが、ノイズチャンネルの音がちょっと大きいので調整する余地があるのと、エイリアスノイズが乗っているため、リサンプリングして22KHzでもノイズが出ないように作り込む必要がありそうです。

そもそも、YAMAHAの音源チップは55KHzで音声の処理をしているそうなので、同じ周波数でレンダリングしてからリサンプリングした方が良いのだそうです(AIによると)。最終的に作り込む際にはその辺も考慮してみたいと思います。

そして忘れてはいけないレンダリング処理時間(10/22050msに収める必要がある)ですが、全然余裕でした(笑)。おおよそ10~20マイクロ秒未満で10サンプル分のレンダリングが完了します。

そして肝心のFM音源のエミュレーションですが、Nuked-OPMというモジュールをまずは組み込んでみることにしました。GitHubにオリジナルのコードがあるのですが、VGMPlayerなどでカスタムするなど軽量化されたモジュールもあります。TinyOPMという、更に軽量化されたモジュールがあるらしいのですが、リンク切れしていました、、

こちらのレンダリング処理時間ですが、1100~1300マイクロ秒と、規定の450マイクロ秒に対してだいぶオーバーしてしまいます。こちらはESP32に最適化するなど、手を入れる必要があるでしょう。

レトロゲームのBGMを再現する

再生するレトロゲームのデータはS98ファイルというPCゲーム由来のもので、過去に吸い出したものがあったため、とりあえずそれを組み込んでテストすることにしました。

YSIIの中盤あたりに出てくる「ノルティアの氷壁」シーンのBGMです。FM音源で主旋律、PSG音源でコードとリズムを演奏しているようです。

FM音源レンダリングが間に合っていないため、DMAバッファが空になってしまい、音がプツプツと切れますが、PSGパートだけにすると、エイリアスノイズ混じりですがそれらしく再生しています(やはりノイズチャネルの音がでかいのは気になりますが)。

ぶっちゃけ、音切れなども含めてまだ殆どノイズみたいな音なので、先は長そうです(汗)。

ということで、ESP32マイコンはPSGだけエミュレーションするには高性能過ぎるが、FM音源をエミュレーションするにはちょっと心許ないマイコンという感じです。

次へと続きます。

yokomumu.hateblo.jp




以上の内容はhttps://yokomumu.hateblo.jp/entry/2025/10/01/235852より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14