supercollider

work with mark: inaugural talk

a small project i did for mark d'invero's inaugural talk nov'04 was to create a sort of entrance music or ambience as people came in and took their seats. i transcribed one of mark's jazz tunes called val's song. the head of this song - repeated over and over - formed the basic musical material. then i coded few agents that would play and manipulate it. the agents got input from a video-analysis program i had written in max/softvns. so there was a dv-camera looking at the crowd taking their seats and the program looked at the total motion of 4 different areas of the hall. as the people settled the amount of motion decreased to nearly zero and this made a nice form curve for the piece as a whole... people coming in, mingling and slowly calming down right before the talk.
the agents were allowed control over certain aspects of the music like overall tempo, which scale to use, transposition, volume, sustain and legato of tones and the amount of reverb. and we used supercollider plus the RedDiskInSamplerGiga with a grand-piano sample library to get a nice but discrete sound. unfortunately very few noticed the music system as we did not allow it much volume and the crowd was pretty noisy.

here's the basic song material val's song in supercollider code...

/*val's song by m.d'inverno*/
s.boot;
TempoClock.default.tempo_(2.2)
(
a= Pdef(\x, Pbind(      /*melody*/
        \root, 3,
        \octave, 5,
        [\degree, \dur], Pseq([
                [-3, 1.5], [0, 1], [1, 0.5], [2, 0.5], [3, 1], [4, 1], [2, 0.5],
                [-3, 1.5], [0, 1], [2, 0.5], [1, 3],
                [0, 0.75], [1, 0.75], [2, 0.75], [4, 0.75], [7, 0.75], [8, 0.75], [9, 0.75], [7, 0.75],
                [8, 1.5], [7, 1], [9, 0.5], [8, 3],
                [-3b, 1.5], [0, 1], [7, 0.5], [7, 2], [0, 1],
                [0, 1.5], [7, 1.5], [7, 0.5], [8, 0.5], [9, 2],
                [7, 0.5], [4, 1], [4, 1], [4, 0.5], [3, 0.5], [-1b, 1], [-1b, 1], [-2b, 0.5],
                [-3, 3], [\rest, 3]
        ], inf)
));
b= Pdef(\y, Pbind(      /*bass*/
        \root, 3,
        \octave, 4,
        [\degree, \dur], Pseq([
                [4, 3], [0, 2], [0, 1],
                [4, 3], [-1, 2], [-1, 1],
                [-2, 3], [-2, 2], [2, 1],
                [-3, 3], [-3, 2], [-2b, 1],
                [-2, 2], [0, 1], [2, 3],
                [3, 1.5], [-2, 1.5], [0, 3],
                [-3, 3], [-3, 2], [0b, 1],
                [0, 3], [-3, 3]
        ], inf)
))
)
Ppar([a, b]).play;

and below is the code i stepped through as a small part of the actual talk. this was just to let people see how we could build music from scratch using sc. in the end mark played along together with this on his electrical piano.

/*--setup--*/
s.boot;
a= [0, 0.25, 1, 0, 0, 0.5, 0, 0.25].scramble;
b= [1, 0, 0, 0, 1, 0.25, 0, 0, 0, 0.5, 0, 0.5, 1, 0, 1, 1].scramble;
c= TempoClock.new;
p= ProxySpace.push(s, clock: c);
~out.ar(2);
~pattern1.kr(1);
~pattern2.kr(1);
~pattern3.kr(1);
~pattern4.kr(1);
~out.play;

/*--talk demo--*/

/*definition*/
(
~bassdrum= {arg t_trig, amp= 1, release= 2.5, freq= 100;
        Decay2.kr(t_trig, 0.01, release, amp)
        * SinOsc.ar([freq, freq*0.9], 0, 0.5)
}
)

~out.add(~bassdrum)
~bassdrum.set(\t_trig, 1)

/*change parameters*/
~bassdrum.set(\freq, 70, \release, 0.3)
~bassdrum.set(\t_trig, 1)

/*add an delay effect*/
~bassdrum.filter(1, {arg in; z= 0.2; in+CombN.ar(in, z, z, 3)})
~bassdrum.set(\t_trig, 1)
~bassdrum.filter(1, {arg in; in})

/*play pattern*/
~pattern1= StreamKrDur(Pseq([1, 0, 0, 1, 0, 1, 1, 1], inf), 0.25)
c.sched(c.timeToNextBeat(1), {~bassdrum.map(\t_trig, ~pattern1)})

/*swing*/
~pattern1= StreamKrDur(Pseq([1, 0, 0, 1, 0, 1, 1, 1], inf), Pseq((0.25*[1.2, 0.8]), inf))

/*add more drums*/
(
~snaredrum= {arg t_trig, amp= 1, release= 0.12;
        Decay2.kr(t_trig, 0.01, release, amp) * Pan2.ar(Resonz.ar(ClipNoise.ar(0.3), 1500, 0.5))
};
~out.add(~snaredrum);
)

/*play pattern*/
(
~pattern2= StreamKrDur(Pseq([0, 1, 0, 0], inf), 0.5);
c.sched(c.timeToNextBeat(1), {~snaredrum.map(\t_trig, ~pattern2)});
~pattern1= StreamKrDur(Pseq([0, 1, 0, 1, 0, 1, 0.25, 1], inf), 0.25);
~pattern2= StreamKrDur(Pseq([1, 0.25, 1, 1, 0, 0, 0, 0, 0.5, 0.5, 0, 0.5, 0, 0, 0, 0], inf), 0.125);
)

/*add a bass w/ random melody and change drum patterns*/
(
~bass= {arg freq= 60, amp= 0;
        RLPF.ar(Saw.ar([freq, freq*1.01], amp), SinOsc.kr(0.2, 0, 200, 500), 0.2, 0.1)
};
~out.add(~bass);
)
(
~pattern3= StreamKrDur(Pseq([1, 0, 0.5, 0.5, 0, 1, 1, 0.5, 0.25, 1, 0, 1, 0.5, 0, 1, 0]*0.6, inf), Pseq((0.125*[1.2, 0.8]), inf));
~pattern4= StreamKrDur(Pseq(b*100+20, inf), Pseq((0.125*[1.2, 0.8]), inf));
c.sched(c.timeToNextBeat(1), {~bass.map(\amp, ~pattern3)});
c.sched(c.timeToNextBeat(1), {~bass.map(\freq, ~pattern4)});
)

~out.release(2);
p.clear;

work with mark: supercollider sampler

for my work together with mark d'inverno i coded a few tools. one of the things that came up was a need for a neutral but nice sounding way to test aspects of our musical agents systems. so we got hold of a grand-piano sample library and i wrote a 'giga sampler' like class for supercollider. this allowed us to use this massive sample library (2.5gig) and let the agents play high quality samples instead of cheap midi or boring synthesised sounds. so for testing melodies, harmonies and such this was a good thing.

the trick with the giga sampler is that it preloads a bit from each soundfile into ram memory and then streams the rest from disk when needed. or at least this is how i understands it. so using this technique, one can get quick access to a lot more samples than normally would fit in the memory of a sampler. a massive library like ours with full 88keys range, sampled in many different velocities, would occupy ~5gig of ram (supercollider uses 32bit internally), nor could it be streamed from disk (the harddrive would be too slow to access and load the headers to play fast chords progressions without staggering etc).

i spent some time to make my class all round useful and it can be downloaded _here or simply install by typing Quarks.install("redSampler") in sc. the class of interest in that package is called RedDiskInSampler.

and here is some testcode for it...

s.boot;
d= ();                                  /*for mapping midinote to filename*/
r.free;
r= RedDiskInSamplerGiga(s);             /*sampler*/
(
var folder= "/Users/asdf/Documents/soundfiles/bosen44100/";  //edit to match your samplebank
var velocities= #[40, 96];              /*velocities to load*/
var octavesToLoad= #[2, 3];             /*how many octaves to load*/
var scale= #['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
/*so number of samples to load is octavesToLoad.size*12*velocities.size*/
/*lowest note C2= midi 36*/
velocities.do{|x, i|
        var tempDict= ();
        d.put(x, tempDict);
        octavesToLoad.do{|y, j|
                scale.do{|z, k|
                        var midinote, pathname, key;
                        midinote= y*12+12+k;
                        key= z++y;
                        pathname= folder+/+x+/+key++".aif";
                        key= (key++"_"++x).asSymbol;
                        tempDict.put(midinote, key);     /*like (45 : A2_96)*/
                        ("loading key"+key+"from file"+pathname).postln;
                        r.preload(key, pathname);
                };
        };
};
)
r.play(\C2_96, 0, 3, 1)
r.play(\D2_40, 0, 3, 1)
Tdef(\test).play
a= r.loadedKeys;
(Tdef(\test, {
        inf.do{|i|
                r.play(a.choose, 0, 0.45, 0.1);
                0.5.wait;
        }
}))
(Tdef(\test, {
        b= a.asArray.scramble;
        inf.do{|i|
                b.do{|x, j|
                        r.play(x, 0, 0.35, 0.1);
                        0.15.wait;
                };
                2.wait;
        }
}))
(Tdef(\test, {
        b= a.asArray.sort;
        inf.do{|i|
                b.do{|x, j|
                        r.play(x, 0, 0.25, 0.08, amp: 0.6);
                        0.1.wait;
                };
                1.wait;
        }
}))
Tdef(\test).stop
r.free

august practice sessions

nick and i made a pact to do 1hour of live coding practice for each day of august. julian joined in too on a couple of days.

here are rendered mp3s of my practising sessions. music quality varies...

they're all coded from scratch (synthesis, patterns etc) in ~1hour using plain jitlib. the sourcecode is available here... code
(you might need to copy and paste or select all to see it as i accidentally colorised all the documents)
so rather than listening to the static mp3s above, i'd recommend to download supercollider and play [with] the code.

i think i've identified two problems. first the getting-started and then the getting-on-when-you-finally-got-started.
in the beginning there's always the empty document... uhu. so setting up a little task to solve or having an idea of some soundscape i'd like to create seemed to help. it was usually ideas like use fm-synthesis today or make soft drone sounds tonight. still, many times it started out sounding just awful and i got more and more stressed trying fix it. any livecoders recognise this feeling? ;-) but pulling some tricks (usually distortion or delay effects :-) and focusing in on a few details - muting other sounds - i think i managed shape all the code to become somewhat okey sounding in the end. i only reset the clock and started all over from scratch twice.
and then when i got nice processes going, it has been hard to let go of that and continue with something different. so the resulting music above is most often just a single 'theme' or process. i feel i'd have to rehears a lot more to be able to do abrupt form changes or to have multiple elements to build up bigger structures over time with. i sort of got stuck in the a of the ABA form. it would've been nice to go ABAC etc. perhaps that the 1h time limit made you reluctant to start something new 45minutes in as that'd have probably been left hanging.
































update 171217: converted all files from .rtf to .scd and attached as a .zip

AttachmentSize
Package icon livecodePractice-aug06_scd.zip56.8 KB

Pages

Subscribe to RSS - supercollider