midir
midir copied to clipboard
Add example for multithread
Hi! I'm having a hard time using midir in a threaded context. I'm using threads to model polyphony, as is typical in many synth implementations I've seen. I specifically don't know what is safe to share using Arc/Mutex. If nothing, I'm not sure how to be confident that I spin up a connection to the same port on a new thread. It looks like I can't share MidiOutputPorts between different instances of MidiOutput.
Or is it better to not use threading at all, and just keep a single thread, and handle scheduling of events?
Thanks for any insight!
I specifically don't know what is safe to share using Arc/Mutex.
@hughrawlinson You should not need to worry about that. If your multi-threaded code compiles (and doesn't make use of unsafe
), it is guaranteed by the library to be safe.
If you have problems getting your code to compile in multiple threads you can use the following strategy:
- If an operation on an object consumes
&self
and the object isSync
wrap your object it in anArc<_>
. - If an operation on an object consumes
&mut self
or the object isn'tSync
wrap your object in anArc<Mutex<_>>
As a reference you can check out my synthesizer project https://crates.io/crates/microwave.
Is there any question still open? Otherwise I'd close this issue.
Thanks for getting back to me. That clarifies things a bit - although, I'm not sure exactly what the library guarantees to be safe. One remaining question is:
If I get a MidiOutputPort on the main thread, and pass it into another thread in the manner you described, and then I unplug the midi device, does that reference break somehow? If so, how do I catch that? Or is that not the kind of guarantee that the library makes?
I also think it would be good to have an example of this - either a specific contrived example like the other examples, or perhaps a link out to the crate you mentioned?
Thanks! 😄
If I get a MidiOutputPort on the main thread, and pass it into another thread in the manner you described, and then ....
@hughrawlinson yeah, you should be able to safely run it on another thread and pass the messages somewhere else. I did a small example of this with tungstenite-rs
server: https://github.com/snapview/tungstenite-rs/issues/122#issuecomment-733396645 . I am more familiar with functional languages than traditional systems programming, so if you have that background too it might help.
To be more specific I am shoveling the midi messages from midir
to tungstenite, and everything works smoothly, no crashes etc. It uses all of 4MB
of RAM when it's running and I'm just testing locally.
If I unplug the midi device, does that reference break somehow?
It's not currently possible to detect disconnected devices. In theory this can be added (at least on Linux). See #35 for more on unplugging the device.