From c54b36c3ffff4c9ef4df3f7089962794e71096e4 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 6 Aug 2020 20:30:04 +0200 Subject: [PATCH] AU: only set render callbacks for connected busses This fixes an issue with Renoise Redux. The plugin reports the following: Reported Channel Capabilities (explicit): [2, 2] [1, 2] [0, 2] When it is added to an Arodur MIDI track, the 0 in, 2 output variant is chosen, since Ardour MIDI tracks don't have audio by default. However the render callback was set uncondionally for all busses. This lead to issues with this specific plugin. --- libs/ardour/audio_unit.cc | 40 +++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index 699e7090c4..51a06a37ea 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -660,19 +660,6 @@ AUPlugin::init () } } - for (size_t i = 0; i < input_elements; ++i) { - /* setup render callback: the plugin calls this to get input data */ - AURenderCallbackStruct renderCallbackInfo; - renderCallbackInfo.inputProc = _render_callback; - renderCallbackInfo.inputProcRefCon = this; - DEBUG_TRACE (DEBUG::AudioUnits, "set render callback in input scope\n"); - if ((err = unit->SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, - i, (void*) &renderCallbackInfo, sizeof(renderCallbackInfo))) != 0) { - error << string_compose (_("cannot install render callback (err = %1)"), err) << endmsg; - throw failed_constructor(); - } - } - /* tell the plugin about tempo/meter/transport callbacks in case it wants them */ HostCallbackInfo info; @@ -1149,6 +1136,11 @@ AUPlugin::configure_io (ChanCount in, ChanCount out) } for (size_t i = 0; i < input_elements; ++i) { unit->Reset (kAudioUnitScope_Input, i); + /* remove any input callbacks */ + AURenderCallbackStruct renderCallbackInfo; + renderCallbackInfo.inputProc = 0; + renderCallbackInfo.inputProcRefCon = 0; + unit->SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, i, (void*) &renderCallbackInfo, sizeof(renderCallbackInfo)); } /* now assign the channels to available busses */ @@ -1212,6 +1204,19 @@ AUPlugin::configure_io (ChanCount in, ChanCount out) } } + for (size_t i = 0; used_in > 0 && i < configured_input_busses; ++i) { + /* setup render callback: the plugin calls this to get input data */ + AURenderCallbackStruct renderCallbackInfo; + renderCallbackInfo.inputProc = _render_callback; + renderCallbackInfo.inputProcRefCon = this; + DEBUG_TRACE (DEBUG::AudioUnits, "set render callback in input scope\n"); + OSErr err; + if ((err = unit->SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, + i, (void*) &renderCallbackInfo, sizeof(renderCallbackInfo))) != 0) { + error << string_compose (_("cannot install render callback (err = %1)"), err) << endmsg; + } + } + free (buffers); buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) + used_out * sizeof(::AudioBuffer)); @@ -1276,6 +1281,13 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha vector > io_configs = pinfo->cache.io_configs; +#if 0 + printf ("AU I/O Initial Config list for '%s' (%zu) n_in-bus: %d n_out-bus: %d\n", name(), io_configs.size(), input_elements, output_elements); + for (vector >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) { + printf ("- I/O %d / %d\n", i->first, i->second); + } +#endif + if (input_elements > 1) { const vector >& ioc (pinfo->cache.io_configs); for (vector >::const_iterator i = ioc.begin(); i != ioc.end(); ++i) { @@ -1325,7 +1337,7 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha name(), io_configs.size(), in, out)); #if 0 - printf ("AU I/O Configs %s %d\n", name(), io_configs.size()); + printf ("AU I/O Config list for '%s' (%zu)\n", name(), io_configs.size()); for (vector >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) { printf ("- I/O %d / %d\n", i->first, i->second); }