MonoPortaVoicer : Voicer


A subclass of Voicer, providing similar functionality for sequencing and MIDI response. Designed to emulate the behavior of mono synthesizers with fingered portamento.


Differences:


MonoPortaVoicer allows only one voice. You must still give 1 as the first argument to MonoPortaVoicer.new. Any other number will be changed to 1 for you.

If a second note is played while the first is sustaining, the pitch will slide to the new pitch if your synthdef is written correctly (see below). Envelopes will not be retriggered.


Getting portamento in your synthdefs and Instr's


As in Voicer, the arguments freq and gate are required. To these, add freqlag -- the lagtime to slide from one pitch to the next. The lagtime argument will be assigned by the voicer depending on whether portamento is needed for this note or not. Do not set freqlag in your initial arguments—above all, do not make freqlag a fixed argument if you're using Instr. Portamento will not work as you expect in that case.


Include the line


freq = Lag.kr(freq, freqlag);


in your synthdef or Instr. For portamento to work correctly, it must be a variable-length lag, and this is the only way to do it.


To set the portamento time, use  myVoicer.portaTime = myTime;


Example:


(

Instr([\analog, \two_osc], {

arg freq, freqlag, gate, ffreq, rq, velsense, env, fenv, detune, width;

var amp, sig;

amp = Latch.kr(gate, gate) * velsense + 1-velsense;

freq = Lag.kr(freq, freqlag);

sig = Mix.ar(Pulse.ar([freq, freq*detune], width, amp));

sig = RLPF.ar(sig, EnvGen.kr(fenv, gate) * ffreq, rq);

sig = sig * EnvGen.kr(env, gate, doneAction:2);

[sig, sig] * 0.5

}, #[\freq, [0, 2], \amp, \freq, [1, 0.05, \linear, 0, 0.5], \amp, nil, nil, [0.98, 1.02, \linear, 0, 1], [0, 1]]);


v = MonoPortaVoicer(1, Instr.at([\analog, \two_osc]), [\ffreq, 2000, \rq, 0.5, \env, Env.adsr(0.05, 0.1, 0.8, 0.2), \fenv, Env.adsr(0.2, 0.3, 0.25, 1), \detune, 0.99, \width, 0.25]);

)


k = VoicerMIDISocket(0, v); // to play the voicer on your keyboard

k.addControl(1, \ffreq, 2000, \freq); // control filter cutoff using modwheel; optional

v.gui; // optional


v.portaTime = 1; // try these different settings, see what the effect is

v.portaTime = 0.25;

v.portaTime = 0; // note that there's always a slide, even if the time is 0, except on retrig

v.portaTime = 0.4;


v.free; // when you're done playing