diff --git a/extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp b/extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp index ac887559ff..b4b4cf5555 100644 --- a/extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp +++ b/extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp @@ -357,6 +357,11 @@ InternalPluginFormat::InternalPluginFormat() AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); p.fillInPluginDescription (midiInDesc); } + + { + AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); + p.fillInPluginDescription (midiOutDesc); + } } std::unique_ptr InternalPluginFormat::createInstance (const String& name) @@ -364,6 +369,7 @@ std::unique_ptr InternalPluginFormat::createInstance (const if (name == audioOutDesc.name) return std::make_unique (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); if (name == audioInDesc.name) return std::make_unique (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); if (name == midiInDesc.name) return std::make_unique (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); + if (name == midiOutDesc.name) return std::make_unique (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); if (name == SineWaveSynth::getIdentifier()) return std::make_unique (SineWaveSynth::getPluginDescription()); if (name == ReverbPlugin::getIdentifier()) return std::make_unique (ReverbPlugin::getPluginDescription()); @@ -388,7 +394,6 @@ bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const P void InternalPluginFormat::getAllTypes (Array& results) { - results.add (audioInDesc, audioOutDesc, midiInDesc, - SineWaveSynth::getPluginDescription(), - ReverbPlugin::getPluginDescription()); + results.add (audioInDesc, audioOutDesc, midiInDesc, midiOutDesc, + SineWaveSynth::getPluginDescription(), ReverbPlugin::getPluginDescription()); } diff --git a/extras/AudioPluginHost/Source/Plugins/InternalPlugins.h b/extras/AudioPluginHost/Source/Plugins/InternalPlugins.h index 82baf6e77b..b5282a09e6 100644 --- a/extras/AudioPluginHost/Source/Plugins/InternalPlugins.h +++ b/extras/AudioPluginHost/Source/Plugins/InternalPlugins.h @@ -41,7 +41,7 @@ public: ~InternalPluginFormat() override {} //============================================================================== - PluginDescription audioInDesc, audioOutDesc, midiInDesc; + PluginDescription audioInDesc, audioOutDesc, midiInDesc, midiOutDesc; void getAllTypes (Array&); //============================================================================== diff --git a/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp b/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp index 082911e504..416c9b4bb0 100644 --- a/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp +++ b/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp @@ -202,11 +202,13 @@ void PluginGraph::newDocument() addPlugin (internalFormat.audioInDesc, { 0.5, 0.1 }); addPlugin (internalFormat.midiInDesc, { 0.25, 0.1 }); addPlugin (internalFormat.audioOutDesc, { 0.5, 0.9 }); + addPlugin (internalFormat.midiOutDesc, { 0.25, 0.9 }); - MessageManager::callAsync ([this] () { + MessageManager::callAsync ([this] + { setChangedFlag (false); graph.addChangeListener (this); - } ); + }); } Result PluginGraph::loadDocument (const File& file) diff --git a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp index a74497f6d9..d6d2fa87a7 100644 --- a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp +++ b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp @@ -1167,10 +1167,13 @@ GraphDocumentComponent::GraphDocumentComponent (AudioPluginFormatManager& fm, deviceManager.addChangeListener (graphPanel.get()); deviceManager.addAudioCallback (&graphPlayer); deviceManager.addMidiInputDeviceCallback ({}, &graphPlayer.getMidiMessageCollector()); + deviceManager.addChangeListener (this); } void GraphDocumentComponent::init() { + updateMidiOutput(); + graphPanel.reset (new GraphEditorPanel (*graph)); addAndMakeVisible (graphPanel.get()); graphPlayer.setProcessor (&graph->graph); @@ -1213,6 +1216,9 @@ void GraphDocumentComponent::init() GraphDocumentComponent::~GraphDocumentComponent() { + if (midiOutput != nullptr) + midiOutput->stopBackgroundThread(); + releaseGraph(); keyState.removeListener (&graphPlayer.getMidiMessageCollector()); @@ -1326,3 +1332,23 @@ bool GraphDocumentComponent::closeAnyOpenPluginWindows() { return graphPanel->graph.closeAnyOpenPluginWindows(); } + +void GraphDocumentComponent::changeListenerCallback (ChangeBroadcaster*) +{ + updateMidiOutput(); +} + +void GraphDocumentComponent::updateMidiOutput() +{ + auto* defaultMidiOutput = deviceManager.getDefaultMidiOutput(); + + if (midiOutput != defaultMidiOutput) + { + midiOutput = defaultMidiOutput; + + if (midiOutput != nullptr) + midiOutput->startBackgroundThread(); + + graphPlayer.setMidiOutput (midiOutput); + } +} diff --git a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h index 2796b75046..f5a5a6cc38 100644 --- a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h +++ b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h @@ -100,7 +100,8 @@ private: */ class GraphDocumentComponent : public Component, public DragAndDropTarget, - public DragAndDropContainer + public DragAndDropContainer, + private ChangeListener { public: GraphDocumentComponent (AudioPluginFormatManager& formatManager, @@ -142,6 +143,7 @@ private: AudioProcessorPlayer graphPlayer; MidiKeyboardState keyState; + MidiOutput* midiOutput = nullptr; struct TooltipBar; std::unique_ptr statusBar; @@ -160,8 +162,11 @@ private: SidePanel* lastOpenedSidePanel = nullptr; //============================================================================== + void changeListenerCallback (ChangeBroadcaster*) override; + void init(); void checkAvailableWidth(); + void updateMidiOutput(); //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GraphDocumentComponent)