09.12.2012 Views

The Kyma Language for Sound Design, Version 4.5

The Kyma Language for Sound Design, Version 4.5

The Kyma Language for Sound Design, Version 4.5

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>The</strong> training sequence is just an Array of Arrays, each subarray containing two numbers — nothing specifically<br />

musical yet:<br />

chain :=<br />

MarkovChain<br />

trainingSequence: #(<br />

#(0 4) #(3 2) #(-5 2) #(2 4) #(3 2) #(-5 2) #(2 4)<br />

#(3 2) #(-5 4) #(2 2) #(3 2) #(-5 4) #(2 2) #(-5 2)<br />

#(5 2) #(-7 4) #(1 2) #(-2 2) #(1 4) #(0 0.5) #(12 4)<br />

)<br />

chainLength: 2.<br />

Next, there is a loop in which the index, i, takes on the values from 1 to 10. Each time through the loop a<br />

new sequence is generated, using a different seed each time, and saved in the variable called seq:<br />

1 to: 10 do: [ :i |<br />

seq := chain newSequenceOfLength: 100 seed: i * 26.<br />

In Smalltalk, you can also create a loop by sending the do: message to an Array. <strong>The</strong> following is a loop<br />

in which the variable offDur takes on each of the values stored in the Array called seq. Each value in<br />

seq is a subarray containing two numbers. Take a look through this code to see if every step makes sense<br />

to you. (If not, don’t worry, it is all explained in more verbose style in the following paragraph!)<br />

seq do: [ :offDur |<br />

dur := (offDur at: 2) / i.<br />

pitchOffset := offDur at: 1.<br />

self<br />

keyDownAt: t beats<br />

duration: dur beats<br />

frequency: 1 g + pitchOffset nn + i nn<br />

velocity: i/10.<br />

t := t + dur].<br />

Each time through the loop, the second element of offDur is divided by i (the index of the outer loop)<br />

and stored in dur. <strong>The</strong> first element of offDur is stored in the variable pitchOffset. <strong>The</strong>n a MIDI<br />

event is created that starts on beat t, lasts <strong>for</strong> dur beats, and whose frequency is 1 g plus the number of<br />

half steps stored in pitchOffset plus a number of half steps equal to the index i. <strong>The</strong>n the time counter<br />

t is incremented by the duration of the event just created and the loop repeats. <strong>The</strong> overall effect is that<br />

we hear several, related sequences, each one faster and at a higher pitch than the one be<strong>for</strong>e it.<br />

Using MIDI Files with the MarkovChain<br />

<strong>The</strong> longer the training sequence, the more likely the generated sequences are to sound related to the<br />

original without being exact copies of the original. But entering long arrays by hand can be tedious, so<br />

here is a little trick <strong>for</strong> obtaining long sequences of MIDI events <strong>for</strong> use in a MarkovChain: Create a<br />

TimedEventSequence by reading it from a MIDI file, make sure it is monophonic, and then create a<br />

MarkovChain using just the events from the TimedEventSequence, ignoring the starting beats.<br />

Play fantasia bill and continue reading while it churns away on this long sequence of MIDI events. Here<br />

is the script:<br />

| pat chain seq |<br />

pat :=<br />

TimedEventCollection<br />

timesAndEventsFromMIDIFile: 'DESAFIN1.MID'<br />

channel: 3.<br />

pat := pat asMonophonicEventSequence.<br />

chain := MarkovChain trainingSequence: pat events chainLength: 3.<br />

seq := chain newSequenceOfLength: 200 seed: 3.<br />

(EventSequence events: seq) playOnVoice: self onBeat: 0 bpm: 90.<br />

145

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!