Very simple synthdef bricks coreaudio (due to BPF mce?)

hey folks—i’ve been trying to use supercollider for some granular synthesis, but while i was experimenting with adding a per-grain filter bank, i managed to deterministically brick coreaudio on my mac. specifically, after instantiating my granulator synth, my computer would no longer play audio (even if i stopped and killed scsynth) until i manually kill -9’d coreaudio and forced it to restart. (if i had audio already playing, it would cut off as soon as the synth started running.)

this issue seems to be specific to multi-channel expansion of a BPF UGen; a single-channel BPF doesn’t cause the issue, nor does replacing BPF with, e.g., RLPF.

update: i did more testing, and the mce is not necessary to repro, but the arrayed controls are. BPF can handle unarrayed NamedControls, literal integers, and arrays of integers as its arguments; it just can’t handle arrayed controls. the rate of the control doesn’t seem to matter.

i winnowed my code down to this relatively compact test case:

(
s.waitForBoot({

SynthDef(\testcase, { |
  out = 0,
  gate = 1,
  buf,
  pan = 0.0,
  amp = 0.5
|
  // fx controls
  var fbfreqs = \fbfreqs.kr({ |i| i * 440 } ! 2); // filter bank frequencies
  var fbrqs = \fbrqs.kr(1.0 ! 2);     // filter bank reciprocal-Q's

  var trig = Impulse.kr(10);
  var srate = BufRateScale.ir(buf);
  var grains = TGrains.ar(1, trig, buf, srate, 0.5, 0.5, 0.0, 1.0, 4);

  var fx = Mix.new(BPF.ar(grains, fbfreqs, fbrqs, 0.5));
  var env = Env.adsr.kr(2, gate);

  var spatial = Pan2.ar(fx * env * amp, pan);
  Out.ar(0, spatial);
}).add;

~path = "/Users/me/path/to/some-nontrivial-length-audio.WAV";
~noise = Buffer.readChannel(s, ~path, channels: [0]);

s.sync;

Synth(\testcase, [buf: ~noise]);

});
)

am i doing something obviously wrong? if not, why does this hose coreaudio?

my specs:

  • 2019 macbook pro (intel), OS 12.6
  • SC 3.12.2 (7c4c983)

Do not put a zero frequency into BPF.

i here is 0, then 1.

Try (i + 1) * 440.

hjh

lol i’m dumb.

that being affirmed—i’m not surprised BPF fails with a 0 frequency, but why does the coreaudio failure persist beyond the lifetime of the scsynth server?

I imagine scsynth was still running in the background and you had DC offset in the signal. basically, anything added to an infinite offset (or an offset above 1) is above 1, so you get no audio, as the output is slammed up against the output limit of -1/1.

Sam

BPF at freq 0 producing a DC offset seems plausible, but scsynth definitely is no longer running; i stop audio and then kill the server and have confirmed with ps that no scsynth processes are still live.

the persistent coreaudio failure is why i didn’t second-guess my code—it seems to me that scsynth should not affect the audio driver once it terminates.

IIRC coreaudio does weird things when it receives a NaN or infinity. I thought this was fixed with the safety clipper in 3.12 though.

Do either of { DC.ar(0)/DC.ar(0) }.play and { DC.ar(1)/DC.ar(0) }.play also repro the issue? In that case there’s an omission in the safety clipper and I can file a bug.

ah, thanks nathan—both of those do in fact repro the issue (with only my left speaker of course).

when i was looking into this late last night i stumbled on Safety and thought it should help avoid this problem, and therefore this must be something specific to BPF… well, the more you know!

Thanks for testing. I’ve filed an issue here and if I have time I’ll try to fix it soon. Safety clipper should also filter out NaNs and infinities · Issue #6018 · supercollider/supercollider · GitHub

1 Like