Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

Designing Sound in SuperCollider/Bubbles

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

Fig 35.5: producing a repeating but random-seeming pattern of triggers First we'll create a reusable synthdef that outputs triggers (but not sound): ( SynthDef(\bubbletrigs, {|out=0, probability=0.5| var trigs, buf, a; // These two lines create a loop of zeroes // with some ones (i.e. triggers) placed at prime-number locations a = {0}.dup(200); [29, 37, 47, 67, 89, 113, 157, 197].do{|val| a[val] = 1}; buf = a.as(LocalBuf); // playbuf by default will use the server's rate, but we want one item every 15ms trigs = PlayBuf.kr(1, buf, 0.015.reciprocal / (s.sampleRate / s.options.blockSize), loop: 1); // Randomly discard half of them, to remove too much obvious looping trigs = CoinGate.kr(probability, trigs); // Let's poll to watch the events appearing trigs.poll(trigs); Out.kr(out, trigs); }).add ) // Then we'll play it: x = Synth(\bubbletrigs); // watch the post window to see the bubble events happening (no sound yet!) x.free; Fig 35.8: sound of a bubble ( SynthDef(\bubblebub, { |out=0, t_trig=0, attack=0.01, decay=0.08, pitchcurvelen=0.1, freq=1000, doneAction=0, amp=0.1| var pitch, son; amp = amp * EnvGen.ar(Env.perc(attack, decay).delay(0.003), t_trig, doneAction: doneAction); pitch = freq * EnvGen.ar(Env.new([0,0,1],[0,1]).exprange(1, 2.718), t_trig, timeScale: pitchcurvelen); son = SinOsc.ar(pitch); // high-pass to remove any lowpitched artifacts, scale amplitude son = HPF.ar(son, 500) * amp * 10; Out.ar(out, son); }).store ) x = Synth(\bubblebub); x.set(\t_trig, 1); // run this line multiple times, to get multiple (very similar) bubbles! x.free; Fig 35.9: four bubble systems, simply triggered at random. ( s.bind{ // Here we'll create busses to hold the triggers, passing them from synth to synth ~maintrigbus = Bus.control(s, 1); ~bubtrigbus = Bus.control(s, 4); // Note how we make sure things are running in the desired order, using \addAfter ~trigs = Synth(\bubbletrigs, [\out: ~maintrigbus]); // This reads the main trig and puts each trig on a randomly-chosen bus ~randomdistrib = { var trig, which; trig = In.kr(~maintrigbus); which = TIRand.kr(0,3, trig); // or try the Stepper instead of TIRand for "round-robin" selection: // which = Stepper.kr(trig, 0, 0, 3); which = which.poll(trig); Out.kr(~bubtrigbus.index + which, trig); }.play(target: ~trigs, addAction: \addAfter); s.sync; ~bubs = [2400, 2600, 2500, 2700].collect{|afreq| Synth(\bubblebub, [\freq, afreq], target: ~randomdistrib, addAction: \addAfter); }; s.sync; // "map" allows us to push the triggers from the control bus to the "t_trig" inputs: ~bubs.do{|bub, bubindex| bub.map(\t_trig, ~bubtrigbus.index + bubindex) }; }; ) Note, instead of using the "bubbletrigs" synth (which is a direct port of the pd example) we could use Patterns to trigger bubble synths. This is a different model for resource management: instead of having four always-running synths which re-trigger to create a new bubble, we create one synth whenever we need a bubble, and it frees itself after. ( p = Pbind( \instrument, \bubblebub, // The commented version is a bit like the above timings... // \dur, Pseq([29, 37, 47, 67, 89, 113, 157, 197, 200].differentiate * 0.015, inf), // ...but happily we have useful random-distrib generators. Ppoisson would be ideal but is misbehaving for me! \dur, Pgauss(0.3, 0.2), \freq, Pwhite(0.0,1,inf).linexp(0,1, 1000, 3000), // doneAction of two allows the synths to free themselves. See "UGen-doneActions".openHelpFile \doneAction, 2 ).play ) p.stop This next one's a bit more complex - we do as the book does and make smaller bubbles have (a) higher pitch (b) lower volume (c) shorter duration. To connect these values together we define a "sizefactor" and use Pkey to reuse it in each of the args. ( p = Pbind( \instrument, \bubblebub, \sizefactor, Pwhite(0.0,1,inf), \dur, Pgauss(0.3, 0.2), \freq, Pkey(\sizefactor).linexp(0, 1, 1000, 3000), \amp , Pkey(\sizefactor).linlin(0, 1, 0.15, 0.04), \decay, Pkey(\sizefactor).linlin(0, 1, 0.05, 0.08), \doneAction, 2 ).play ) p.stop