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;