楽譜を表示したい
よくある方法
ブログに楽譜を表示したい場合、一番単純なやり方は、
- Finale や MuseScore などのソフトを立ち上げ、
- 音符を打ち込み、
- それを画像として保存し、
- トリミングし、
- 画像として本文中に貼る
というものだが、とってもめんどくさい。
そうではなくて、今こうやって本文を書いているのと同じように、ただ文字を書くだけで、それを楽譜として表示させられるようにしたい。
それをちょっとずつやっていく。
方針
おおよそ、
- 音符の情報を記述する「コード」を書く(ある程度の可読性があり、慣れればすぐ書け、極力文字数が少ないような記述の方法を自作する)
- その「コード」を解析して、「音の集まり」の情報を得る
- 「音の集まり」の情報から、「楽譜を構成する要素の集まり」の情報を作る
- 「楽譜を構成する要素の集まり」の情報を元に、画面上に各要素を描画する
という流れで、入力を楽譜に変換していきたい。
たとえば、
- コード:C^5 G5 (5は4分音符の意味)
- 音の集まり:オクターブ上のCの4分音符、Gの4分音符
- 楽譜を構成する要素の集まり:第3間に黒い符頭、その符頭の左端から下向きに符尾、・・・
- →それらを描画
という流れである。
以前の記事 最近作ったアプリ「Lead Sheeter」 で触れたものも同じ発想で作っていたが、行き当たりばったりで上手くいかないところがあったので、改めて設計し直すことにした。特に、途中の「音の集まり」の情報、「楽譜を構成する要素の集まり」の情報のところは、既存の楽譜ファイルの形式を参考にすることにした。
musicXML
楽譜の情報をテキストファイルに起こす方法として最も有名なものの一つが musicXML だ。Finale、Sibelius、MuseScore など数多くの楽譜作成ソフトで使えるファイル形式なので、異なるソフト間での楽譜データのやりとりに使われていることも多いかと思う。
musicXML のチュートリアルにある例だが、
- ト音記号
- 4分の4拍子
- 音符は「真ん中のド」の全音符一個
を表す musicXML は、おおよそ
<score-partwise version="4.0">
<part-list>
<score-part id="P1">
<part-name>Music</part-name>
</score-part>
</part-list>
<part id="P1">
<measure number="1">
<attributes>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<clef>
<sign>G</sign>
<line>2</line>
</clef>
</attributes>
<note>
<pitch>
<step>C</step>
<octave>4</octave>
</pitch>
<duration>4</duration>
<type>whole</type>
</note>
</measure>
</part>
</score-partwise>
のようになる。
この musicXML という形式はとてもよくできているが、「音の集まり」の情報と「楽譜を構成する要素の集まり」の情報が混在しているともいえ、また今実現したいこと(ちょっとした単旋律を書くこと)に対してはオーバーキルすぎるので、言葉遣いやデータの階層の面で musicXML を参考にしつつ、独自のものを作ることにした。
- コード
- 音の集まりの情報
- 楽譜を構成する要素の集まりの情報
までの変換の部分は、npmパッケージとして公開し、自作の複数のプロジェクトで共用できるようにした↓
いずれしたいこと:
- musicXML との相互変換
- SVG画像としての出力
- この記事で触れた MathJax のように、ページ中の特定の部分を楽譜に変換する機能(たぶん無理)
今実現していること
前述の leadsheetjs に、「コード」から「楽譜を構成する要素の集まりの情報」への変換部分をある程度作ったので、それを使って1行分の楽譜を書く機能をこちらで実装した。
例えば、
bbb4/4,
G5 Bb5 Eb^5 F^5 | G^5 Ab^6 G^5 | F^5 Eb^5 D^5 Eb^5 | C^5 D^5 Cb^5 Db^5
と打つと、
のように表示される。