Multi-Part Music

This chapter explains how to describe an entire song consisting of multiple parts (instrumental or vocal parts) using Pytakt MML.

Defining contexts

As explained in Chapter 4, you can use square brackets and curly braces to describe multi-part music. However, when settings such as the base octave or MIDI channel differ for each part, you would need to re-set these values for each part at the beginning of the separated time section. To simplify this task, Pytakt MML provides a mechanism to define contexts (which are collections of context attributes) with names, and then reference them to switch settings all at once.

To describe a musical piece, you first need to decide how to divide it into parts. The division is arbitrary, but as a guideline, think of one staff in the score as one part.

Once the part divisions are finalized, consider a name (a string of alphanumeric characters or underscores, not starting with a number) for each part. Then, create a context using $newcontext and associate the name with the context as shown in the example below. In this example, to add accompaniment to Schubert’s serenade introduced in Chapter 3, we define three parts: a vocal part and two piano parts (right hand and left hand). (The piano could be combined into a single part, but here we split it into two parts).

$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 and ch will be discussed later. L= sets the base duration, v= sets the velocity, and o= sets the base octave. After the above definitions, you only need to place $partname: before the curly brace to apply all the settings above to that part. Using this, you can write songs as shown below.

[
  $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]}
]

Assigning tracks and MIDI channels

The tk= in the above $newcontext indicates the setting of the track number. By assigning a separate track for each part, you can individually control whether it plays or not, display it in a different color on the piano roll, show it on a separate staff in the score, and separately assign a synthesizer when multiple synthesizers are present. Track numbers start from 0, but Track 0 (the conductor track) is reserved for information affecting all parts, such as tempo settings. Therefore, each part is assigned a track number starting from 1. Unless there is a specific reason, assign track numbers sequentially, one for each part.

ch= indicates the setting for the MIDI channel number. MIDI channels range from 1 to 16. To use different timbres or to control effects such as vibrato or pedal differently, you must assign separate channels. Therefore, assign distinct channels to parts using different timbres. Conversely, parts sharing the same timbre should be assigned the same channel, unless there is a specific reason, such as individually controlling vibrato or pitch bend. For piano parts, assign one channel per instrument due to pedal control requirements. For rhythm instrument (drum set) parts, assign Channel 10 since most synthesizers use this channel for such sounds.

Example of the beginning section

Below is an example of how to describe the beginning section for multiple-part music. Setting the track name using $trackname is useful for displaying track names in the piano roll and for including track name information in MIDI files.

;
; 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}
]

Handling transposing instruments

For certain instruments, it is a common practice to notate a pitch (the written pitch) on the score that differs from the actual pitch sounded (the actual pitch). Such instruments are called transposing instruments. To describe MML using the written pitch for these instruments, add the specification effectors=[Transpose(difference between actual pitch and written pitch)] when creating the context.

$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 }  ; Actually played as "_F _G _A"

Transpose is a type of effector, and details about it will be explained in Chapter 12.



Last update: Jan 30 2026 16:26 JST     Copyright (C) 2026 Satoshi Nishimura Top Page