// title: The City Breathing // author: nufets // description: // an installation-setup // code: // An installation piece // (c) Stefan Nussbaumer 2011 - licensed under Creative Commons: https://creativecommons.org/licenses/by-sa/3.0/ // sampled sound (street-noise) gets ganulated and played back spread over an arbitrary number of speakers // the audience interacts with the installation via a microphone // you will need to install the following quarks in order to run the piece: // CVCenter: Quarks.install("CVCenter") // wslib: Quarks.install("wslib") // audio-files can be downloaded here (as soon as they get approved...): // http://www.freesound.org/people/nufets/sounds/150201/ // http://www.freesound.org/people/nufets/sounds/150200/ // http://www.freesound.org/people/nufets/sounds/150199/ ( s.waitForBoot { c = Condition.new; t = TempoClock().permanent_(true); CVCenter.use(\tempo, #[0.5, 5, \exp], 1.0, tab: \traffic); b = Buffer.readDir("/Volumes/satellite/Music/road_to_nowhere/rtn_samples_mono/", server: s, notify: true); ( SynthDef(\grainer, { |bufnum, out=0, ratio=1, start, end, atk, sus, rel, level=1, curve=(-4), gate=1, pos=0, width=1, orientation=0.5| var in, env, times, outs; env = Env.linen(atk, sus, rel, level, curve); in = BufRd.ar(1, bufnum, Phasor.ar( 0, BufRateScale.kr(bufnum) * ratio, start, end )); Out.ar(out, PanAz.ar(4, in, pos, width: width, orientation: orientation) * EnvGen.ar(env, gate, doneAction: 2)); }).add ); ( SynthDef(\audience, { |in=0, amp=1.0, atk=0.01, rel=0.01, median=4, ampThresh=0.01, clarity=1, lagAmp=1, lagPitch=1, lagHasPitch=1| var sig, ampltd, pitch, hasPitch; sig = SoundIn.ar(in, amp); ampltd = AmplitudeMod.kr(sig, atk, rel); #pitch, hasPitch = Pitch.kr(sig, 20, median: median, ampThreshold: ampThresh, clar: clarity); SendReply.kr(Impulse.kr(10), 'audience-noise', [ampltd, pitch, hasPitch].lag([lagAmp, lagPitch, lagHasPitch])); }).add ); s.sync; ~audience = Synth(\audience, [\in, 0]); CVCenter.use(\audAmp, #[0.1, 1.5].asSpec, 0.0, \audience); CVCenter.use(\audPitch, #[20, 5000, \exp].asSpec, 20.0, \audience); CVCenter.use(\audClar, #[0.0, 2.0].asSpec, 0.0, \audience); ~resp.remove; ~resp = OSCresponderNode(nil, 'audience-noise', { |t, r, msg| [CVCenter.at(\audAmp), CVCenter.at(\audPitch), CVCenter.at(\audClar)].do({ |cv, i| cv.value_(msg[i+3]) }); ~response = msg[3..]; }).add; ~rt = { loop { t.tempo_(CVCenter.at(\tempo).value * CVCenter.at(\audAmp).value * 10); 0.1.wait; } }.fork(AppClock); t.tempo.postln ( ~increase = CVCenter.use(\increase, #[0.1, 10.0], 1.0, \traffic); ~decrease = CVCenter.use(\decrease, #[0.1, 10.0], 1.0, \traffic); Pdef(\grain, Pbind( \instrument, \grainer, \bufnum, Pfunc({ ~buf = b.choose; ~buf.bufnum }), \ratio, (Pxrand(ScaleInfo.scales.choose, inf) * CVCenter.use(\detune, #[1, 0.1].asSpec, 0, \traffic) * CVCenter.at(\audPitch)/500).trace(prefix: 'pitch :'), \start, Pfunc({ rand(~buf.numFrames) }), \end, Pfunc({ rand(~buf.numFrames) }), \dur, Pn( Pseg( Pwrand([ 0.1, 0.2, Pseq((1/7)!7, 1), Pseq((1/3)!3, 1), 0.5, Pxrand([0.7, 0.3], 1) ], [1, 10, 5, 8, 3].normalizeSum, inf), Pseq([~increase, ~decrease], inf), repeats: 1 ) * CVCenter.at(\audAmp).reciprocal, inf )/*.trace(prefix: 'dur: ')*/, \atk, 0.001.rrand(Pkey(\dur)/4), \sus, 0.001.rrand(Pkey(\dur)/4), \rel, Pkey(\dur)-Pkey(\atk)-Pkey(\sus), \level, CVCenter.use(\sampAmp, \amp.asSpec, tab: \traffic), \curve, Pwhite(-4.0, 4.0), \pos, CVCenter.use(\pos, \pan.asSpec, tab: \traffic)+CVCenter.at(\audPitch), \width, Pn(CVCenter.use(\width, #[0.06, 0.2223].asSpec, tab: \traffic) * (CVCenter.at(\audAmp) + 0.5 * 30), inf)/*.trace(prefix: 'width: ')*/, \orientation, CVCenter.use(\ori, #[0, 1].asSpec, tab: \traffic)+CVCenter.at(\audClar)/*.trace(prefix: 'ori: ')*///, ) ) ); Pdef(\grain).play(t); ( Pdef(\audience, Pbind( \instrument, ~audience, \type, \set, \args, #[lagAmp, lagPitch, lagHasPitch], \dur, Pwhite(0.01, 1.0), #[lagAmp, lagPitch, lagHasPitch], Ptuple([CVCenter.at(\audAmp) * 7, CVCenter.at(\audPitch) / 200, CVCenter.at(\audClar) * 7], inf).collect({ |all| all.scramble }).trace(prefix: 'ptuple: ') ) ) ); Pdef(\audience).play(t); } )