Ardour / alsa / thread stack size / calf issue

I’ve been getting a crash on project load with the calf-0.90.3 limiter:

#0 calf_plugins::limiter_audio_module::process(unsigned int, unsigned int, unsigned int, unsigned int)
(this=0x87a5940, offset=, numsamples=256, inputs_mask=, outputs_mask=4294967295) at modules_limit.cpp:138
#1 0x00007f849e7af92a in calf_plugins::audio_module<calf_plugins::limiter_metadata>::process_slice(unsigned int, unsigned int) (this=0x87a5940, offset=0, end=4096) at ./calf/giface.h:625
#2 0x00007f849e77210d in calf_plugins::lv2_instance::run(unsigned int, bool) (this=0x872d950, SampleCount=4096, has_simulate_stereo_input_flag=) at lv2wrap.cpp:164
#3 0x00007f8503c94675 in lilv_instance_run(LilvInstance*, uint32_t) (instance=0x87a6840, sample_count=4096) at /home/blair/software/lilv/0.24.0/include/lilv-0/lilv/lilv.h:1694
#4 0x00007f8503ca477b in ARDOUR::LV2Plugin::run(unsigned int, bool) (this=0x8775050, nframes=4096, sync_work=false) at …/libs/ardour/lv2_plugin.cc:3088

  • snip -

I assume the plugin processing thread is created via AlsaAudioBackend::create_process_thread, in which we have a fixed stacksize:

size_t stacksize = 100000;

I’m using the alsa backend without running under any special privileges, ie. no realtime threads. I don’t think this will make a difference tho, the stacksize is used in both pbd_realtime_pthread_create and pthread_create code paths.

Now in calf’s modules_limit process() we have:

STACKALLOC(float, fickdich, limiter.overall_buffer_size);

I am using a generous amount of buffer samples (4096) as I’m mixing an old song at 96KHz (side note: I’ve since reformed and will stick to 48KHz). This eventually turns into a generous limiter buffer too, from gdb I see the value for limiter.overall_buffer_size is 76802, so this allocates 76802 floats or 76802 * sizeof(float) > 100000 bytes on the stack.

So, I assume this overflow is a segfault at the best of times and silent corruption otherwise.

I don’t know enough about the realtime aspect here tho, and whether there are issues increasing ardour’s thread stack size in that case. Maybe 640K would be enough for everybody? I can’t imagine it would be a problem on a machine with gigs of ram. I’m not sure if this is an ardour issue or a calf issue, let me know if you want this as an ardour ticket.

I do see pthread_utils.cc the following comment around a 500000 byte stack size default:

// set default stack size to sensible default for memlocking

I rebuilt ardour (5.12.0) with 512 * 1024 stack size for AlsaAudioBackend and am no longer experiencing the crash.

Now to debug the calf GUIs in this project flashing up momentarily and then closing with this in the log:

CALF DEBUG: instance 0x2cb1c40 data 0x8aea520
CALF DEBUG: calf 0x7f9809d70410 cpi 0x7f980958a1d0

Oh yeah, plug for the half-mixed call-and-response song:

Blair

calf plugins are notoriously unreliable and responsible for the most crash reports that we receive for Ardour on GNU/Linux. And apart from that the DSP of most calf effects is usually substandard.

It seems that calf limiter uses a FIFO for a lookahead buffer and uses the stack for this.

I don’t even know where to begin explaining how wrong it is.
If this is used to calculate the gain factor, it’ll accumulate drift. That’s something you definitely don’t want in a limiter. Also using the stack to delay data as FIFO is wrong: Stack pointers are LIFO. Pushing and popping this much data from the stack is expensive and should not be done regularly in the realtime thread either, which is why Ardour limits it.

We advise to avoid using calf-plugins, one of many other threads on this subject

Until you add a few more calf plugins and need a deeper stack…
This is at best a work-around, that doesn’t solve the underlying issue and likely makes things worse.

2 Likes

Thanks x42, I’ll migrate away from calf-plugins. It’s a shame tho, the UI is so polished for an open-source package that I expected the underlying code to be solid too.

I just built lsp-plugins, and it looks pretty nice, and it seems well-regarded in these forums. I keep it basic, EQs and compressors mainly. Are there any other open-source DSP plugin packages people are willing to endorse?

Would you take the time to explain the ‘deeper stack’ comment, my understanding there is that we aren’t recursing plugin process() calls, but instead ardour is traversing the graph to schedule the various plugin instance process calls, so thread stacksize should be the max over the individual plugin stack usage.

Blair

It’s one time additive, the stack alloc reserves space for as long as the plugin is loaded.
Anyway, I’m glad that you managed to help yourself and work around the issue.

Looks can be deceiving, and yes it’s a pity. The GUI sometimes also shows things that does not match what actually happens (more on How to achieve multiband processing?), there’s zipper-noise when automating the EQ… etc; the list goes on.

On the upside frustrated devs “trying to fix calf” is what eventually lead to other plugin-bundles to show up. zam-plugins and x42-plugins are examples of that.

As for a free/libre peak-limiter I can offer https://x42-plugins.com/x42/x42-limiter (should be packaged on most modern distros). Prior to that I used to use swh’s no frills “Fast Lookahead Limiter”.

The LSP plugins are great, too. Usually very robust and work reliably. Personally I think they have too many controls and require too many knobs to be twiddled, but that’s only a matter of taste. From a technical POV they’re good quality.

Invada Studio Plugins

1 Like