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;