I’ve just had a few issues with a patch I’m working on. I’ve opened an issue here, but after testing a bit more, I think it might actually be a problem with my actual code rather than a bug, so I thought I’d ask for feedback. Basically it’s a big reverb patch, and my very beginnery c++ chops lead me to wonder if I’m using too much memory, or using it poorly.
The error is:
munmap_chunk(): invalid pointer
Server ‘localhost’ exited with exit code 0.
server ‘localhost’ disconnected shared memory interface
This has turned up twice when I’ve updated the three synths (not every time though). Also, instantiating the reverb synth itself causes the server to quit instantly. Code is below, I’d love any feedback on this issue as it’s part of a major project and memory has been something I’ve been worried about anyway.
(
SynthDef(\hs, {
|feedback = -3, scale = 1, amp = -20|
var input, output;
var early, late;
var earlyTimes, lateTimes;
var fb, tank, taps, outputDelays;
var bands;
var cd;
// input
input = In.ar(0, 2); // this is for testing, use SoundIn for performance
input = input.sum;
// early reflections - series
early = input;
earlyTimes = [142, 107, 379, 277] / 29761;
4.do { |i| early = AllpassC.ar(early, 0.5, earlyTimes[i], 1) }; // this may be worth experimenting with - AbsAllpass instead?
// mix signal with feedback
fb = LocalIn.ar(2);
late = [early + fb[0], early + fb[1]] / 2; // maybe unnecessary to divide by two here because there will be gain control later on
// split signal into bands w Linkwitz-Riley
// <75, 75 - 180, 180 - 700, 700 - 2.5k, 2.5k>
bands = Array.newClear(5);
bands[0] = LPF.ar(LPF.ar(late, 75), 75);
bands[1] = HPF.ar(HPF.ar(late, 75), 75);
bands[1] = LPF.ar(LPF.ar(bands[1], 180), 180);
bands[2] = HPF.ar(HPF.ar(late, 180), 180);
bands[2] = LPF.ar(LPF.ar(bands[2], 700), 700);
bands[3] = HPF.ar(HPF.ar(late, 700), 700);
bands[3] = LPF.ar(LPF.ar(bands[3], 2500), 2500);
bands[4] = HPF.ar(HPF.ar(late, 2500), 2500);
// reverb tank function
taps = List.new;
tank = {
|in, allpassTimes = #[], decayTimes = #[], delayTimes = #[], fbIndex = 0, tapsIndex = 0|
var sig;
sig = AllpassC.ar(in, 0.1, allpassTimes[0] * scale, decayTimes[0]);
taps.add(sig);
sig = DelayC.ar(sig, 0.1, delayTimes[0]);
sig = LPF.ar(sig, 9000);
taps.add(sig);
sig = AllpassC.ar(sig, 0.1, allpassTimes[1] * scale, decayTimes[1]);
sig = DelayC.ar(sig, 0.1, delayTimes[1] - ControlDur.ir);
taps.add(sig);
fb[fbIndex] = fb[fbIndex] + sig;
};
// band 0, loops 0 + 1;
tank.(bands[0][0], allpassTimes: [0.022579, 0.149625], decayTimes: [11.8, 11.8], delayTimes: [0.060481, 0.124995], fbIndex: 0);
tank.(bands[0][1], allpassTimes: [0.030509, 0.141696], decayTimes: [11.8, 11.8], delayTimes: [0.089244, 0.10628], fbIndex: 1);
// band 1 - these times are based off the others and scaled by various powers
tank.(bands[1][0], allpassTimes: [0.023452, 0.152494], decayTimes: [12.8, 12.8], delayTimes: [0.062202, 0.127622], fbIndex: 0);
tank.(bands[1][1], allpassTimes: [0.031593, 0.144491], decayTimes: [12.8, 12.8], delayTimes: [0.091427, 0.108689], fbIndex: 1);
// band 2
tank.(bands[2][0], allpassTimes: [0.033291, 0.148789], decayTimes: [10.7, 10.7], delayTimes: [0.094801, 0.112406], fbIndex: 0);
tank.(bands[2][1], allpassTimes: [0.024824, 0.156902], decayTimes: [10.7, 10.7], delayTimes: [0.06487, 0.131665], fbIndex: 1);
// band 3
tank.(bands[3][0], allpassTimes: [0.03293, 0.14789], decayTimes: [9.4, 9.4], delayTimes: [0.094094, 0.111627], fbIndex: 0);
tank.(bands[3][1], allpassTimes: [0.02453, 0.155981], decayTimes: [9.4, 9.4], delayTimes: [0.06431, 0.1308197], fbIndex: 1);
// band 4
tank.(bands[4][0], allpassTimes: [0.024073, 0.1545067], decayTimes: [6.3, 6.3], delayTimes: [0.06341843, 0.129467], fbIndex: 0);
tank.(bands[4][1], allpassTimes: [0.032363, 0.146452], decayTimes: [6.3, 6.3], delayTimes: [0.092964, 0.110383], fbIndex: 1);
// feedback signal
fb = LeakDC.ar(fb);
fb = LPF.ar(fb, 14000);
fb = Limiter.ar(fb);
fb = fb * feedback.dbamp;
LocalOut.ar(fb);
// output processing
outputDelays = Array.newClear(6);
6.do { |i| outputDelays[i] = taps[i] + taps[i+5] + taps[i+11] + taps[i+17] + taps[i+23] }; // 6 taps from 5 signals
output = [[
DelayC.ar(outputDelays[0], 0.1, 0.008937),
DelayC.ar(outputDelays[0], 1, 0.999294),
DelayC.ar(outputDelays[1], 0.1, 0.064279).neg,
DelayC.ar(outputDelays[2], 0.1, 0.067068),
DelayC.ar(outputDelays[3], 0.1, 0.066866).neg,
DelayC.ar(outputDelays[4], 0.1, 0.006283).neg,
DelayC.ar(outputDelays[5], 0.1, 0.035819).neg
].sum,
[
DelayC.ar(outputDelays[3], 0.1, 0.011861),
DelayC.ar(outputDelays[3], 1, 0.121871),
DelayC.ar(outputDelays[4], 0.1, 0.041262).neg,
DelayC.ar(outputDelays[5], 0.1, 0.089816),
DelayC.ar(outputDelays[0], 0.1, 0.070932).neg,
DelayC.ar(outputDelays[1], 0.1, 0.011256).neg,
DelayC.ar(outputDelays[2], 0.1, 0.004066).neg
].sum
];
output = output * amp.dbamp;
Out.ar(0, output);
}).add;
SynthDef(\test, {
var sig, env;
env = Env.perc(0.01, 0.13).ar(Done.freeSelf);
sig = Saw.ar(XLine.kr(1000, 100, 0.11));
sig = sig ! 2 * -10.dbamp;
Out.ar(0, sig);
}).add;
SynthDef(\kick, {
var sig, env;
env = Env.perc(0, 0.14).ar(Done.freeSelf);
sig = SinOsc.ar(57 * (1 + Env.perc(0, 0.14, 22, -25).ar));
sig = sig + (BPF.ar(PinkNoise.ar * -10.dbamp, 779));
sig = (sig * 1.4).tanh * env;
sig = sig ! 2 * -10.dbamp;
Out.ar(0, sig);
}).add;
)