MantisBT - ardour
View Issue Details
0007692ardourbugspublic2018-11-28 08:302018-12-09 00:43
0007692: insert or drag plugin is not the same
Hi there
Tried MB5, Ardour 5, 32c.. Busdriver (Nomad) if first inserted to mixbus (stereo) freezes Ardour and MB. If inserted to tracks or utility buses it is OK. If dragged from a track, where it was inserted, to any mixbuses it is also OK. Aftre that I can insert in mixbuses without any freeze.
Seems inserting first to a mixbus or dragged and then insert any makes a difference as dragging first solves the issue. Can be always reproduced.
1. insert Busdriver to a mixbus = freeze
2. open session again
3. insert to track
4. drag it to a mixbus
5. insert into another mixbus
6. insert, drag as many anywhere you like it works
Found it in 32c first, John reproduced, told to report you Guys
No tags attached.
Issue History
2018-11-28 08:30tassyskNew Issue
2018-11-28 08:59johne53Note Added: 0020489
2018-11-28 09:00johne53Note Edited: 0020489bug_revision_view_page.php?bugnote_id=20489#r639
2018-11-29 09:06johne53Note Added: 0020493
2018-12-01 06:38johne53Note Added: 0020500
2018-12-04 07:04johne53Note Added: 0020508
2018-12-05 00:54johne53Note Added: 0020509
2018-12-06 11:17x42Note Added: 0020517
2018-12-07 01:47johne53Note Added: 0020520
2018-12-07 02:08sarahtaylorNote Added: 0020521
2018-12-07 03:53johne53Note Edited: 0020520bug_revision_view_page.php?bugnote_id=20520#r641
2018-12-07 03:56johne53Note Edited: 0020520bug_revision_view_page.php?bugnote_id=20520#r642
2018-12-07 04:00johne53Note Edited: 0020520bug_revision_view_page.php?bugnote_id=20520#r643
2018-12-07 04:01johne53Note Edited: 0020520bug_revision_view_page.php?bugnote_id=20520#r644
2018-12-08 07:54x42Note Deleted: 0020521
2018-12-08 08:41x42Note Added: 0020523
2018-12-09 00:42johne53Note Added: 0020524
2018-12-09 00:43johne53Note Edited: 0020524bug_revision_view_page.php?bugnote_id=20524#r646

2018-11-28 08:59   
(edited on: 2018-11-28 09:00)
FWIW a Debug build asserts at this line in 'PluginInsert::connect_and_run()':-

    assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);

(though I'm not sure what that's actually testing). Maybe the plugin is reporting the wrong number of channels?

2018-11-29 09:06   
After a bit more experimentation, I've realised that my situation is slightly different from Tassy's. If I open the Plugin Manager dialog, then I select the BusDriver plugin, I can drag & drop it to any channel (or bus) without any problems.

But if I use the Plugin Manager dialog normally (i.e. by clicking the 'Add' button, followed by 'Insert Plugins') Ardour will always crash - IF - there are no other instances of the plugin (in this session). It makes no difference whether I'm adding to a channel or bus. The crash occurs if I'm using the Plugin Manager dialog normally AND this is the first instance of the BusDriver plugin.
2018-12-01 06:38   
Tassy - try inserting 2 instances of the plugin - i.e. with no BusDriver plugins already loaded...

1) Open the Plugin Manager dialog
2) Select the BusDriver plugin
3) Press 'Add'
4) Press 'Add' again
5) Press 'Insert Plugins'

In my case, that seems to prevent the crash (although you get an extra plugin that you'll need to remove later).
2018-12-04 07:04   
The only thing I've been able to find is that when a plugin gets inserted, the code calls the function 'ProcessThread::get_noinplace_buffers()'. This ends up at a section which looks like this:-

    if (count != ChanCount::ZERO) {
        assert(sb->available() >= count);
        sb->set_count (count);
    } else {
        sb->set_count (sb->available());

Where 'sb->available())' effectively returns a pair of numbers. Whenever the insertion works correctly (for this particular plugin) the returned numbers are [4,2] - but whenever the crash occurs, those numbers get returned as [4,1].

Unfortunately I don't know what those numbers mean or how they get calculated (for example, does the plugin itself play some part in calculating them?)
2018-12-05 00:54   
I came across something interesting this morning...

Referring to my previous post, it seems that 'sb->set_count()' is setting up a count of the available PortSets. This gets used by BufferSet::attach_buffers() to attach buffers to the available ports - but there's an interesting note in BufferSet::attach_buffers() :-

   /** Set up this BufferSet so that its data structures mirror a PortSet's buffers.
    * This is quite expensive and not RT-safe, so it should not be called in a process context;
    * get_backend_port_addresses() will fill in a structure set up by this method.
    * XXX: this *is* called in a process context; I'm not sure quite what `should not' means above.

Could this explain why inserting the plugin by one method works okay but inserting it by the other method fails ?
2018-12-06 11:17   
re [4,2] Does the plugin have two MIDI inputs?

In Ardour5, Mixbus5, process buffers never shrink. If, at some point Ardour allocated 2 midi buffers, they'll always be available from then on as thread/process buffers for all threads (this behavior is due to change).

re. assert (inplace_bufs.count () >= natural_input_streams () + _configured_out)

That is the max possible permutation for plugins that don't support in-place processing (all VSTs) or when routing signals in a non-linear way.
Worst case we need to have sufficient buffers to provide all plugin-inputs with a buffer and at the same time be able to bypass the original signal "around" the plugin to all outputs. hence natural_input_streams + configured_out.
2018-12-07 01:47   
(edited on: 2018-12-07 04:01)
x42 wrote:
" re [4,2] Does the plugin have two MIDI inputs? "

No, it requires 0 x inputs and 1 x output (in fact, I think that might be the reason for the problem...)

When a plugin gets loaded we call the function 'Route::configure_processors_unlocked()'. It contains a 'for' loop which seems to calculate the requirement for audio channels and MIDI channels (keep in mind that this crash only happens when BusDriver gets loaded for the first time - AND - there are no other MIDI plugins loaded).

If I load the plugin normally (using the Plugin Manager dialog) what happens is that the calculation comes out as [4,1]. Later on in the process, I think this is getting interpreted as 4 x audio channels (2 x in, plus 2 x out) and 1 x MIDI channel (1 x in, but 0 x out). But this plugin doesn't require an input; it only requires an output. I think that's what's causing the problem. In fact to test this I tried loading a plugin which has the opposite requirement (1 x input, but 0 x outputs). In that case, the calculation also came out as [4,1].

Something else which might be a factor here is that my particular PC doesn't have any MIDI hardware. In that situation, Ardour seems to manufacture its own virtual MIDI channels, as and when needed - but AFAICT there's an assumption somewhere that if only 1 x channel is needed, it'll be an input. I suspect that a user with actual MIDI hardware would (probably?) never see this crash.

Over on the Mixbus forum I've contacted Tassy to ask if his PC also doesn't have any MIDI hardware.

[Edit...] FWIW ensuring that the MIDI channels always have an even number seems to fix the problem.

Towards the bottom of 'Route::configure_processors_unlocked()' we currently have these lines:-

    /* make sure we have sufficient scratch buffers to cope with the new processor
    _session.ensure_buffers (n_process_buffers ());

If I change them to this, the problem goes away...

    /* make sure we have sufficient scratch buffers to cope with the new processor
       configuration (also ensure that the midi buffers always have an even number)
    if (processor_max_streams.n_midi() % 2) {
        processor_max_streams.set_midi (processor_max_streams.n_midi() + 1);
    _session.ensure_buffers (n_process_buffers ());

I'm not sure if that'll screw up something else but it definitely fixes this particular crash.

2018-12-08 08:41   
That is odd issue. Do other generator plugins have the same issue?

When you hit that assert, could you print the streams?

 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);

"natural_input" should be [0,0], configured out is [2,0]. So inplace_bufs must be [0,0] or [1,0] for the assert to trigger. I don't yet see how that can happen, nor why MIDI would be relevant at all.

I tried, with test-signal (no inputs, 1 audio out) on a stereo-bus and Dummy backend without any MIDI i/o and cannot reproduce this. The plugin is replicated. This works fine for LV2 and Lua. Perhaps this is VST specific? I cannot easily test that.

ThreadBuffers::ensure_buffers() already forces MIDI buffers to be at least 1 (in Ardour5/Mixbus5). So we can't currently have zero MIDI buffers. However I'm about to remove that restriction since we vastly over-allocate buffers (VST MIDI buffers are 4MB per thread per channel for no good reason and we waste a few hundred MBs in total for nothing in BufferSet::get_vst_midi).
2018-12-09 00:42   
(edited on: 2018-12-09 00:43)
I don't seem to have test-signal, except as an unrelated python script somewhere (I'm guessing it should be a plugin?) but this got me confused:-

    x42 wrote:-
    "natural_input" should be [0,0], configured out is [2,0].


    ThreadBuffers::ensure_buffers() already forces MIDI buffers to be at least 1 "

I don't understand how you're seeing 0 for the 2nd value if there always needs to be at least 1 x MIDI buffer?? Anyway... these are the values I see here whenever the assertion triggers:-

    '_configured_out' is [2,1]
    the returned value from 'natural_input_streams()' is [2,1]
    the returned value from 'inplace_bufs.count()' is [4,1]

and if I apply my patch (from post #0020520) 'inplace_bufs.count()' will increase to [4,2], which the assertion accepts (i.e. it stops the crash).