In this
example we use three
instances of the SoundCipher class to generate polyphonic music with
three parts. Each instance can have its own instrument setting and
plays independently. They are all synchronised by the draw() thread
which is operating at a low frame rate. In other tutorials,
particularly
those in the Callback section, there are examples of how to use
SoundCipher's own scheduling capabilities that allow more musical use
of beats and tempi in beats per minute.
Three significant algorithmic
composition techniques are used here (and elsewhere in the tutorials) they are:
1) probability through constrained randomness; 2) imposing regularity
through modulus over an ever-accumulating counter - in this case the
frame counter - and; 3) pitch organisation using a pitch set and
transposition.
The import statement makes the SoundChiper library available for
this program. The asterix indicates that all classes in the library
should be available.
Three instances of the SoundCipher class are instantiated; they are labeled sc, sc2 and sc3.
A
pitch set in created as an array of floats. These notes are a C
pentatonic over a couple of octaves. Notice that the root and dominant
pitches are repeated several times in the list, this is to bias their
likelihood of selection when we randomly choose from the array.
Other
variables set at this point include the length of the pitchSet array
(because we will use that a few times), the key or root note offset
which is used to transpose the pitches when required, and the note
density setting which is changed as the music proceeds to create more
spare or more intense passages.
The setup() method sets the
frame rate for the draw thread to 8 frames per second, and sets the
instrument for sc3 to number 49. The JavaSound synthesizer on which the
music is played has sounds that correspond to the General MIDI
specification in which sound 49 is "String Ensemble". A complete list
of the GM Instruments is available at Wikipedia's General MIDI entry. The first two parts use the default instrument - acoustic piano.
The
draw() function does all the real work in the program. It is called 8
times a second and each time may or may not play a note on each of the
three SoundCipher instances. The first part is evaluated if a random
number is less than the denisty. If so a note is played, a fill colour
selected, and a rectangle drawn. Parameter values for these are subject
to degrees of randomness that provide variety and change in the output.
The
second part executes every 32 frames. When it does it changes the
keyRoot value so that the music is transposed, the density value is
recomputed, and a long low pedal tone is played.
The third part
is triggered every 16 frames and it selects pitches for a chord and
then plays that chord with a somewhat random dynamic. This was the part
that used the String Ensemble sound. Notice that the chord pitches are
transposed down an octave (-12) from the pitch set, which moves them
into a lower register than the piano melody and somewhat above the
pedal tone. |