幻魔ナイトブログ

主に絵、音楽、プログラミングなどについて書きます。

Music21ガイドを解き明かす(2章)

f:id:MahiroN:20200822135636p:plain 元となっているドキュメントは以下。
User’s Guide, Chapter 2: Notes — music21 Documentation

音符についての章のようです。
Noteという単語についてWeblioで調べて見たところ音符という意味があるらしいです。

概要

まず、機能の格納場所ついて ノートモジュール内のノートオブジェクトに格納されているらしい。 ここでコーディングルールの説明がされている

  • モジュール:小文字から始まる。
  • オブジェクト:大文字から始まる。

要するにnoteモジュールの中にNoteオブジェクトがあるということだ。 noteモジュールの中にはNote以外にも色々とクラスがあるが最も重要なものはnote.Restだとのこと。

以下のようにmusic21のモジュールをインポートすればオブジェクトにアクセス可能となります。

>>> from music21 import * 

あとはコマンドラインで「note」と入力すればNoteオブジェクトにアクセスすることができます。
ちなみにnoteと打つとモジュールが格納されているパスが表示されます。インストールディレクトリを忘れてしまったときに確認できる小技として役立ちます!!

ちなみにnoteモジュールにNoteオブジェクトやRestオブジェクト以外に何が含まれているか知りたい場合は以下のコマンドが使えます。

>>> dir(note)

Python名前空間の汚染ついては正直よくわからなった。 ただ、もしその問題で上記の「from music21 import *」を使用したくない場合は以下のように書けばいいです。

import music21

その場合、Noteオブジェクトにアクセスする方法は以下のようになります。

music21.note

Noteオブジェクト

基本

ここから音符の作成の話です。前提として>>> from music21 import *でモジュールをインポートしたとします。 まずはF5の音を作ってみましょう。

F5の音って? 一般的に日本人であれば音符の名前は「ドレミファソラシ」ですが、海外では「CDEFGAB」とアルファベットで表現し、「C」が「ド」に対応します。でもこれだけだとどの高さの「ド」なのかわかりませんよね?. そこで番号をつけます。
結局のところ「音名+高さ番号」で表現しているにすぎません。簡単ですね♪. ピアノの鍵盤で表現すると以下のような感じになっています。

ではF5のNoteオブジェクトのインスタンスを作ってみましょう。以下のコマンドで作ります。

f = note.Note("F5")

これでF5の音符オブジェクトが作成されました(正確にはインスタンスだと思うが)。色々メソッドを使ってみましょう!! - まうzメソッドを使わず「f」と打ってみましょう。オブジェクトが返されます。

  • 音名を各確認する。英語での音名の「F」が返ってきます。
>>> f.name
'F'
  • オクターブを確かめる。オクターブの番号が返ってきます。
>>> f.octave
5
  • ピッチを確かめる。pitchメソッドを使いますが今までのような文字列ではなくF5のおとのpitchオブジェクトが返されます。
>>> f.pitch
<music21.pitch.Pitch F5>
  • 返されたpitchオブジェクトからfurequencyメソッドを呼び出すことで周波数を知ることができます。
>>> f.pitch.frequency
698.456462866008
  • pitchClassStringというメソッドでピッチクラスを参照することもできます。
>>> f.pitch.pitchClassString
'5'

これでF5の音が698Hzでピッチクラスが5の音であることがわかりましたね。
周波数の端数はコンピューターによって違うので気にしなくても良いです。

※ピッチクラスとは...

ちなみに数字にクォートがついているかどうかは記号として返しているか数字として返しているかの違いらしい。

ピッチクラスは文字列ではなく、数字でも出力できます。異なるメソッドを使うます。

>>> f.pitch.pitchClass
5

臨時記号

ところで1つきになることがありませんか?
フラット(♭)やシャープ(#)はどういう風に表現すれば良いのでしょうか。
シャープは#、フラットは-で表現します。

>>> bflat = note.Note("B-2")

※上記の数字はオクターブ番号です。

こういった臨時記号はpitchモジュールのaccidentalメソッドで取得することができます。

>>> bflat.pitch.accidental
<accidental flat>

上を見たらわかりますがaccidental属性?は臨時記号を返すのではなく臨時記号のオブジェクトを返します。 それがAccidentalオブジェクトです なのでaccidentalメソッドで取得したオブジェクトを格納する変数を作成しておけば他の属性も参照することができます。

>>> acc = bflat.pitch.accidental

Accidentalオブジェクトには.alter.displayLocationの2種類の属性があります。よく使うのは.alterです。これは臨時記号によってい何半音音が動くかを取得します。
フラットのように音が下に動く時は負の数が返ってきます。

>>> acc.alter
-1.0

# ちなみにわざわざ変数に格納しなくても取得可能
>>> bflat.pitch.accidental.alter
-1.0

displayLocationは記号の表示位置です。デフォルトではnormalですが変更することが可能です。

>>> acc.displayLocation
'normal'
>>> acc.displayLocation = 'above'
>>> acc.displayLocation
'above'

ちなみに参照(Cで言う所のポインタ)が置き換わるので、上記を行った後に変数格納せずにdisplayLocationを呼び出した場合も置き換わっています。

>>> bflat.pitch.accidental.displayLocation
'above'

wasWrittenByStockhausen 属性はデフォルトではアクセスしようとするとエラーになるが値の設定をして使用することは可能らしい。。(なんのこっちゃ)

bflat.wasWrittenByStockhausen = True
f.wasWrittenByStockhausen = False

出力してみよう

属性の情報を見ていてもちょっと飽き飽きしてきますよね。
以下のコマンドでnoteオブジェクトを楽譜として表示することができます。ただし、MuseScore、Finale、 Sibelius、 Finale NotepadなどのMusicXMLを読み込むことのできるソフトをインストールしておく必要があります。
この中だと無料で使用できるのはMuseScoreです。

無料で使える楽譜作成ソフト | MuseScore

楽譜に出力するにはshowメソッドを使用します。4分音符で表示されます。F5なのでト音記号の楽譜状に記されます。

f.show()

楽譜に表示する場合は引数の指定は特に必要ありませんが、音を鳴らしたい場合は'midi'を引数に入れます。

f.show('midi')

ちなみに上記のコマンド、時々動かないことがある私のMac環境では以下のようなエラーが出た。

>>> f.show('midi')
FSPathMakeRef(/Applications/Utilities/QuickTime Player 7.app) failed with error -43.

これは設定されたパスにmidiを再生するためのアプリケーションがないからです。
そんな時は以下のように設定を変更します。(ご自分の環境に合わせてね。)

>>> music21.environment.set('midiPath', '/System/Applications/QuickTime Player.app/')

ちなみに試したらわかると思いますが、QuickTimeで開くことはできますがMidiに対応していない云々のエラーが出て結局再生できません。これはSnow Leopard以降のMacではQuickTimeMidiに対応しなくなったためです。
回避するためには古いQuickTime7を手に入れる必要があるようです。(最初再生できなくてびびったが本家サイトに書いてありました。)

上でしれっと書きましたがshowはオブジェクトやモジュールではなくメソッドです。プログラムをかじったことがある人ならわかると思いますが、メソッドなのでカッコは必要です。

メソッドの結果をメソッドを変数に代入するのではなくオブジェクト自身に対して変更を加えたいならinPlaceオプションをTrueにしたら良いです。tranceposeメソッドで試してみましょう。
今回はbflatをメジャーサードに転調してみます。メジャーサードだからM3です。

Noteオブジェクトのtransposeメソッドについてはこちらを参照してください。

# 通常
>>> d = bflat.transpose("M3")
>>> d
<music21.note.Note D>

#  オブジェクト自身に変更を加える例
>>> bflat.transpose("P4", inPlace=True)
>>> bflat
<music21.note.Note E->

bflatという変数名なのに実際はeflatというのはちょっと混乱しますね。。

残りはよくわからないのでまた今度かきます。

Restオブジェクト

noteモジュールの中で大切なのはNoteオブジェクトとRestオブジェクトであると前述しました。
Noteオブジェクトは音符のことでした。ではRestオブジェクトとはなんのことでしょう?
考えるのに疲れたならば少し休憩をとってもいいですよ。Let's take a rest!!...
そうですRestとは休憩の意味があります。つまり休符のことです。

restのインスタンスは下記のように記述します。

r = note.Rest()

カッコをつけるのを忘れないでください。Noteオブジェクトの時もそうでしたね。

出力してみましょう。

r.show()

当たり前ですが、休符なのでpitchを出力しようとしてもエラーになります。

>>> r.pitch
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Rest' object has no attribute 'pitch'

注意事項

最後に注意事項です。以下のようにnoteという変数を使用してnoteオブジェクトの格納は行わないでください。「note」はmusic21の予約後です。

note = note.Note("C#3")

お問合わせはこちら