// title: Cumulative Pulses // author: henklass // description: // Cumulative pulses // Imagine pulse-generators with different frequencies. // Pulses are added together to generate control signals, e.g. for pitch, or maybe time. // The signals can be presented in an array to be used in a Pbind. // The length of this array is determinded by the lcm of all reciprocal frequencies / periods. The number of pulse-generators determines the ambitus of the signals. The signals are repeated palindromes. // // Example: // // period | pulses // // 1: 1 1 1 1 1 1 1 1 1 1 // // 2: 1 0 1 0 1 0 1 0 1 0 // // Si: 2 1 2 1 2 1 2 1 2 1 // // // 1: 1 1 1 1 1 1 1 1 1 1 // // 2: 1 0 1 0 1 0 1 0 1 0 // // 3: 1 0 0 1 0 0 1 0 0 1 // // S: 3 1 2 2 2 1 3 1 2 2 // // // 1: 1 1 1 1 1 1 1 1 1 1 1 1 // // 2: 1 0 1 0 1 0 1 0 1 0 1 0 // // 3: 1 0 0 1 0 0 1 0 0 1 0 0 // // 4: 1 0 0 0 1 0 0 0 1 0 0 0 // // s: 4 1 2 2 3 1 3 1 3 2 2 1 // // // In this case, the signal is used to play a melody. The separate pulse-generators are shown bij different steps on a randomly chosen scale. For the bass-line the melody is cut in half and each half is played on a different channel in half tempo. // code: /* Cumulative pulses Imagine pulse-generators with different frequencies. Pulses are added together to generate control signals, e.g. for pitch, or maybe time. The signals can be presented in an array to be used in a Pbind. The length of this array is determinded by the lcm of all reciprocal frequencies / periods. The number of pulse-generators determines the ambitus of the signals. The signals are repeated palindromes. Example: period | pulses 1 1 1 1 1 1 1 1 1 1 1 2 1 0 1 0 1 0 1 0 1 0 Signal: 2 1 2 1 2 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 2 1 0 1 0 1 0 1 0 1 0 3 1 0 0 1 0 0 1 0 0 1 Signal: 3 1 2 2 2 1 3 1 2 2 1: 1 1 1 1 1 1 1 1 1 1 1 1 2: 1 0 1 0 1 0 1 0 1 0 1 0 3: 1 0 0 1 0 0 1 0 0 1 0 0 4: 1 0 0 0 1 0 0 0 1 0 0 0 s: 4 1 2 2 3 1 3 1 3 2 2 1 In this case, the signal is used to play a melody. The separate pulse-generators are shown bij different steps on a randomly chosen scale. For the bass-line the melody is cut in half and each half is played on a different channel in half tempo. */ s.boot; ( SynthDef(\theSine, { | freq = 440, amp = 1 , pan = 0| Out.ar(0, Pan2.ar( SinOsc.ar(freq) * EnvGen.kr(Env.perc(0.001, 1, 1, -8), doneAction: 2), pan, amp ); ) }).send; SynthDef(\theBlip, { |freq=440, numharm=8, pan = 0, amp=1| Out.ar( 0, Pan2.ar( Blip.ar(freq, numharm, 1) * EnvGen.kr(Env.perc(0.1, 1, 1, -8), doneAction: 2), pan, amp ); ); }).send; ) ( var theNumber = 8, theDuration = 0.2, theScale=Scale.choose.postln; var theValues, thePulses, bass1, bass2; var grandLcm; /* grandLcm takes 1 argument n and computes the least common multiple of a series of numbers, 1..n */ grandLcm={arg n; if (n>=2, {g=lcm (thisFunction.value(n-1), n)}, {g=1} ); g; }; //thePulses contains the patterns of each individual pulse-generator thePulses=Array.new(theNumber+1); thePulses.add([0]); //thePulses.add([1]); for (1, theNumber, { arg i; var thePattern; thePattern=Array.newClear(grandLcm.value(theNumber)+1); //thePattern.size.postln; for(0, grandLcm.value(theNumber), { arg j; if (j.mod(i)==0, {thePattern[j]=1}, {thePattern[j]=0} ); }); thePulses.add(thePattern); }); //thePulses.postln; //theValues contains the result of all pulse-generators theValues=Array.newClear(grandLcm.value(theNumber)+1); for (0, theValues.size-1, { arg i; theValues[i]=0; }); for (2, theNumber, { arg i; for (0, theValues.size-1, { arg j; if (j.mod(i)==0,{theValues[j]=theValues[j]+1}); }); }); //theValues.postln; theValues.plot; //the pattern of each pulse-generator gets its own pitch and stereo-position for (1, theNumber ,{ arg i; Pbind( \instrument, \theSine, \scale, theScale, \degree, Pseq(thePulses[i]*i, 1), \octave, 5, \dur, theDuration, \amp, 1/theNumber, \pan, (2*i/theNumber-1) ).play; }); //resulting melody in the center Pbind( \instrument, \theBlip, \scale, theScale, \degree, Pseq(theValues, 1), \numharm, theNumber, \pan, 0, \dur, theDuration, \amp, 0.05 ).play; //adding basslines bass1=Array.newClear(theValues.size / 2 +1); for (0, bass1.size-1, {arg i; bass1[i]=theValues[i] }); Pbind( \instrument, \theBlip, \degree, Pseq(bass1, 1), \numharm, theNumber/2, \pan, -1, \scale, theScale, \octave, 2, \dur, theDuration*2, \amp, 0.25 ).play; bass2=bass1.reverse; Pbind( \instrument, \theBlip, \degree, Pseq(bass2, 1), \numharm, theNumber/2, \pan, 1, \scale, theScale, \octave, 2, \dur, theDuration*2, \amp, 0.25 ).play; )