x42 / midifilter.lv2

LV2 plugins to filter midi events
https://x42-plugins.com/x42/x42-midifilter
GNU General Public License v2.0
70 stars 20 forks source link

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

Open 3hhh opened 1 year ago

3hhh commented 1 year ago

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.

x42 commented 1 year ago

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

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.

x42 commented 1 year ago

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.

3hhh commented 1 year ago

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.

x42 commented 1 year ago

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

3hhh commented 1 year ago

On 10/27/23 14:53, Robin Gareus wrote:

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

Yes, "not fast enough" only applies to mididings and "not easily usable for blocking tasks" to LV2 plugins. My brain mixed it up, sorry.

At least rtmidi seems to work with both speed & easy parallel execution according to my tests so far.

3hhh commented 5 months ago

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