Thursday, January 20, 2011

Problem #4 - More Sonifications

I decided for this sonification to treat the digits 0..9 something like a major-9th chord. The frequency ratio 4:5:6:7:8:9 is a major ninth in 7-limit just intonation. Since we can't multiply frequencies by 0, I add 1 to all of the digits, so our pitch ratio is 1:2:3:4:5:6:7:8:9:10 which is essentially a power chord underneath a major 9th, topped off with an extra mediant (and also the first 9 overtones of the lowest pitch). Ok.

In the first sonification I posted, there are only 5 distinct pitches, which play at different octaves - I decided to make things more interesting by transposing these pitches according to some other base pitch - this kind of parallel harmonization, called "chord planing" became kind of a cliche in early 20th century music by composers like Debussy and Ravel (in a funny way this reminds me of the time my undergrad composition teacher Rob Constable, who studied with Ligeti, played us the opening of an intensely polyrhythmic and polytonal piece like Lotano and then said that "Ligeti would sail across the Atlantic and kill me for saying this but you can really hear the Ravel in the there").

So this next version tweaks the previous version by playing a parallel harmony at some overtone based on the sum of the digits in the palindomic number being played - for example, if the notes in the melody are 975579 then the pitches are 42 *.x [9,7,5,5,7,9];

I brough down the base frequency from the key of 16hz to the key of 11000/768 hz, and then made the wait time as the iterator counted down be 64 times that frequency. (So the rhythms are still related at an octave ratio to the pitches to try to squeeze out some interesting phase-cancellation effects in how the pitches overlap).



(
//set up a Routine that will iterate 999 * 999 times.
Routine{
999.do({|j|
var jj = 999-j;
999.do({|i|

var n =((999-j) * (999-i)).asString,c=0,s;
//test if the string representation of n is a palindrome
(n.reverse==n).if ({
//it is - let's play some notes
Routine {
/* we'll use the sum of the
digits of n as a musical parameter */
var sumDigits=0;
n.size.do({|d|
sumDigits = sumDigits + n.at(d).digit;
});

//step through each of the digits of n
n.size.do({|k|
//we'll play 2 notes for each digit
var s = [1,0], freq, octave;
//a pair of notes, in a base octave, and harmonized at an overtone
octave = [{((1/((12/11)/1000))/64) * sumDigits},{((1/((12/11)/1000))/128) * (2**sumDigits.log2.floor)}];
//iterate through [0,1] and play the 2 notes
s.collect({|t|
var ss;
ss = Synth("sine");
//the frequency is octave * kth digit of n
freq = (n.at(k).digit +1) * (octave[t]);
/* amplitude follows a pink noise curve, release gets longer as the sequence progresses,
and pan spreads more as the sequence progreses. The amplitude envelope is a sharp percussive curve. */
ss.set(\freq,freq ,\atk,0.001,\rel,((i+3).log + (j+3).log).clip(0.1,7)*2/3,
\pan,(j/1000)* (-1**i) *2/3,\amp,0.3 * (1/(freq+128)),\sus,-32,\gate,1);
});
//change the rhythm of the notes - each palindomic melody is based on a factor of the palindromic number
((1/ (jj.factors.wrapAt(i)).log2.ceil)).wait;
});
}.play;
p.add([999-j,999-i,n.asInt]);
});
((12/11) / 1000).wait;
});

});
}.play;
)


4.0 by Backtrace


Even with all of the rhythmic complexity, it feels like the notes come in clusters - around every 11th time through the loop, for example. This got me thinking into what it is that actually makes a number palindromic, and if it has anything to do with it being the product of numbers that must have palindromic prime factors.


The next sonification I made was rhythmically simpler, but harmonically the same - as the outer iterator counts down, if any products in the inner loop of 999 numbers contain palindromes, it plays all of them at once, waits for 1 second, and then moves to the next in the list (if there are no palindromes, it gets skipped with no wait). The rhythms of the palindromic melodies are also simpler - just 1 beat per second divided by the number of digits, so a melody is always 1 second long.


(
Routine{
999.do({|j|
var jj =999-j, doWait = 0;
(jj).post;
jj.factors.postln;

999.do({|i|
var n =((jj) * (999-i)).asString,c=0,s;
(n.reverse==n).if ({
n.postln;
doWait = 1;
Routine {
var sumDigits=0;
n.size.do({|d|
sumDigits = sumDigits + n.at(d).digit;
});

n.size.do({|k|
var s = [1,0], freq, octave;
octave = [{16 * sumDigits},{8* (2**sumDigits.log2.floor)}];
s.collect({|t|
var ss;
ss = Synth("sine");
freq = (n.at(k).digit +1) * (octave[t]);
ss.set(\freq,freq ,\atk,0.001,\rel,n.size,\pan,(j/1000)* (-1**i) *2/3,\amp,(jj.log10 /10) * (1/(freq+128)),\sus,-32,\gate,1);
});
(1/n.size).wait;
});
}.play;
p.add([999-j,999-i,n.asInt]);
},{
0.wait
});

});
doWait.wait;
});
}.play;
)

4.1 by Backtrace

No comments:

Post a Comment