Rustでテキスト音楽「サクラ」をコツコツ書いていたのですが、3日目にブラウザで音が鳴らせるようになったので記事にまとめてみました。
テキスト音楽「サクラ」とは何か
「ドレミ」や「cde」のテキストをMIDIファイルに変換するコンパイラです。 手軽に音楽を作成できるツールです。
完成したもの
今回、ブラウザで簡単に「ドレミ」や「cde」の楽譜を書いて音が再生できるようになりました。まずは、以下で試すことができるので見てみてください。PC/スマートフォン、タブレットのブラウザで動かすことができます。
なぜサクラをRustで書き直したのか
あるディープラーニングの仕事の待ち時間(データ学習の間)に何かできないかなぁと思って、待ち時間にコツコツRustでサクラを作り直していました。とは言え、3日目にして、公開できるレベルまで作ることができました!
サクラ開発の歴史 - テキスト音楽「サクラ」は、Delphi(v1)→Delphi(v2)→C(未完成)→Go(未完成)→Rust(今回)と何度も途中まで作り直しています。途中まで作ると、飽きてしまうので、最後まで完成したのは、Delphiで作ったv2で、現在もv2がサイト上で公開されています。
現在のところ、今回のRust版は、未完成のGo言語版と同じくらいまで作っていますが、ブラウザで動かして、みんなに使ってもらいやすい分、もう少し実装が進みそうです。やはり、公開して使ってもらえると、モチベーションが上がりますね!
ブラウザでサクラを動かす仕組みは?
サクラは、テキストからMIDIファイルを作成するコンパイラです。そのため、今回作ったのは、テキストを読み込んでMIDIファイルを生成する部分です。MIDIファイルを生成したら、PicoAudioというブラウザ上でMIDIを再生するライブラリにMIDIファイルを投げて再生します。
ソースコード → (サクラでコンパイル) → MIDIファイル
MIDIファイル → PicoAudio.jsで演奏
サクラはRustで書いて、WebAsseblyに変換し、ブラウザからWebAssemblyを読み出してコンパイル処理をします。
サクラのRust版はオープンソースで開発し、以下で公開しています。
簡単に、処理の流れを紹介します。
[1] ストトン表記→MMLへの変換
最初に、「ドレミ」の表記(これをストトン表記と言います)を、MMLに変換します。以下のソースです。バージョン、0.1.0だと、145行ほどで、単純に1文字ずつ最長一致で単語を確認して、文字列置換しているだけです。
[2] MML→MIDIへの変換
MMLの表記は非常に複雑で簡単にパースできません。特に音符の後の音長表現は、比較的複雑な処理が必要です。そこで、以前、Go言語で作ったときには、コンパイラコンパイラを使ったのですが、今回は、何も考えず手書きでパーサーを書きました。
また、MMLからMIDIへの変換はそれほど重たい処理ではないので、あまり効率を考えていません。逆にコードが読みやすいかも。
サクラでは、英小文字(cdeなど)は1文字コマンド、英大文字(Track/Channelなど)は複数文字のコマンドと決まっています。
それで、英大文字は、本来Mapなどに入れておくと高速に判定できるのですが、コマンドは、それほど多くないと思ったので、連続するifで分岐しており、全くお手本にならないので、今後改善したいところです。
なお、MIDIに変換する前に、MMLのコードをトークンに分割します。なお、楽譜情報には繰り返しなどの仕組みがあるので、トークンに変換した後で繰り返し処理などを解決します。
それで、以下のような仕組みになっています。
- [1] ソースコード(MML)
- [2] トークンに分割 --- /src/lexer.rs
- [3] 分割したトークンを元に実行してイベントを書き込み --- /src/runner.rs
- [4] イベントをソートしてMIDIに変換 --- /src/midi.rs
コマンドラインで実行する方法
もちろん、Rustなので、ブラウザだけでなく、コマンドライン上で実行できます。以下にCUIで作曲する方法を紹介しています。
リポジトリから最新版をダウンロードしてサクラのコマンドをビルドする方法。
# リポジトリを取得
$ git clone https://github.com/kujirahand/sakuramml-rust.git
$ cd sakuramml-rust
# ビルド
$ cargo build
# MMLファイルをMIDIに変換
$ cargo run music.mml
まとめ
以上、簡単に、テキスト音楽サクラ「サクラ」のRust版の仕組みを紹介しました。MMLコンパイラの開発は、MIDIの知識がちょっと必要ですが、それほど難しくなくて、Rustの練習にもぴったりの内容です。また、Rustを使うとブラウザでプログラムを動かすWebAssemblyを作るのも簡単でした。
サクラのブラウザ版は今後も気まぐれに開発していこうと思っています。
良かったら使ってみてください。
メモ - Rustの本書きました
そうそう、先日私が書いたRustの本、良かったら見てみてください!!この本の中では、簡単なMML→WAVファイル生成の作り方も解説しています。
参考
- Qiita > CUIで音楽製作環境の構築(macOS版) --- MIDI関連ツールのセットアップについて