‹ Work with Mark: Cellular AutomataWork with Mark: SuperCollider Sampler ›

Work with Mark: Inaugural Talk

2006-09-17 20:37 research, supercollider

A small project I did for Mark d'Invero's inaugural talk November 2004 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 a 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 SuperCollider. 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: Cellular AutomataWork with Mark: SuperCollider Sampler ›