The LiSa Tutorial

Tutorial #2: using Voices

Let's sample a little ascending SinOsc and then play it back, first forward, then backwards with a slight overlap. We use the Envelope ugen to control enveloping of the recording in this case, though we could also use recRamp as in the first tutorial:

//signal chain
SinOsc s => Envelope e => LiSa loopme => dac;

//monitor the input as well as LiSa
s => dac;

//initialize SinOsc parameters
440. => s.freq;
0.2 => s.gain;

//alloc memory
6::second => loopme.duration;

//play s for a bit
500::ms => now;

//sweep the freq for fun
Envelope pitchmod => blackhole;

//set the time to target to 2 seconds
2::second => pitchmod.duration;

//set the initial value for the sinwave
s.freq() => pitchmod.value;

//set the target; "pitchmod" will begin moving towards
//880 as soon as time begins to pass

880 =>;

//set times for recording fade in/out and sample loop length
100::ms => dur recfadetime;
1000::ms => dur mylooplen;
recfadetime => e.duration;

//start recording input; record 1 seconds worth

//turn in the Envelope for recording

//calculate the time we want to record to (until before ramping down)
now + (mylooplen - recfadetime) => time later;

//allow time to pass, recording and also updating the SinOsc frequency
while(now < later) {

pitchmod.value() => s.freq;
10::ms => now;


//start ramping down

//wait for ramp to finish, and then stop recording
recfadetime => now;

//at this point, we should have a nice enveloped sample
//of the gliss in the LiSa internal buffer

//disconnect the SinOsc so we don't have to hear it
//and hangout a bit before playing back....
s =< dac;
1000::ms => now;

//now, manipulate the sample
//get an available voicenumber;
note that this voice won't actually be reserved until you play it
loopme.getVoice() => int voice1;

//we'll play voice 1 forward, and then
//crossfade it with voice 2 backwards, 1);
(mylooplen - recfadetime) => now;

//just as voice 1 is going to fade, bring in voice 2 backwards
loopme.getVoice() => int voice2;
loopme.rate(voice2, -1.);

//note that we need to set the playback position
loopme.playPos(voice2, mylooplen);

//make it a little softer
loopme.voiceGain(voice2, 0.2);

//begin playing voice 2; helps us hear when voice 2 comes in, 1);

//wait until voice 1 had finished fading, then turn off
recfadetime => now;, 0);

//wait for voice 2 to finish
1000::ms => now;

So, we hear the input, which clicks when we start it up and finish it. In the midst of that, we sample it with some nice ramping, so our LiSa buffer doesn't have any clicks. Then, when we're done sampling, we play it, first forwards, and then just as the forward voice is about the ramp down (due to the ramping that we created when we recorded to the internal buffer), we bring in the backwards voice so it overlaps. If we change the voiceGain of voice 2 to unity, then this overlap will be seamless. As an Added Bonus, this example also illustrates a couple different applications of the Envelope ugen.

more tutorials coming....