MidiOut::sendMessageNow() doesn't work from Vst3

I’m attempting to output MIDI notes directly from the main thread using the following code snippet:

juce::MidiMessage midiMessageOn = juce::MidiMessage::noteOn(3, 60, (juce::uint8)64);
midiOutputDevice->sendMessageNow(midiMessageOn);

This code works flawlessly when running as a standalone application, but when used as a VST3 plugin in Ableton Live or within the JUCE Plugin Host, the MIDI messages are not sent out. There are no exceptions or errors thrown, and the sendMessageNow() function is being called without any issues.

I’m using Windows 10 and JUCE version 7.0.9. When debugging, I noticed that internal->sendMessageNow() successfully acquires a handle to the platform-specific Windows MIDI output and calls the output function on the first try. The MIDI device I’m using is loopMIDI.

I’ve searched the forums and it seems that others have successfully implemented similar functionality. Am I missing something here?

As a plugin you have no control over the MIDI outputs, those are controlled by the host.

To send MIDI out in a plugin, you need to fill the MidiBuffer you receive from the host in processBlock() with new messages that you generate.

Thanks for the quick response. So, I guess directly accessing certain hardware MIDI outputs from within a plugin isn’t possible at all, right?

I think I’ll end up writing two different versions of the MIDI output section, one for standalone and one for plugins.

I don’t know if it’s not possible at all - it’s possible that if you would, for example, run the program that sends MIDI output as another process and communicate the messages from the plugin into it, it might work.

However, you may run into all kinds of collisions with both the host and your host trying to touch the MIDI devices, so I guess it would work some of the time and with certain DAWs but not all the time.

A more native way to the way DAWs work is to let them handle the audio and MIDI devices and use the I/O specified in the VST3 format (MidiBuffer).

1 Like

Yeah, true, this sounds reasonable. I’ll stick to the MidiBuffer and work with the DAW’s output handling. This appears to be a safe bet.

That should be the safest bed for commercial plugins yes. If you are building something for yourself (or know the implications), you might be able to open a separate MidiOutput. Depending on if your plugin is sandboxed, I’d even give this a high rate of success. Then you can do what ever you want but you won’t (or not easily) get those MIDI events back into the DAW in any meaningful way.

Yeah, the thing that bothers me the most at the moment is that I’m not able to have multiple output channels from one Vst3 since certain IDEs (cough cough Ableton) combines everything into one channel. I was just thinking that it might be worth it to work on some kind of subprocess with some kind of API to recieve and play Midi notes. But it seems like too big of a project with too many pitfalls at the moment. Maybe I will just have to live with the limitaitons and find another way to work around them…

It is definitely possible. I’ve got direct MIDI output in a plugin (mainly for testing) and it works in various DAWs. I’m not recommending it as a releasable option, however. :wink:

1 Like

Are you doing this in a separate process? For me this just does not work (Windows 10, loopMIDI with Ableton or Juce Plugin Host). Maybe this is related to Windows, since sendMessageNow() uses a windows/platform specific class?

That’s why this is so confusing to me. I read several times about people successfully outputting Midi notes directly via sendMessageNow() from within a plugin and I was thinking that it’s weird that it just does not want to work for me.

Maybe at this point you need to A) share some code and B) get a MVP ready. Luckily with nice tha latter is very easy. Just create a new plugin, open a port in preparetoplay and send some random message in processBlock.

Good idea with the MVP. While creating a quick demonstration project, I think I got to the core of the problem, which relates to the order in which MIDI Output handles are acquired.

I can now reliably cause Ableton to crash if my plugin attempts to open an output port that is already enabled as an output port within Ableton before loading the plugin. Direct MIDI output actually works if the MIDI port is completely disabled within Ableton before the plugin is loaded. I experience undefined behavior when I enable the MIDI Output within Ableton after starting my plugin; sometimes this works, and sometimes it doesn’t.

So, it’s good to know that direct output is entirely possible, albeit with caution for testing purposes. However, as mentioned previously, it’s very risky since it easily clashes with the host, and that behavior is hard to predict.

Thanks everyone for the help!