If you know how to call a function then you can start composing
interesting algorithmic music by using two functions -- stroke and spray --
to generate sound for you.
Think about these two functions as different ways to "paint"
notes: stroke generates musical events in sequential
order while spray generates musical events using
randomness.
To work with these functions you need to download the file "paint.scm" and load that file into Grace:
You can load "paint.scm" into Grace using the menu item or using SAL's load command:
SAL's load command. Replace "/path/to/" with the appropriate path on your machine.
load("/path/to/paint.scm")
The following is an explanation of each function's parameters.
stroke( ... )Generates MIDI events in sequential order. Most parameters allow lists of values to be specified, in which case elements from the list are played in left-to-right order. Lists containing fewer elements than the total number of notes generated will automatically loop around from the last element back to the first until the algorithm stops.
stroke supports the following named parameters:
len: numberend: numberlen: is not specified. If values for both len: and end: are
specified then the process stops as soon as the first condition holds
true.rhy: {number | list}dur: {number | list}key: {number | list}amp: {number | list}chan: {number | list}spray( ... )Uses discrete, uniform random selection to generate MIDI events. Most parameters allow lists of values to be specified, in which case elements are randomly chosen from the list each time an event is generated.
spray supports the following named parameters:
len: numberend: numberstroke.
rhy: {number | list}stroke.dur: {number | list}stroke.key: {number |
list}band: {number
|list}key: value to
randomly select the next key number. If a list of
intervals is specified then a new interval is randomly selected from
the list each time a MIDI event is output and added to the current key
number to determine the actual key number that is played. The list
can contain sublists of intervals; in this case each sublist is
treated as a chord, i.e. the key numbers in the sublist are performed
simultaneously.amp: {number | list}stroke.chan: {number | list}stroke.sproutThe sprout
command starts musical algorithms running. The first
argument to the command is the algorithm, or list of algorithms,
you want to execute. The second (optional) argument is the start
times or list of start times that the algorithms should start
running at, where 0 means now. If you provide a list of
algorithms and a list of start times then each algorithm will be
paired to its corresponding start time in left-to-right order.
The (optional) third argument to sprout is a scorefile
to write. If a scorefile is specified then the system will run
the algorithms as fast as possible and algorithms will generate
all their musical output to that file. For example, to achieve
the most precise timing you can sprout the examples to Midifiles
(instead of out the Midi Port) and then use a Midifile player to
play the file. See the comments below on how to do this.
Download source:
reich.sal
load("paint.scm") variable pphase = {64 66 71 73 74 66 64 73 71 66 74 73} sprout(list(stroke(len: 147, key: pphase, rhy: 0.16666667), stroke(len: 150, key: pphase, rhy: 0.16333333))) ;; to write a Midifile add two additional arguments to the ;; sprout command: a score startime (keep it 0 for now) and ;; the name (string) of the Midifile to write. sprout(list(stroke(len: 147, key: pphase, rhy: 0.16666667), stroke(len: 150, key: pphase, rhy: 0.16333333)) , 0, "test.mid")
Download source:
messiaen.sal
load("paint.scm") variable liturgie-talea = {1 1 1 .5 .75 .5 .5 .5 .5 .75 .75 .75 .25 .5 .75 1 2 } variable liturgie-color = {{f3 g bf c4 ef b e5} {f3 g bf c4 e a d5} {f3 af bf df4 ef a d5} {f3 af bf df4 ef g c5} {f3 g bf d4 fs b c5} {f3 g bf d4 e a c5} {f3 a c4 d g cs5 fs} {f3 g c4 d g b e5} {f3 bf df4 gf e5} {f3 b d4 g e5 g} {f3 c4 ef af g5} {f3 cs4 e a g5 b} {af3 ef4 gf bf ef5 gf cf6} {af3 ef4 f bf df5 f5 bf5} {gf3 df4 af ef af cf6 ef} {gf3 df4 bf d5 f bf d6} {a3 c4 d fs bf df5 gf bf df6} {bf3 cs e gs c5 d gs c6} {c4 d f a4 cs5 e a} {cs4 e fs bf d5 f} {fs4 g bf d5 fs a} {fs4 a b ds5 es gs} {f4 bf d5 e g} {e4 af cs5 d} {d4 g b cs5 e} {cs4 f bf b f5} {b3 e4 af bf} {af3 cs4 f g} {gf3 cf4 ef f}} sprout( stroke( len: length(liturgie-talea) * 8 + 14, rhy: in-tempo(liturgie-talea, 80), key: key(liturgie-color), chan: {0 1 2 3})) ;; Midifile version sprout( stroke( len: length(liturgie-talea) * 8 + 14, rhy: in-tempo(liturgie-talea, 80), key: key(liturgie-color), chan: {0 1 2 3}) , 0, "test.mid")
Download source:
mike.sal
load("paint.scm") variable blues = {0 3 5 6 7 10 12} sprout(list(spray(len: 200, dur: .2, rhy: .2, band: {0 3 5}, key: 30, amp: 0.35, end: 36), spray(len: 160, dur: .2, rhy: {-.2 -.4 .2 .2}, band: {3 7 6}, key: pick({30 42}), amp: 0.5, end: 25), spray(len: 180, dur: .2, rhy: {-.2 .2 .2}, band: blues, key: pick({42 54}), chan: 2, end: 20), spray(len: 100, dur: .2, rhy: {-.6 .4 .4}, band: blues, key: 66, amp: 0.4, end: 15), spray(len: 200, dur: .2, rhy: .2, band: {0 3 5}, key: 30, amp: 0.5, end: 10), spray(len: 160, dur: .2, rhy: {-.2 -.4 .2 .2}, band: {3 7 6}, key: pick({30 42}), amp: 0.8, end: 10), spray(len: 180, dur: .2, rhy: {-.2 .2 .2}, band: blues, key: pick({42 54}), chan: 2, end: 10), spray(len: 100, dur: .2, rhy: {-.6 .4 .4}, band: blues, key: 66, amp: 0.6, end: 10), spray(len: 100, dur: .2, rhy: .2, band: blues, key: 66, amp: 0.4, end: 6) ), {0 5 10 15 37 37 37 37 47} )