【脳筋】東方旧作アレンジのMMLを再生したくてWSLでCライブラリをビルドした話
注意:筆者はPMD、MML、PC-98のFM音源について本当に何の知識もない状態からスタートしています。PC-98すら実機を触ったことがありません。詳しい方から見たら突っ込みどころしかないと思いますが、そういう記事です。「知識ゼロの人間がAIに丸投げしたらどうなったか」の記録として読んでください。
音楽だと思ったら暗号だった
音楽ファイルだと思ってわくわくしながらダウンロードしたら、暗号だった。
きっかけはSaria Lemesという作者の東方旧作アレンジだった。
YouTubeで見つけた。
【PC-98アレンジ】永遠の巫女 - 東方靈異伝
PC-98のFM音源で鳴る東方の曲。「Eternal Shrine Maiden」——東方靈異伝のテーマ曲のPMDアレンジ。
配布リンクがあった。Pastebinという馴染みのないサイトだった。
ダウンロードボタンを押した。落ちてきたのはテキストファイルだった。
開いてみる。
#Title Eternal Shrine Maiden (Website Ver.)
#Composer ZUN
#Arranger pedipanol
#DT2Flag on
#Timer 190ヘッダの後に意味不明な文字列がズラズラ並んでいる。@004 0 6 18 12 1 4 3 35...みたいな変な数値の羅列。A l8 v11 [d2dc<a f b2>dc<a...]みたいな記号の嵐。
なんやねんこれ。
MIDIは知ってる。でもこれは未知すぎた。音楽のための楽譜に見えない。ただの暗号にしか見えなかった。
あとで知ったが、これはMML(Music Macro Language)というテキストで音楽を記述する言語で、CDEFGABが音階、L4が四分音符、O4がオクターブ、という体系らしい。らしい、というのは当時の自分にはそんな知識は一切なかったからだ。
でもこのテキストをどうやって音にするのか分からない。
サイトは英語だし、PMDの再生環境なんて触ったこともない。このテキストを「コンパイル」して.Mファイルにして、それをFM音源エミュレータで鳴らす? 手順が多すぎる。
FMPMD2000というWindows用のPMD再生ソフトがあることは見つけた。2025年4月更新。Win11でも動きそうだ。使おうと思った。
「PMDWin.dllが見つかりません」
即あきらめた。たぶん探せばどこかにあるんだろうけど、めんどくさかった。

Claude Codeに丸投げした
あーもういいや。AIにやらせよう。
Claude Codeを開いて、このテキストファイルを渡した。
「これを再生したい」
ここから遠回りが始まった。
MMLソースから音を出すまで
Claude Codeが提案したのは、WSL(Windows Subsystem for Linux)上でpmdminiというCライブラリをビルドするアプローチだった。
pmdmini。PC-98のFM音源ドライバ「PMD」(Professional Music Driver、KAJA氏作)の再生エンジンをCライブラリ化したOSSプロジェクト。内部でYM2608(OPNA)のFM音源をソフトウェアエミュレーションしている。GitHubにある。
Ubuntu上でcloneして、依存関係を解決して、ビルドする。言葉にすると簡単だが、PC-98音源ドライバのエミュレーションライブラリだ。すんなりいくわけがない。
ビルドエラー。依存関係の不足。ヘッダファイルの不整合。Claude Codeと二人三脚でひとつずつ潰していく。人間の部下だったら発狂してる作業量を、AIは淡々とこなす。
ただ、ここでひとつ問題があった。
手元にあるのはMMLのソーステキストであって、コンパイル済みの.Mファイルではない。pmdminiが食えるのは.Mファイルだ。MMLソースをコンパイルして.Mにする工程が別途必要になる。
結論から言うと、Saria LemesのMMLソースの再生は後述する筆者のガバによって苦難の道になった。
MMLをコンパイルして.Mにする環境構築、音色定義の解釈、PMDコンパイラの入手……どれもハードルが高すぎた。しかもClaude Codeは、YM2608のFM合成エンジンをPythonで丸ごと再実装しようとし始めた。pmd_renderer.py、1400行超。FM音源チップのソフトウェアエミュレータを自前で書くという、とんでもない方向に突っ走った。その解析に49分かかっても終わらない。「Imagining...」の表示を延々と眺める。修正を一発入れるだけでも33分。「Cooking...」の表示を延々と眺める。


悟った。これは無理だ。
もっと簡単な曲から試すべきだった。いきなりSaria Lemesの複雑なアレンジで挑んだのが間違いだった。
ZUNの.Mファイルで道が開けた
行き詰まっていたとき、方針を変えた。
MMLソースのコンパイルは諦めて、最初からコンパイル済みの.Mファイルを探した。
見つけたのはZUN本人のサイトだった。
https://www16.big.or.jp/~zun/html/pmd.html
ZUNの個人サイトといえば「幻想的音楽」のページが有名だが、実はPMDファイルの配布ページが別にある。ここに東方旧作のBGMが.Mファイルで置いてあった。知る人は少ないかもしれない。
ダウンロードした。タイムスタンプを見た。
1998年10月26日。
28年前のバイナリファイルが、2026年のWindows 11のダウンロードフォルダに入っている。ファイルの中身は、28年前のZUNがPC-98の前に座って打ち込んだFM音源の楽曲データだ。
これをpmd2wavに通した。
鳴った。
YM2608っぽい音がした。「幻樂団の歴史」——ZUNが過去の東方楽曲をアレンジしたCDに収録されているPC-98音源の音と似た音が出ていた。28年前にZUNが打ち込んだ曲が、2026年のWSL上で、pmdminiのソフトウェアエミュレーションを通じて、WAVファイルとして再生された。
デジタル考古学だと思った。
pmdminiの中身はYM2608のFM音源をソフトウェアで再現している。でもあくまで「近似」だ。ヤマハのエンジニアが設計したFM音源チップを、ソフトウェアで模倣している。完全再現ではない。でもその近似で十分だった。
ここから道が開けた。.Mファイルの再生パイプラインが確立したことで、pmd2mml(逆コンパイラ)も使えるようになった。.Mファイルの中身をMMLテキストとして読み出せる。
ただし「逆コンパイル」という言葉には注意が必要だ。
MMLテキストをmc.exe(PMDコンパイラ)でコンパイルすると、人間のための情報は全部捨てられる。コメント、マクロ名、ループ構造、セクション区切り、空白やインデント——全部消える。残るのは「チャンネルごとの命令バイト列」だけ。音符のピッチ、長さ、音色変更、テンポ変更がバイナリで並んでいるだけのデータ。
逆コンパイルで復元できるのは、音程や長さ、音色・音量・テンポの変更命令くらいだ。元のループ構造、マクロ定義、コメント、作者の意図した書き方は戻ってこない。
C言語をコンパイルして.exeにしたあと、逆アセンブルしても元のCソースには戻らないのと同じ理屈だ。機械が実行するのに必要な情報だけが残って、人間が読むための情報は全部捨てられる。
つまりpmd2mmlが出力するMMLは「機械的に復元した楽譜」であって、Saria Lemesが書いた「人間の意図を持ったMML」とは全く違うものになる。
環境は ~/Desktop/pmd-mml-player/ に出来上がった。3つのツールが使える状態になった。
pmd2wav — .MファイルをWAVに変換。コマンド一発。
pmd2mml — .Mファイル(コンパイル済みバイナリ)をMMLテキストに逆コンパイル。楽譜が読める。
pmdmini本体 — PMD再生エンジンのCライブラリ。
この時点では、最初の目的だったSaria LemesのMMLソースの再生にはたどり着けていなかった。pmdminiとは別に、FM合成エンジンを自前でPythonに書かせて再現しようとするアプローチが間違っていた。正規ルート(PMDDotNETでコンパイル)に気づくのはもう少し後の話だ。
でも方針を変えてZUNの.Mファイルを食わせたら道が開けた。遠回りしたおかげで「.Mファイルの再生・変換・逆コンパイル環境」という資産が生まれた。
遠回りで得た資産
整理する。
FMPMD2000のDLLエラーで撤退してClaude Codeに丸投げした結果、今できるようになったのはこの程度だ。
pmd2wavでZUNの.MファイルをWAV化できるようになった — 幻樂団の歴史のCDみたいな音でWAVファイルが出力される。コマンド一発。
pmd2mmlで逆コンパイルできるようになった — ただし前述の通り、復元されるのは機械的な楽譜であって、元のMMLソースとは別物。
WSL上のビルド環境ができた — 今後PC-98関連のツールをビルドする基盤。
この時点ではSaria LemesのMMLソースの再生にはたどり着けていなかった。MMLからの自前WAV生成もガビガビで全然似てなかった。
でも「.Mファイルを渡せばWAVが出てくる環境」がWSL上にある、という事実は残った。そしてこの環境が、のちに正規ルート(mc.exeでのコンパイル)に切り替えたとき、そのまま活きることになる。
読者向け:2つの方法
「自分も.Mファイルを再生したい」という人向けに、2つの方法をまとめておく。
方法1:簡単な方法(FMPMD2000)
所要時間:3分
FMPMD2000をダウンロード・インストール
.Mファイルを開く
再生ボタンを押す
以上。「とりあえず聴きたいだけ」ならこれが最速。ただし「PMDWin.dllが見つかりません」と出る場合は、ドライバ(DLL)を適切な場所から探してきてください。筆者はここを横着した結果地獄を見ました。また、MMLソーステキスト(.txt)しか手元にない場合は、別途PMDコンパイラでのコンパイルが必要。
方法2:遠回りだけど資産が残る方法(WSL + pmdmini)
所要時間:30分〜1時間
WSL (Ubuntu) が入っている前提。
bash
# 1. 依存パッケージ
sudo apt update
sudo apt install -y build-essential git libsdl2-dev
# 2. pmdminiクローン & ビルド
cd ~/Desktop
git clone https://github.com/mistydemeo/pmdmini.git
cd pmdmini
make
# 3. pmd2wav で .M → WAV変換
./pmd2wav input.M output.wav
# 4. pmd2mml で逆コンパイル(MMLソース復元)
./pmd2mml input.M > output.mml(※実際のビルド手順は環境により異なる場合があります。上記は概要です)
WAV変換ができれば、ffmpegでMP3にするなり好きにできる。pmd2mmlで逆コンパイルすれば、28年前に打ち込まれたMMLがテキストとして手に入る。
そもそもの正解ルート
ここまで読んで「いや、最初からこうすればよかったのでは」と思った方、その通りです。
筆者の当初の目的は「PastebinにあったMMLソーステキストを音にしたい」だった。正解ルートはこうだったはずだ。
PMDコンパイラを入手する — オリジナルはKAJA氏のmc.exe(DOS用)だが、現代環境ではPMDDotNET(kuma4649氏作、.NET製の互換実装)が使える
MMLテキストを.Mファイルにコンパイルする — MMLソース → .Mバイナリ
FMPMD2000で.Mを再生する(DLLをちゃんと揃えて)、またはpmd2wavでWAV化する
「MMLソース → コンパイラで.Mに変換 → 再生」の3ステップ。
筆者がやったのは、この「コンパイル」の工程を飛ばして、pmdminiで直接どうにかしようとしたことだ。pmdminiは.Mファイルを食う再生エンジンであって、MMLコンパイラではない。そもそも道具の選択が間違っていた。
知識がないとはこういうことだ。
追記:正規ルートでやり直したら一発だった
この記事を書いている途中で、正規ルートを実際に試してみた。
PMDDotNET(PMDコンパイラの.NET互換実装)を入手し、Saria LemesのMMLソーステキストをコンパイルして.Mファイルを生成。それをpmd2wavに通した。
一発できれいな音が出た。
正規ルート導入前は悲惨だった。パートはバラバラ、音は全く似てない、ガビガビ。あれだけ時間をかけて出来上がったのがゴミみたいな音だった。それが正規ルートに切り替えた瞬間、一発でリファレンスに近い音が出た。大革命だった。
音程が低い問題があったが、+2、+3、+4半音のバージョンを作って聴き比べた結果、+4半音(短3度)で完全一致。たぶん鳴らしたかったMMLは原曲から4半音低く書かれていて?、マスタートランスポーズ _M+4 で補正するのが正解だったらしい。知らんけど。
最初にYouTubeで聴いて「この音を自分の環境で鳴らしたい」と思った、あの音がWSLから出てきた。音量が多少違うくらいで、ほぼ同じ音。
あの49分間は何だったのか。
用語集
PMD — Professional Music Driver。KAJA氏作のPC-98用FM音源ドライバ。MMLで書かれた楽曲を.Mファイルにコンパイルして再生する
mc.exe — PMDのオリジナルMMLコンパイラ。DOS用
PMDDotNET — mc.exeの.NET互換実装(kuma4649氏作)。現代のWindows/Linux環境で動く
YM2608 (OPNA) — PC-9801-86サウンドボードに搭載されたFM音源チップ。FM 6ch + SSG 3ch + リズム + ADPCM ヤマハ製
MML — Music Macro Language。テキストで音楽を記述する言語
pmdmini — PMDの再生エンジンをCライブラリ化したOSS。FM音源のソフトウェアエミュレーションを行う
pmd2wav — pmdminiを使って.MファイルをWAVに変換するCLIツール
pmd2mml — .Mファイルをmmlソースに逆コンパイルするツール
FMPMD2000 — Windows用のPMD/FMP再生ソフト。GUIで.Mファイルを開けば即再生
Pastebin — テキスト共有サイト。MMLソースの配布に使われていた
おわりに
Pastebinからテキストファイルが落ちてきて、英語だし意味わかんないからClaude Codeに丸投げして、WSLでCライブラリをビルドして、28年前の.Mファイルで道が開けて、YM2608っぽい音が鳴った。
FMPMD2000で3秒で終わる話を、盛大に遠回りした。
でも、その遠回りのおかげで、.Mファイルを「聴く」だけでなく「変換する」「読む」「理解する」がたぶん?できるようになった。
そして記事を書いている途中で正規ルートを試したら、当初の目的だった東方のMMLアレンジが一発で鳴った。盛大に遠回りした末に、最初の目的地にたどり着いた。
教訓:AIに丸投げする前にフローを作れ
AIコーディング系記事では耳タコ案件かもしれないが反省点がある。
正規ルートに切り替えたら一発で鳴った。ということは、泥沼にハマった本質はAIに丸投げしたことじゃない。何も分からない状態でいきなりAIに投げたことだ。
正解ルートは「MMLソース → mc.exeでコンパイル → .M → 再生」の3ステップだった。これを最初に把握していれば、Claude Codeへの指示も「mc.exeをWSLで動かしてこのMMLをコンパイルして」と具体的にできた。
でも筆者にはPMDの知識がゼロだったので、「このテキストファイルを再生したい」としか言えなかった。Claude Codeは言われた通りにpmdminiをビルドし、さらにFM合成エンジンを自前でPythonで書き始め、49分かけて迷子になった。道具の選択が最初から間違っていた。
AIと協力してプロジェクトを進めるなら、丸投げの前にまず全体のフローを作った方がいい。「入力は何で、出力は何で、間に何が必要か」を人間側で整理してからAIに渡す。でないと、AIは全力で間違った方向に突っ走る。人間が方向を示して、AIが実行する。この順番を守らないと、今回みたいに時間を盛大に無駄にする。
AIは万能じゃない。ただし、正しいルートを与えれば、最短でゴールまで連れていく。正規ルートに切り替えたら一発で鳴ったのがその証拠だ。
実は筆者、全く同じ失敗を前にもやっている。
PS3のホームブリュー開発を始めたとき、PSL1GHT(PS3ホームブリュー用のOSSツールチェイン)の存在を知らなかった。本来は「Cでコードを書いてmakeでビルドする」のが正規の手順だが、ビルド環境の存在自体を知らなかったので、AIにPythonでバイナリパッチを当てさせてSELFファイルを直接生成させようとした。しかもClaude Codeではなくチャットで。
構造が全く同じだ。「ツールチェインの存在を知らない人間がAIに丸投げして、力技で突破しようとする」。PMDでmc.exeを知らなかったのと、PS3でPSL1GHTを知らなかったのは同じ失敗。2回目なのに学んでいない。
デジタル考古学は、遠回りした方が面白い。……でも次こそはもう少し賢く遠回りしたい。3回目はさすがにない。たぶん。
普段はAIがミスるたびに反省の川柳を詠ませている側なのだが、今回ばかりは自分が詠む番だ。
懲りもせず また丸投げの 力技 知らぬまま AIも共に 道迷う 正解は 三歩手前に あったのに 四十九分 画面の向こう まだ考え DLL 見つかりません で全て終わる
