Pythonで音楽学
music21は音楽学のためのライブラリで、音楽構造の抽出、変換、編集などといったことを記号操作によって行う。外部プログラムと連携して、抽出した情報の可視化もできる。
記号操作と書いたのは、MusicXMLやABCのような記譜用のマークアップ言語で書かれたファイルを入力として読み込んで、内部でも音楽要素を記号として扱って処理を実行するから。音響信号は扱えないので、WavやらMP3といった音声ファイルは読み込めない。
Pythonのインタラクティブモードであれこれ試すと楽しい。音楽学はよくわからないので*2、簡単にできる範囲で可視化したりして遊んだ。
ファイルを読み込んで楽譜を表示する。
楽譜の表示にはMuseScoreかFinale(Finale Reader)が必要。どちらのソフトも演奏機能があるので聴くこともできる。
>>> from music21 import * >>> s = converter.parse('/home/naraba/program/python/music21/etude10-05.xml') >>> s.show()
読み込んだ作品はショパンのエチュード 作品10 第5番(G♭ major*3 )、愛称「黒鍵」。
こういう曲。
音楽の調を調べる。
>>> s.analyze('key') <music21.key.Key of F# major>
F♯ majorはG♭ majorの異名同音調。
オブジェクトの階層構造は伝統的な西洋音楽の階層構造を反映していて、上からScore(総譜)、Part(パート譜)、Measure(小節)、Note(音符)などのようになっているらしい。「黒鍵」はピアノ曲で右手と左手のパートがあって、メタデータ部を合わせると3つのパートとなる。
>>> s <music21.stream.Score 181616076> >>> len(s) 3 >>> s[0], s[1], s[2] (<music21.metadata.Metadata object at 0xed6a08c>, <music21.stream.Part piano>, <music21.stream.Part piano>)
左手パートの小節数は86。左手パートの冒頭10小節のピアノロールを表示。
>>> len(s[2]) 86 >>> s[2][:10].plot('pianoroll')
右手パートの小節数も当然86。右手パートに含まれる音符の長さのヒストグラムを表示。
>>> len(s[1]) 86 >>> s[1].plot(format='histgram', values='quarterLength')
四分音符の長さが基準で1。横軸目盛の割り切れない数の表示が困ったことになっているが、ほとんど16分音符の三連符*4しかない。
右手パートに含まれる音符のピッチクラスごとの数を集計。それに続いて、ピッチクラスの重み付き散布図を表示。
>>> s[1].pitchAttributeCount('name') {u'E-': 163, u'D-': 254, u'F': 1, u'B-': 162, u'A-': 218, u'G-': 181} >>> s[1].plot(format='scatterweighted', values='pitchclass')
作品の愛称「黒鍵」の由来通り、右手パートはほとんどがピアノの黒鍵の音だけど、一音だけFの音(ファ)がある。音の長さもこの作品ではレアな四分音符。
F音がどの小節にあるのか探して、その小節だけ楽譜を表示。
>>> for m in s[1].getElementsByClass('Measure'): ... for p in m.pitches: ... if p.name == 'F': print m.measureNumber ... 66 >>> s[1][66].show()
全体を長2度上に移調して、右手パートのピッチクラスの散布図を表示。
>>> s.transpose(2, inPlace=True) >>> s[1].plot(format='scatterweighted', values='pitchclass')
メモ:LilyPondのファイルフォーマットは複雑すぎるという話
残念ながら、music21はLilyPondの記法で書かれたlyファイルを読み込めない*5。プロジェクト公式の課題トラッカーで表明されている通り、この制約は今のところというわけではなく、今後もずっと続く模様。
理由も上のリンク先に書いてあるが、lyファイルにはSchemeのコードまで書けたりして、他のプログラムが楽譜として解析するには複雑すぎる。仮に一度解析プログラムを作り上げたとしてもLilyPondは活発なプロジェクトだし、構文もよく変更されるので追随するのが大変だろう。
おそらく同じ理由で、lyファイルをMusicXMLとかABCに変換するプログラムも(探した限りでは)ない。lyファイルを他のファイルフォーマットに変換する機能をLilyPond自体に追加するのが他の手段との比較上は一番楽な気がするけど、LilyPondプロジェクトにそういう計画は(探した限りでは)ない。
ちなみに、music21はMIDIファイルなら読み込める。そこで、LilyPondでlyファイルからMIDIファイルを出力して、この出力をmusic21に読み込ませればいいのではないかというと、MIDI出力の時点で楽譜の一部の要素が欠落してしまう。MIDIは演奏データをデジタル転送するための規格で、記譜のための仕様は十分ではないので、MIDI出力でサポートされない要素があるのが理由。
諦めた。