Convolution inside a feedback-delay network

Hi!

I would like to insert a convolution in the middle of a feedback delay network, however the server is crashing every time I run the synth.

I am using IRs from Echothief which have something like 32855 samples at 44100Hz.

It only works when I used a fixed kernel (which is the “proper” thing to do, but I also would like to try a moving one) with a short impulse response (2048 samples, from the example page ofConvolution2). When I use a longer impulse response it crashes. I assume this is due to the amount of memory allocation (maximum of s.options.memSize_(2**20) on Windows 11).

Is there a way to execute this idea?


s.options.memSize_(2**20);
s.reboot;

~underpass = Buffer.readChannel(s,"C:/Downloads/EchoThiefImpulseResponseLibrary/EchoThiefImpulseResponseLibrary/Underpasses/TelephoneWash.wav", channels: [0]);
~underpass.play;


(
SynthDef(\conv, {
	var source, local;
	
	source = Decay.ar(Impulse.ar(0.3), 0.1) * WhiteNoise.ar(0.2);
	local = LocalIn.ar(2) + [source, 0]; // read feedback, add to source
	local = DelayN.ar(local, 0.2, 0.2); // delay sound
	
	// fixed Kernel
	//local = Convolution2.ar(local, ~underpass, 1, BufFrames.ir(~underpass), 0.5);
	// moving Kernel
	local = Convolution.ar(local, PlayBuf.ar(1, ~underpass, BufRateScale.ir(~underpass),loop: 1.0), 1, BufFrames.ir(~underpass), 0.5);

	// reverse channels to give ping pong effect, apply decay factor
	LocalOut.ar(local.reverse * 0.5);
	
	local
}).add;
)
Synth(\conv)

Use PartConv for longer impulses. see:
https://doc.sccode.org/Classes/PartConv.html
Best,
Paul

2 Likes

You could also try to implement that idea by using PV ugens and spectral multiplication (PV_Mul). In any case, you’d get a lot of delay in the feedback loop in addition to the minimum delay – that equals the duration of the control block – plus the extra delay you’re introducing via DelayN. The delay of PV ugens is window size minus control block duration, for the convolution ugens that use FFT it’s probably the same but I never checked.
If I’d experiment which such a setup, which sounds interesting idea to me, I’d rather start with PV ugens as you can then easily extend the concept with other spectral modifications.

1 Like

From the docs on Convolution:

Size of FFT frame, must be a power of two (512, 1024, 2048, 4096 are standard choices). Convolution uses twice this number internally. Note that the convolution gets progressively more expensive to run for higher powers! The maximum value you can use is 2^16=16384. (This upper limit is half of “SC_FFT_MAXSIZE” defined in the SC source code.) Larger convolutions than this can be done using PartConv.

1 Like

Thanks a lot for all the answers.

Sorry, I’ve missed that basic thing under my nose.

Looking at include/common/SC_fftlib.h I saw

#define SC_FFT_MINSIZE 8
#define SC_FFT_LOG2_MINSIZE 3
#define SC_FFT_MAXSIZE 32768
#define SC_FFT_LOG2_MAXSIZE 15

Therefore, can I increase SC_FFT_MAXSIZE to a bigger value (e.g. 32768*2)? and then recompile it?
Does this make any sense? Would it cause problems like latency or so?

I am not understanding exactly why it is crashing, because it does not trow a memory allocation log. Is this crash exactly associated with memory allocation or can I solve it with the maximum number of wired buffers?

No you should use partConv. Convolution is very slow with big kernels, partconv is design to speed things up.

It is a bug that it crashed though. It should give you an error somewhere.

1 Like