This song is a transcription of Terry Riley's seminal minimalist composition.
The driver javascript constructs the path to the song file then loads it by constructing a Songbook instance.
let songFile = "in-c.hz";
let thisDir = path.dirname(this.GetFilePath());
let presetDir = thisDir;
let songPath = path.join(thisDir, songFile);
let str = await FetchWSFile(songPath, false/*not binary*/);
let songbook = new Songbook(str, songFile);
for await (const val of songbook.PerformSong(this, presetDir, 0))
yield;
This song comprises six Voices and six Tracks. We rely on preset.js
to
initialize each Voice as requested by its AnodeInit
request.
Each voice performs a random number of repetitions of each of 54 predetermined patterns in sequence (v0-v53). Here are two of them:
v0 = [z]!<?2,16>
v1 = [[c e@7]!3]@3!<?5,10>
We can see that the first pattern, v0
, is a random number of rests (z
) between
2 and 16. This provides each voice with a random initial delay. Similarly the next
pattern, v1
, repeats the a stretched (@
) group of 3 repeats (!
) of c and e
betweeen 5 and 10 times.
Here's an example track:
Track(Id:"Track1", Mute:0)
{
VoiceRef = "v1"
// $[x} is a measure reference
// $[v0] (just an offset, so we're first)
$[v1] $[v2] $[v3] $[v4]
$[v5] $[v6] $[v7] $[v8] $[v9]
$[v10] $[v11] $[v12] $[v13] $[v14]
$[v15] $[v16] $[v17] $[v18] $[v19]
$[v20] $[v21] $[v22] $[v23] $[v24]
$[v25] $[v26] $[v27] $[v28] $[v29]
$[v30] $[v31] $[v32] $[v33] $[v34]
$[v35] $[v36] $[v37] $[v38] $[v39]
$[v40] $[v41] $[v42] $[v43] $[v44]
$[v45] $[v46] $[v47] $[v48] $[v49]
$[v50] $[v51] $[v52] $[v53]
}
It simply enumerates all the patterns in order (though Track1 doesn't perform v0). Each track shares this same structure but since randomness is introduced each track (and each overall performance) is unique.
More details on the musical machinery behind this piece can be found in its comments.
To see a mixing console for each voice in the song, the HzPlugins Tab
shows this:
To see a piano-roll visualization
of the song, select Toggle Previewer
revealing something like this: