x42 / midifilter.lv2

LV2 plugins to filter midi events

Home Page:https://x42-plugins.com/x42/x42-midifilter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Q: Is `forge_midimessage()` thread-safe?

3hhh opened this issue · comments

commented

I tried to call forge_midimessage() from a Linux background pthread, but noticed no effect / the Midi notes never reached Ardour.

I confirmed that the thread was running, receiving & processing the Midi notes from the foreground thread.

So is forge_midimessage() possibly not thread-safe?
If not, can the Ardour lua plugins create Midi messages from background threads instead?

If I understand it correctly, I could also use the Midi timestamps sent by the Midi master for timing, but that doesn't suit my needs as these only come in every 10ms or so, which is above the resolution (1-5ms) I need. So I tried background threading.

All plugin processing, this must be called in the realtime-context of the host.
Furthermore the I/O buffers are only valid during run().

Custom threads in plugins are highly problematic and to be avoided

  • the plugin cannot know the thread priority to use
  • synchronization with the host's realtime context is hard to get right
    • it must be lock-free during realtime processing
    • it needs to be synchronous during offline processing
  • background threads interfere with host processing in parallel.

If you really need to do work in the background, https://lv2plug.in/ns/ext/worker might help.

There are very very few plugins that use threads.

If not, can the Ardour lua plugins create Midi messages from background threads instead?

Nope. Same rules apply, besides Lua DSP scripts cannot even start threads.

See also https://lv2plug.in/c/html/group__lv2core.html#a4d904937a1bd27cb5f5478f95c708b16 Notably:

This pointer must be stored by the plugin instance and used to read/write data when run() is called.
Data present at the time of the connect_port() call MUST NOT be considered meaningful.

hence you can only call forge_midimessage() from inside run().

Also read the "Threading Rulers" at http://lv2plug.in/ns/lv2core

Similar rules apply to all plugin standards.

commented

Thanks for the clarifications. They are much appreciated!

The original goal was to implement a generic MIDI cross-talk cancellation algorithm mostly intended for MIDI drum triggers.

I already tried mididings, but that didn't perform well enough; now LV2 plugins apparently aren't fast enough for MIDI either (without doing rather uncommon things as you pointed out)... I guess I might try to implement my own simple MIDI router with python3-rtmidi next.

How can plugins not be fast enough? They run every process cycle.
I pointed out that you cannot use threads, which is entirely unrelated.

commented
commented

For anyone needing similar code - I ended up with this: https://github.com/3hhh/xtalk