Music21 3章 ピッチ、デュレーション、音符

Noteオブジェクトの実践編となります。
主なテーマはピッチとデュレーションになります。

Pitchオブジェクト

Noteオブジェクトがnoteモジュールの中にあるのと同じようにpitchオブジェクトはPitchモジュールの中にあります。
pitchオブジェクトのインスタンスを作ってみましょう。音名と臨時記号はNoteオブジェクトと同じように指定します。

from music21 import *
p1 = pitch.Pitch('b-4')

>>> p1.octave
4

>>> p1.pitchClass
10
>>> p1.name
'B-'
>>> p1.accidental.alter
-1.0

もう2つ紹介します。一つ目は音名とオクターブを指します。 2つめはピッチの値です。実はこれはMIDIの用語でピッチを表現するのに用いられます。 0~127の値で表され、数値が1増えると音が半音上がります。ピアノの鍵盤の中央にあるC4の音が60となり、C4の#またはD4の♭が61となります。

>>> p1.nameWithOctave
'B-4'
>>> p1.midi
70

もちろんあとで変更可能です。

>>> p1.name = 'd#'
>>> p1.octave = 3
>>> p1.nameWithOctave
'D#3'

transposeメソッドも使用可能です。

>>> p2 = p1.transpose('M7')
>>> p2
<music21.pitch.Pitch C##4>

PitchオブジェクトとNoteオブジェクトの違い

ここまででわかると思いますがPitchオブジェクトとNoteオブジェクトはほとんどメソッドなど使えるものが同じです。

ドキュメントを読んでいる限りだとnote.Noteオブジェクトの中にPitchオブジェクトがあるので機能的には一緒です。note.Noteオブジェクトでできることはnote.Note.pitchオブジェクトでもできる。

# note.Noteオブジェクトでできることはnote.Note.pitchオブジェクトでもできます。
>>> csharp = note.Note('C#4')
>>> csharp.name
'C#'
>>> csharp.pitch.name
'C#'
>>>
>>> csharp.octave
4
>>> csharp.pitch.octave
4
>>

pitchオブジェクトの方が機能が多いようです。スペイン語での表示が可能です。

# Pictchオブジェクトではスペイン語が可能
>>> csharp.pitch.spanish
'do sostenido'

# Noteオブジェクトではエラーが出る
>>> csharp.spanish
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Note' object has no attribute 'spanish'

その他の機能について 例えば「シャープ」を音楽記号できちんと表示することができます。ブログでは分かりませんが。。

>>> print(csharp.pitch.unicodeName)
C♯

異名同音を取得することもできます。

>>> print( csharp.pitch.getEnharmonic() )
D-4
>>> print( csharp.pitch.getLowerEnharmonic() )
B##3

C#異名同音だから上記のようになりますね。

Pitchオブジェクトの方が多機能に見えますが、Noteオブジェクトはどうして存在するのか?
それはDurationが存在するからです。Durationとは音の長さのことです。これがなくては楽譜状に表示することはできません。

Durationオブジェクト

とういうことでDurationオブジェクトをみていきましょう

構造としてはほぼ全てのオブジェクトがDurationを持ち、Durationオブジェクトはほぼ全ての長さを設定することが可能なようです。

Durationオブジェクトはdurationモジュールの中にあります。早速インスタンスを作ってみましょう。

halfDuration = duration.Duration('half')

引数「half」を与えているのはおそらくコンストラクタですかね。
ところでこのhalfって一体なんなのでしょうか?日本語では2分の1。。。
要するに2分音符です!!
Durationの指定は全て英語で行います。以下が対応表です。

指定形式 長さ
whole 全音
half 2分音符
quarter 4分音符
eighth 8分音符
16th 16分音符
32th 32分音符
64th 64分音符
数値 n×4分音符(1.5なら付点4分音符)
以下はその他のmusic21がサポートしているDuration
breve ブレーヴェ(ブレヴィス): 全音符×2
longa ロンガ: 全音符×4
maxima 全音符×8
128th, 256th, ....1024th n分の1音符
dottedQuarter = duration.Duration(1.5)

Durationオブジェクトの属性をみてみましょう。

  • .quarterLength: 4分音符を1として長さを表示します
>>> dottedQuarter.quarterLength
1.5
  • .type: Durationのタイプを出力します。
>>> dottedQuarter.type
'quarter'
>>> halfDuration.type
'half'

# 指定の仕方によってはcomplexとなります。
>>> test= duration.Duration(2.5)
>>> test.type
'complex'

ただしこれで全てのDurationを説明できるわけではないらしい。

  • .dot: 付点の数を返します。
>>> halfDuration.dots
0
>>> dottedQuarter.dots
1

付点の数などはあとで設定することができます。

>>> dottedQuarter.dots = 1
>>> dottedQuarter.quarterLength
1.5

>>> dottedQuarter.dots = 2
>>> dottedQuarter.quarterLength
1.75

>>> dottedQuarter.dots = 3
>>> dottedQuarter.quarterLength
1.875

>>> dottedQuarter.dots = 4
>>> dottedQuarter.quarterLength
1.9375

quarterLengthの長さも変更可能です。

>>> dottedQuarter.quarterLength = 0.25
>>> dottedQuarter.type
'16th'

>>> dottedQuarter.dots
0

なお、quaterLengthはしばしばqLと呼ばれるらしい。 ちなみに0.8や1/3と指定するkとおで4分音符の5/4や8分音符の3連符も扱うことができます。 ※Python2で分数を使うときは気をつけましょう。Pythonでは整数の除算は整数で返されてしまいます。割られる側の数を少数にしておくのが最も簡単な回避です。

再びNoteオブジェクト

さて、Noteオブジェクトがpitchだけでなくdurationも持つことができると知ったところで再びNoteオブジェクトをみてみましょう。

少し整理するとNoteオブジェクトはデフォルトでは
 ・Pitch: C4
 ・Duration: 1.0(4分音符×1)
となります。

>>> n1 = note.Note()
>>> n1.pitch
<music21.pitch.Pitch C4>
>>>
>>> n1.duration
<music21.duration.Duration 1.0>

もちろん変更可能で、他の属性も設定に応じて更新されます。

# 属性の変更
>>> n1.pitch.nameWithOctave = 'E-5'
>>> n1.duration.quarterLength = 3.0

# 他の属性が変更されていることの確認
>>> n1.duration.type
'half'
>>> n1.duration.dots
1
>>> n1.pitch.name
'E-'
>>> n1.pitch.accidental
<accidental flat>
>>> n1.octave
5

Pitchオブジェクトの一部の属性はNoteオブジェクトから呼び出すことができますが、Durationについても同様にNoteオブジェクトから呼び出すことができます。

>>> n1.name
'E-'
>>> n1.quarterLength
3.0

# 3に設定されたqLを1に戻すこともできます。
>>> n1.quarterLength = 1.0

ざっくりこの話をまとめると大まかな作業は全部Noteオブジェクトで行って、細いことはそれぞれのオブジェクトで行うということですかね。

ただ、Noteオブジェクトだけでできる操作があります。(pitchやdurationではできない。)
その一つが歌詞(lyric)をつけることです。

やり方は簡単でLyric属性を設定するだけです。 ドキュメントによるとLyric属性は元々GeneralNoteクラスの属性なのですが、NoteクラスがGeneralNoteクラスを継承しているため使用可能なそうです。

otherNote = note.Note("F6")
otherNote.lyric = "I'm the Queen of the Night!"

addLyric()メソッドを使えばもっと複雑なことができるらしい...要するに変数を歌詞に代入でき、かつprint関数みたいな使い方ができるということかな?

>>> n1.addLyric(n1.nameWithOctave)
>>> n1.addLyric(n1.pitch.pitchClassString)
>>>
>>> n1.addLyric('QL: %s' % n1.quarterLength)
>>> n1.show()

ちなみにあとでqLを更新しても歌詞の方には反映されないらしい。

n1.quarterLength = 6.25
n1.show()