秋月電子で買えるようになったPico Audio Packで遊んでみます。
(今回はNuttXでなく、Pico SDK上で動かします)
概要
Pico Playground内のデモでI2Sを用いたオーディオ出力の方法が分かってきたので、X68000用音楽データのMDXファイルをPico上で再生してみました。
MDXについては以下のWikipediaの記述をご覧ください。
FM音源+ADPCMのフォーマットであるMDXファイルは、mdx2wavというコンバータでストレートPCMに変換できます。
元のコードではLinux用アプリケーションとして標準出力にPCMデータを出力するようになっていますが、これをライブラリとして組み込んで、出力されたPCMデータをそのままI2Sに流し込みます。
ソースコード
ソースコードはgithubに置いてあります。mdx2wavをsubmoduleにしているので、git cloneの際には--recursive
を付けてください。
makeすると build/pico-mdx/pico-mdx.uf2 が出来るので、これをインストールして起動するとMDXファイルの再生が始まります。
再生するファイルはバイナリ内に埋め込みになっています。pico-mdx/CMakeLists.txt に以下の記述があるので、ファイルを変更する場合はここに再生したいファイルをフルパスで指定してください。
MDXファイルに対応するPDXファイルがある場合には、PDX_FILE_NAME
の行のコメントアウトを外してここにファイル名をフルパスで指定してください。
【追記】 最新のソースコードでは複数ファイルの再生に対応したので、MDXファイルの指定方法が変更されています。Raspberry Pi PicoのBOOTSELボタンを使ってMDX playerを制御する を参照してください。
target_compile_definitions(pico-mdx PRIVATE
:
#
MDX_FILE_NAME="${CMAKE_CURRENT_LIST_DIR}/test.mdx"
# PDX_FILE_NAME=""
)
内部で利用しているmdx2wavは、オリジナルのソースコードから以下の変更を加えています。
- 固定データにconstを付加
- ライブラリ中にある書き換え不要なデータにconstを付けました。Picoの場合こうしたデータはフラッシュ上に置かれるので、少ないRAMを節約するためには重要です。
- FM音源エミュレートライブラリfmgenを削除
- 元のコードではFM音源のエミュレート用ライブラリとしてfmgenとmameの両方が載っていて切り替え可能になっていますが、デフォルトではmameを使うようになっている上fmgenが大きな配列を固定で持っていたので、メモリ節約のために削除しました。
- 非アラインメントデータアクセスの修正
- 再生するMDXファイルをRAMにコピーする処理でワードデータをunalignedアクセスする可能性のある箇所があり、ファイルによってクラッシュする問題があったので修正しました。PCではunalignedアクセスは遅いだけで動作はしますが、Cortex-M0+ではHard Faultになるためこの修正が必要です。
-
【追記】渡されたデータの直接再生
- 元のコードでは、最初に渡されたMDX, PDXデータを一旦自分で確保したメモリにコピーしてから使うようになっていましたが、渡されたデータを直接参照して再生するように変更しました。特にサイズの大きなPDX(サンプリング音)をフラッシュに置いたままにできるようになったことで、RAM消費を大幅に削減できるようになりました。
制約
現状では以下の制約があります。
再生できるMDXファイルはバイナリに埋め込まれた1つのみです- ファイル再生時のサンプリングレートは22.05kHzになります
- 44.1kHzだと処理が間に合わず音が途切れ途切れになってしまいます。特にPico向けの最適化などをやっていないこともあり、リアルタイムでのFM音源のエミュレーションはさすがにちょっと厳しいようです。
-
PDX(サンプリング音)の再生は未サポートですこれは非常に残念なのですが、端的に言うと「RAMが足りない!」。mdx2wavは再生ファイルを一旦メモリに読み込んでから処理するようになっていますが、264kBしかないPicoのSRAMはサンプリング音を扱うには小さすぎました。フラッシュには余裕があるのでフラッシュメモリ上のデータを直接処理できれば再生できるかも知れませんが、上記の通りFM音源のみでも44.1kHzだと間に合わないので、PCM合成も行うと22.05kHzでも厳しいかも知れません。
-
【追記】PDXファイルの再生に対応しました!
- mdx2wavを修正してデータを一旦RAMにコピーせず直接再生するようにしてみたところ、MDX,PDXともに問題なく再生できるようになりました。性能的に間に合うかも気になっていたのですが、22.05kHzであればPCM再生も問題ないようです。
実行
再生時の動画をtwitterに上げました。