この章では、複数のパート(楽器またはボーカルパート)からなる曲全体を Pytakt MML で記述する方法について説明します。
4章 で説明したように角括弧と波括弧を使って複数パートの曲を記述することが可能ですが、基準オクターブ、MIDIチャネルなどの設定値がパートごとに異なる場合、区切った時間区間の冒頭で各パートごとにそれらを再設定する必要が出てきます。その手間を省くため、Pytakt MML にはコンテキスト(コンテキスト属性をひとまとめにしたもの)を名前で定義し、それを参照してまとめて設定値を切り替える機能があります。
曲を記述するには、まずどのようにパート分けするかを決める必要があります。分け方は任意ですが、目安として、スコア譜の五線一段が1つのパートと考えると良いでしょう。
パート分けが決まったら、パートごとに $newcontext によってコンテキストを作成し、パートの名前(英数字または下線の列で、先頭が数字ではないもの)を考えて、下の例のようにして名前とコンテキストを結びつけます。この例では、3章で紹介したシューベルトのセレナーデに伴奏を追加するため、歌とピアノ(右手と左手)の3つのパートを定義しています (ピアノは1つのパートにまとめることもできますが、ここでは2パートに分けています)。
$vocal = $newcontext(tk=1, ch=1, L=L8, v=80)
$piano_rh = $newcontext(tk=2, ch=2, L=L8, v=60)
$piano_lh = $newcontext(tk=3, ch=2, L=L8, v=60, o=3)
tk と ch については後述します。L= は基準音価、v= はベロシティ、o= は基準オクターブの設定です。上のように定義を行った後は、波括弧の前に $パート名: を置くだけで、そのパートに関する上のすべての設定を行ったことに相当します。これを利用すれば、下のように曲を記述してゆくことができます。
[
$vocal: {{A Bb A}*/3 ^D~~ A {G A G}*/3 ^D~ G r}
$piano_rh: {r [_A D] [D F] [_A D] [D F] [_A D]
r [_G D] [D E] [_G D] [D E] [_G D]}
$piano_lh: {[_D D]~~~rr _[_Bb Bb]~~~rr}
]
[
$vocal: {A~~ G {G F E}*/3 F~~~rr}
$piano_rh: {r [_G _A C+] [_A C# E] [_G _A C#] [_A C# E] [_G _A C#]
r [_F _A D] [_A D F] [_F _A D] [_A D F] [_F _A D]}
$piano_lh: {_[_A A]~~~rr [_D D]~~~rr}
]
[
$vocal: {rrrrrr rrrrrr}
$piano_rh: {^{[C# A]~~ [E G] {[E G] [D F] [C# E]}*/3 [D F]~~~~~}}
$piano_lh: {_[_A A] [A ^E] ^[E G] [A ^E] ^[E G] [A ^E]
[_D D] [A ^D] ^[D F] [A ^D] ^[D F] [A ^D]}
]
上の $newcontext における tk= の設定はトラック番号を示しています。トラックを別にすることによって、個別に再生の有無を制御したり、ピアノロール上で異なる色で表示したり、五線譜上で別の段に表示したり、複数シンセサイザがある場合にどのシンセサイザで演奏するかを制御たりすることが可能になります。トラック番号は 0 から始まりますが、0番トラック(コンダクター・トラック)はテンポ設定など全パートに関係する情報専用のため、各パートには1番から割り付けていくことになります。特に理由がない限り、各パートに1つずつ順番に割り当てます。
ch= の設定はMIDIチャネル番号を表しています。MIDIチャネルは1から16までで、異なる音色を使ったり、あるいは異なるビブラートやペダル等の制御を行うには、チャネルを別にしないといけません。したがって、使用する音色が違うパートには別のチャネルを割り当て、逆に、同じ音色を使うパートは、個別にビブラート、ピッチベンドの制御するなど特段の理由がない限り、同じチャネルを割り当てます。ピアノパートは、ペダル制御の都合上、1台ごとに1つのチャネルを割り当てます。リズム楽器(ドラムセット)のパートは、多くのシンセサイザで10番のチャネルを使用していることから、10番のチャネルに割り当てます。
複数パートの曲について、開始部分の記述例を下に示します。$trackname によるトラック名の設定は、ピアノロールでのトラック名表示や、MIDIファイルにトラック名の情報を入れるために役立ちます。
;
; F. Schubert, Staendchen
;
$title("Staendchen (Serenade)")
$title("Composer: Franz Schubert")
; Defining contexts
$vocal = $newcontext(tk=1, ch=1, L=L8, v=80)
$piano_rh = $newcontext(tk=2, ch=2, L=L8, v=60)
$piano_lh = $newcontext(tk=3, ch=2, L=L8, v=60, o=3)
; Key signature, time signature & tempo
$keysig("D minor")
$timesig(3, 4)
$tempo(66)
; Setting track names and initializing synthesizers
[
$vocal: { $trackname("Vocal") $prog(gm.SynthVoice) $vol(100) }
$piano_rh: { $trackname("Piano Right Hand") $prog(gm.Piano1) $vol(100) }
$piano_lh: { $trackname("Piano Left Hand") }
]
; Bars 1-4
[
$piano_rh: {r [_A D] [D F] [_A D] [D F] [_A D]
r [_Bb D] [D F] [_Bb D] [D F] [_Bb D]
r [_Bb D] [D E] [_Bb D] [D E] [_Bb D]
r [_A C#] [C# E] [_A C#] [C# E] [_A C#]}
$piano_lh: {[_D D]~~~rr _[_Bb Bb]~~~rr _[_G G]~~~rr _[_A A]~~~rr}
]
楽器によっては、慣例として実際に発音される音の高さ(実音)とは異なる音の高さ(記譜音)を楽譜に記載するものがあります(そのような楽器は移調楽器と呼ばれます)。このような楽器に対して記譜音でMMLを記述するためには、コンテキストを作成する際に effectors=[Transpose(実音と記譜音の差)] という指定を追加します。
$clarinet_in_Bb = $newcontext(tk=1, ch=1, effectors=[Transpose(Bb3-C4)])
$clarinet_in_A = $newcontext(tk=1, ch=1, effectors=[Transpose(A3-C4)])
$horn_in_F = $newcontext(tk=2, ch=2, effectors=[Transpose(F3-C4)])
$contrabass = $newcontext(tk=3, ch=3, effectors=[Transpose(-12)])
$horn_in_F: { C D E } ; 実際は _F _G _A と演奏される
Transpose はエフェクタと呼ばれるものの1つで、これについての詳細は第12章で解説します。