Here's a how you can update the plugin host to handle midi out.
1. First you need to add some code to actually create the midi out connection so to say
In FilterGraph.cpp you add
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::midiOutputFilter), 0.25f, 0.9f);
in InternalFilters.cpp you add
{
AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode);
p.fillInPluginDescription (midiOutDesc);
}
and
if (desc.name == midiOutDesc.name)
return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode);
and
case midiInputFilter: return &midiInDesc;
in relevant places, I guess you'll see right away where to put these lines.
2. Some more updates
Add to the collection of privates of GraphEditorPanel.h
MidiOutput *midiOut;
Make GraphEditorPanel a ChangeListener i.e in GraphEditorPanel.h it should look like
class GraphEditorPanel : public Component, public ChangeListener
3. Add to GraphEditorPanel.cpp
void GraphDocumentComponent::changeListenerCallback (ChangeBroadcaster* source)
{
if (source == deviceManager)
{
midiOut = deviceManager->getDefaultMidiOutput();
if (midiOut)
midiOut->startBackgroundThread();
//else stop?
graphPlayer.setMidiOutput(midiOut);
}
}
and its declaration to GraphEditorPanel.h
4. Now add the line
changeListenerCallback (deviceManager);
somewhere in the constructor of GraphDocumentComponent. (GraphEditorPanel.h)
and put following at the to beginning of ~GraphDocumentComponent
if (midiOut)
midiOut->stopBackgroundThread();
5. Finally you need to update two juce files. Add
MidiOutput *midiOutput;
to the private parts :) of juce_AudioProcessorPlayer.h
Add
void AudioProcessorPlayer::setMidiOutput(MidiOutput *newMidiOutput)
{
if (midiOutput != newMidiOutput)
{
const ScopedLock sl (lock);
midiOutput = newMidiOutput;
}
}
to juce_AudioProcessorPlayer.cpp and corr declaration to juce_AudioProcessorPlayer.h
Now we've come to the part where midi output is actually taken from the AudioProcessorGraph.
In juce_AudioProcessorPlayer.cpp change
if (!processor->isSuspended())
{
processor->processBlock (buffer, incomingMidi);
return;
}
to
if (!processor->isSuspended())
{
processor->processBlock (buffer, incomingMidi);
MidiBuffer &midiBuffer ((dynamic_cast<AudioProcessorGraph *>(processor)) ->getCurrentMidiOutputBuffer());
if (!midiBuffer.isEmpty() && midiOutput)
midiOutput->sendBlockOfMessages(midiBuffer, Time::getMillisecondCounter(), getCurrentProcessor()->getSampleRate());
return;
}
6. And last add following line to the publics of juce_AudioProcessorGraph.h
MidiBuffer& getCurrentMidiOutputBuffer() { return currentMidiOutputBuffer; }
After building and starting the plugin host you should now have a midiout. Draw a connection between midi input and midi output. If you have selected a midiout device in the audiosettings (e.g Microsft GS Wavetable Synth in windows) you should now here a piano when playing on the midikeyboard. See the attached pic.
If you're more into copy & paste programming you could instead of modifying the two juce files create a "midiout processor" by subclassing juce_AudioProcessor. But I leave that as an excersise for the reader...
Good luck!