Saturday, March 26, 2011

A Tweetable Drone

A tweetable Drone
Make a drone in Supercollider than can be posted on Twitter with few enough characters to include the #supercollider hashtag.

{Mix.ar(Pan2.ar(Blip.ar([64,63]*.x(3/2**(0..5))*.x 
Blip.kr(0.0001/(99..96),3,1/2**(13..18),1),9,0.03),[-1,1]/.x(1..9)))}.play


This is how many years it takes for the cycle to repeat
(1/(0.0001 /(99..96)).product) / (3600 *24 *365.25)


/*The lowest note is
63 HZ and the highest is
63 * (3/2**5) * 9

4305.65625 Hz


The fundamental frequency of 64 and 63. 1/64 is the difference between an overtone major third and a major third in pythagorean tuning (5/4, or 80/64 vs 9/8 * 9/8, or 81/64). 1:64 is also the ratio of a pitch and another pitch 6 octaves above it, so in a sense you can think of the rhythm as the pitch, 6 octaves down.

This code defines 2 sine waves at 64 and 63 hz. I'm using the "Blip" Ugen because it has fewer characters than SinOsc and because we can use it to add more overtones to our sound without adding more characters to the code:

{Mix.ar(Pan2.ar(Blip.ar([64,63],1,0.3)))}.play;


Fundamental tone by Backtrace


Add overtones up to the 8th overtone:


{Mix.ar(Pan2.ar(Blip.ar([64,63],9,0.3)))}.play

Fundamental with overtones by Backtrace


Now, just the sine waves, but harmonized. The expression (3/2**(0..5)) produces an array with these values
[ 1, 1.5, 2.25, 3.375, 5.0625, 7.59375 ]

Which are the first 6 steps around the circle of 5ths, or if this were written in C major, you would start at C and go up a perfect 5th to G, then D, A, E and B natural, all pitches within the key of C major.

{Mix.ar(Pan2.ar(Blip.ar([64,63]*.x(3/2**(0..5)),1,0.1)))}.play;

Harmonized in 5ths by Backtrace



Now the same chord, with the overtones. This is the complete set of pitches in the piece, but due to phase cancellation all of these pitches are never heard at once.
{Mix.ar(Pan2.ar(Blip.ar([64,63]*.x(3/2**(0..5)),9,0.1)))}.play;

All pitches by Backtrace


This is the shape of the moduation on the pitches - using Blip.kr. You can hear how the pitch takes different sized dips, large and small. In the final piece, the modulation is much slower and more subtle.


{Mix.ar(Pan2.ar(Blip.ar([64] *.x Blip.kr(1/4,3,1,2),1,0.03)))}.play;


Modulator shape by Backtrace


Here, multichannel expansion produces 4 pairs of [63,64] modulating in patterns that are increasingly out of step with each other. The mutiple modulators are created using the expression (99..96) which produces an array with values [99,98,97,96] and then this signal is multipled by the frequencies [64,64] via the *.x operator.

{Mix.ar(Pan2.ar(Blip.ar([64,63] *.x Blip.kr(1/(99..96),3,1/2,1),1,0.03)))}.play;

Multiple modulators by Backtrace


Now let's hear the same, with overtones.
{Mix.ar(Pan2.ar(Blip.ar([64,63] *.x Blip.kr(1/(99..96),3,1/2,1),9,0.03)))}.play;

Overtones with large modulators by Backtrace


Now, let's slow the modulaton down 10,000 times. and make the actual pitch bending much much smaller, from a range of 1/(2**13) to 1/(2**18). These changes in pitch are far too small to hear - the largest is 1/8192 multiplied by the highest pitch 4305.65625 which is (4305.65625/8192) which is about 0.52 of 1Hz. What you hear instead is the sound of pitches up and down the overtone series fading in and out via phase cancellation.

{Mix.ar(Pan2.ar(Blip.ar([64,63]*.x Blip.kr(0.0001/(99..96),3,1/2**(13..18),1),9,0.05)))}.play;

Overtones with small modulators by Backtrace


Finally, we add our harmony, in stacked perfect 5ths.
{Mix.ar(Pan2.ar(Blip.ar([64,63]*.x(3/2**(0..5))*.x Blip.kr(0.0001/(99..96),3,1/2**(13..18),1),9,0.05)))}.play;



The last step is to revisit our Pan2 UGen and use multichannel expansion, ranges and operator adverbs to split the Blip UGens into 16 channels panned from full left to full right
[-1,1]/.x(1..9)
produces:

[ -1, -0.5, -0.33333333333333, -0.25, -0.2, -0.16666666666667, -0.14285714285714, -0.125, -0.11111111111111,
1, 0.5, 0.33333333333333, 0.25, 0.2, 0.16666666666667, 0.14285714285714, 0.125, 0.11111111111111 ]


{Mix.ar(Pan2.ar(Blip.ar([64,63]*.x(3/2**(0..5))*.x
Blip.kr(0.0001/(99..96),3,1/2**(13..18),1),9,0.03),[-1,1]/.x(1..9)))}.play

At 127 characters, we still have room to add the #supercollider hash tag
{Mix.ar(Pan2.ar(Blip.ar([64,63]*.x(3/2**(0..5))*.x 
Blip.kr(0.0001/(99..96),3,1/2**(13..18),1),9,0.03),[-1,1]/.x(1..9)))}.play #supercollider

Tweetable drone by Backtrace