WarpIn Warp live input


Inspired by Chad Kirby's SuperCollider2 Warp1 class, which was inspired by Richard Karpen's sndwarp for CSound. A granular time strecher and pitchshifter.


WarpIn.ar(in, buffer, warpFactor, freqScale, windowSize, envbufnum, overlaps, windowRandRatio, 

interp, mul, add)


in - input - make sure the number of channels is the same as those allocated in the buffer

buffer - the buffer number of a mono buffer.

warpFactor - amount to stretch or compress the buffer. 0.5 is half speed, 2 is twice the speed. Since the 

sound is recorded and warped at the same time, warpFactors of greater than 1 may overshoot the

record buf.

freqScale- the amount of frequency shift. 1.0 is normal, 0.5 is one octave down, 2.0 is one octave up.

Negative values play the soundfile backwards.

windowSIze - the size of each grain window.

envbufnum - the buffer number containing a singal to use for the grain envelope. -1 uses a built-in 

Hanning envelope.

overlaps - the number of overlaping windows.

windowRandRatio - the amount of randomness to the windowing function.  Must be between 0 (no

randomness) to 1.0 (probably to random actually) 

interp - the interpolation method used for pitchshifting grains. 1 = no interpolation. 2 = linear. 

4 = cubic interpolation (more computationally intensive).



Examples:


s = Server.local;

s.boot;


//Use headphones for these examples!

(


SynthDef(\warp, {arg dur = 1, buffer = 0;

var out, buflength, env, warp;

env = EnvGen.kr(Env([0.0001, 1, 0.0001], [0.1, 0.9], [4, -4]), timeScale: dur, doneAction: 2);

buflength = BufDur.kr(buffer);

warp = 0.5;

// read in stereo ... can be any number of channels BUT these must match the 

// number of channels in the buffer

out = WarpIn.ar(AudioIn.ar([1, 2]), buffer, warp, 1, 0.1, -1, interp: 1);

Out.ar(0, out * env);

}).send(s);


)


// stereo buffer

b = Buffer.alloc(s, s.sampleRate * 16, 2);

a = Synth(\warp, [\dur, 16, \buffer, b]);


b.free;


// a Routine to create individual buffers for a testure of WarpIns

(

~bufs = [];

r = Routine.run({

var buf, synth, cond, thisnotedur;

cond = Condition.new;

10.do({

thisnotedur = 4.rrand(12);

// stretching by 0.5, need buffer for half the duration

buf = Buffer.alloc(s, thisnotedur * s.sampleRate * 0.5, 2); 

~bufs = ~bufs.add(buf);

s.sync(cond);

a = Synth(\warp, [\dur, thisnotedur.postln, \buffer, buf]);

1.wait;

})

});

)

// clean up

~bufs.do({arg me; me.free});

b.free;