The question was asked how to make sliding notes with Pbind. My preferred technique is to use MonoPortaVoicer, in my class library. MonoPortaVoicer mimics the behavior of portamento on mono synths, where overlapping the previous note with the next one causes a slide.
Voicer and MonoPortaVoicer are available from http://www.dewdrop-world.net/sc3/index.php#dewdroplib
Here's an acid-house-style demo to illustrate how it works.
Sliding notes have the sustain parameter just slightly higher than the event delta (same as if you overlapped notes on your MIDI keyboard).
Also, MonoPortaVoicer does tend to throw a lot of "FAILURE /n_set Node not found" messages when playing quickly like this. It's a timing issue that I'm not sure is solvable:
- note1 starts
- note1 is released
- note2 starts – it thinks note1 is still playing, so it tries to turn its gate off early (n_set)
- BUT, note1's release envelope has already ended so the synth is gone
- the n_set, \gate, -1 message arrives at the server but note1's node can't be found – failure message goes out
It's a harmless message, only trying to remove a synth that has already died.
Anyway... add a 4x4 kick drum, drop a tab, and have a merry xmas!
hjh
// init ( Instr("bass.distpulse", { arg freq, gate, freqlag, pwidth, detune, distortion, ffreq, rq, vsense, fenvsense, env, fenv, trigthresh, t_gate, logate = 0, higate = 1, lotrig = 0.5, hitrig = 1.0; var sig, amp; var trig = (t_gate > trigthresh) * LinLin.kr((t_gate - trigthresh).clip(logate, higate), logate, higate, lotrig, hitrig); freq = Lag.kr(freq, freqlag); amp = (Latch.kr(gate, gate) - 1) * vsense + 1; // oscillator sig = Pulse.ar([freq, freq*detune], pwidth); // distortion sig = Mix.ar((sig * distortion).distort) * amp; // filter envelope ffreq = ffreq * (1 + EnvGen.kr(fenv, trig, levelScale: trig * fenvsense)); sig = RLPF.ar(sig, ffreq.clip(20, 20000), rq); // output phase sig * EnvGen.kr(env, gate, doneAction:2) }, [\freq, [0, 1], \freqlag, [0, 1], \mydetune, [1, 10], \freq, \myrq, [0, 1], [0, 1], EnvSpec(Env.adsr(0.01, 0.25, 0.5, 0.1)), EnvSpec(Env.adsr(0.01, 1, 1, 1))]); m = MixerChannel(\bass, s, 1, 2, level: -14.dbamp); v = MonoPortaVoicer(1, Instr("bass.distpulse"), [\detune, `1.00851763877, \distortion, 10, \ffreq, 180, \rq, 0.05, \vsense, 0.2, \fenvsense, 9.0, \env, Env.adsr(0.01, 0.06, 0.4, 0.1), \fenv, Env(#[1, 4, 1], #[0.01, 0.9], curve: -2), \logate, `0, \higate, `0.5, \lotrig, `0, \hitrig, `1, \trigthresh, 0.5, \pwidth, `0.5], target:m); v.portaTime = 0.3; c = v.mapGlobal(\ffreq, nil, 180, \freq); d = c.play({ LinExp.kr(LFNoise1.kr(0.05, 0.5, 0.5), 0.0, 1.0, 180, 2000) }); TempoClock.default.tempo = 122/60; ) // go ( p = Pchain( Pseq([ // short repeated tonic notes Pbind(\midinote, Pstutter(Pwhite(4, 12, 1), 36), \delta, Pwrand(#[0.25, 0.5], #[0.7, 0.3], inf), \sustain, Pkey(\delta) * Pwhite(0.2, 0.8, inf), \gate, Pwhite(0.1, 0.75, inf) ), // downward slides Pbind(\midinote, Plazy({ Pseq([Prand(#[40, 41, 43, 46], 1), 36], rrand(1, 5)) }), \delta, Pseq([Pwrand(#[0.25, 0.5, 0.75], #[0.7, 0.2, 0.1], 1), Pwrand(#[0.25, 0.5, 0.75], #[0.1, 0.7, 0.2], 1)], inf), \sustain, Pkey(\delta) * Pseq([1.1, Pwhite(0.6, 1.05, 1)], inf), \gate, Pwhite(0.4, 0.9, inf) ) ], inf), Pbind(\type, \voicerNote, \voicer, v) ).play; ) p.stop; // clean up d.free; v.free; m.free;