StereoConvolution2L stereo real-time convolver with linear interpolation

add

StereoConvolution2L.ar(in, kernelL, kernelR, trigger, framesize, crossfade, mul, add)

Strict convolution with fixed kernel which can be updated using a trigger signal. There is a linear crossfade between the buffers upon change.

Like Convolution2L, but convolves with two buffers and outputs a stereo signal. This saves one FFT transformation per period, as compared to using two copies of Convolution2L.

Useful applications could include stereo reverberation or HRTF convolution.

See Steven W Smith, The Scientist and Engineer's Guide to Digital Signal Processing:

chapter 18: http:// www.dspguide.com/ch18.htm

in - processing target

kernelL - buffer index for the fixed kernel of the left channel, may be modulated in combination with the trigger

kernelR - buffer index for the fixed kernel of the right channel, may be modulated in combination with the trigger

trigger - update the kernel on a change from <=0 to >0

framesize - size of FFT frame, must be a power of two. Convolution uses twice this number internally, maximum value you can give this argument is 2^16=65536. Note that it gets progressively more expensive to run for higher powers! 512, 1024, 2048, 4096 standard.

crossfade - The number of periods over which a crossfade is made. The default is 1. This must be an integer.

See also Convolution2 and Convolution2L.

(//allocate three buffers

b = Buffer.alloc(s,2048);

c = Buffer.alloc(s,2048);

d = Buffer.alloc(s,2048);

b.zero;

c.zero;

d.zero;

)

(

50.do({ |it| c.set(20*it+10, 1.0.rand); });

3.do({ |it| b.set(400*it+100, 1); });

20.do({ |it| d.set(40*it+20, 1); });

)

(

SynthDef(\conv_test, { arg kernel1, kernel2, t_trig=0;

var input;

input=Impulse.ar(1);

//must have power of two framesize

Out.ar(0,StereoConvolution2L.ar(input,kernel1, kernel2,t_trig,2048, 1, 0.5));

}).add

)

x = Synth(\conv_test, [\kernel1,b,\kernel2,c]);

// changing the buffer number:

x.set(\kernel1,d);

x.set(\t_trig,1); // after this trigger, the change will take effect.

x.set(\kernel2,d);

x.set(\t_trig,1); // after this trigger, the change will take effect.

d.zero;

40.do({ |it| d.set(20*it+10, 1); });// changing the buffers' contents

x.set(\t_trig,1); // after this trigger, the change will take effect.

x.set(\kernel1,b);

x.set(\t_trig,1); // after this trigger, the change will take effect.

x.free;