diff --git a/extras/Projucer/Source/Project/jucer_Project.cpp b/extras/Projucer/Source/Project/jucer_Project.cpp index 0c9ab440a8..489e5ab137 100644 --- a/extras/Projucer/Source/Project/jucer_Project.cpp +++ b/extras/Projucer/Source/Project/jucer_Project.cpp @@ -266,6 +266,9 @@ void Project::initialiseAudioPluginValues() pluginVST3CategoryValue.referTo (projectRoot, Ids::pluginVST3Category, getUndoManager(), getDefaultVST3Categories(), ","); pluginRTASCategoryValue.referTo (projectRoot, Ids::pluginRTASCategory, getUndoManager(), getDefaultRTASCategories(), ","); pluginAAXCategoryValue.referTo (projectRoot, Ids::pluginAAXCategory, getUndoManager(), getDefaultAAXCategories(), ","); + + pluginVSTNumMidiInputsValue.referTo (projectRoot, Ids::pluginVSTNumMidiInputs, getUndoManager(), 16); + pluginVSTNumMidiOutputsValue.referTo (projectRoot, Ids::pluginVSTNumMidiOutputs, getUndoManager(), 16); } void Project::updateOldStyleConfigList() @@ -1089,6 +1092,25 @@ void Project::createAudioPluginPropertyEditors (PropertyListBuilder& props) "Check this box if your plug-in is sandbox safe. A sand-box safe plug-in is loaded in a restricted path and can only access it's own bundle resources and " "the Music folder. Your plug-in must be able to deal with this. Newer versions of GarageBand require this to be enabled."); + { + Array varChoices; + StringArray stringChoices; + + for (int i = 1; i <= 16; ++i) + { + varChoices.add (i); + stringChoices.add (String (i)); + } + + props.add (new ChoicePropertyComponentWithEnablement (pluginVSTNumMidiInputsValue, pluginCharacteristicsValue, Ids::pluginWantsMidiIn, + "Plugin VST Num MIDI Inputs", stringChoices, varChoices), + "For VST and VST3 plug-ins that accept MIDI, this allows you to configure the number of inputs."); + + props.add (new ChoicePropertyComponentWithEnablement (pluginVSTNumMidiOutputsValue, pluginCharacteristicsValue, Ids::pluginProducesMidiOut, + "Plugin VST Num MIDI Outputs", stringChoices, varChoices), + "For VST and VST3 plug-ins that produce MIDI, this allows you to configure the number of outputs."); + } + { Array vst3CategoryVars; diff --git a/extras/Projucer/Source/Project/jucer_Project.h b/extras/Projucer/Source/Project/jucer_Project.h index 887eed09a0..ed96df9b04 100644 --- a/extras/Projucer/Source/Project/jucer_Project.h +++ b/extras/Projucer/Source/Project/jucer_Project.h @@ -142,7 +142,8 @@ public: String getPluginChannelConfigsString() const { return pluginChannelConfigsValue.get(); } String getAAXIdentifierString() const { return pluginAAXIdentifierValue.get(); } String getPluginAUExportPrefixString() const { return pluginAUExportPrefixValue.get(); } - String getPluginAUMainTypeString() const { return pluginAUMainTypeValue.get(); } + String getVSTNumMIDIInputsString() const { return pluginVSTNumMidiInputsValue.get(); } + String getVSTNumMIDIOutputsString() const { return pluginVSTNumMidiOutputsValue.get(); } //============================================================================== static bool checkMultiChoiceVar (const ValueWithDefault& valueToCheck, Identifier idToCheck) noexcept @@ -423,12 +424,13 @@ private: ValueWithDefault projectNameValue, projectUIDValue, projectLineFeedValue, projectTypeValue, versionValue, bundleIdentifierValue, companyNameValue, companyCopyrightValue, companyWebsiteValue, companyEmailValue, displaySplashScreenValue, reportAppUsageValue, splashScreenColourValue, cppStandardValue, - headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInJuceHeaderValue, binaryDataNamespaceValue; + headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInJuceHeaderValue, binaryDataNamespaceValue, + compilerFlagSchemesValue; ValueWithDefault pluginFormatsValue, pluginNameValue, pluginDescriptionValue, pluginManufacturerValue, pluginManufacturerCodeValue, pluginCodeValue, pluginChannelConfigsValue, pluginCharacteristicsValue, pluginAUExportPrefixValue, pluginAAXIdentifierValue, pluginAUMainTypeValue, pluginAUSandboxSafeValue, pluginRTASCategoryValue, pluginVSTCategoryValue, pluginVST3CategoryValue, pluginAAXCategoryValue, - compilerFlagSchemesValue; + pluginVSTNumMidiInputsValue, pluginVSTNumMidiOutputsValue; //============================================================================== std::unique_ptr compileEngineSettings; diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp index 76b4b82072..19c922ec0e 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp @@ -123,6 +123,8 @@ void ProjectSaver::writePluginCharacteristicsFile() flags.set ("JucePlugin_IAAType", toCharLiteral (project.getIAATypeCode())); flags.set ("JucePlugin_IAASubType", "JucePlugin_PluginCode"); flags.set ("JucePlugin_IAAName", project.getIAAPluginName().quoted()); + flags.set ("JucePlugin_VSTNumMidiInputs", project.getVSTNumMIDIInputsString()); + flags.set ("JucePlugin_VSTNumMidiOutputs", project.getVSTNumMIDIOutputsString()); { String plugInChannelConfig = project.getPluginChannelConfigsString(); diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h index f126efbded..786ec282bb 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h @@ -337,6 +337,8 @@ namespace Ids DECLARE_ID (pluginAAXCategory); DECLARE_ID (pluginAAXDisableBypass); DECLARE_ID (pluginAAXDisableMultiMono); + DECLARE_ID (pluginVSTNumMidiInputs); + DECLARE_ID (pluginVSTNumMidiOutputs); DECLARE_ID (exporters); DECLARE_ID (website); DECLARE_ID (mainClass); diff --git a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h index 3a0674a6f3..7ce4eea43d 100644 --- a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h +++ b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h @@ -69,7 +69,23 @@ public: value (valueToListenTo.getPropertyAsValue()) { value.addListener (this); - setEnabled (valueWithDefault.get()); + valueChanged (value); + } + + ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl, + ValueWithDefault valueToListenTo, + const Identifier& multiChoiceID, + const String& propertyName, + const StringArray& choices, + const Array& correspondingValues) + : ChoicePropertyComponentWithEnablement (valueToControl, valueToListenTo, propertyName, choices, correspondingValues) + { + jassert (valueToListenTo.get().getArray() != nullptr); + + isMultiChoice = true; + idToCheck = multiChoiceID; + + valueChanged (value); } ~ChoicePropertyComponentWithEnablement() override { value.removeListener (this); } @@ -78,5 +94,27 @@ private: ValueWithDefault valueWithDefault; Value value; - void valueChanged (Value&) override { setEnabled (valueWithDefault.get()); } + bool isMultiChoice = false; + Identifier idToCheck; + + bool checkMultiChoiceVar() const + { + jassert (isMultiChoice); + + auto v = valueWithDefault.get(); + + if (auto* varArray = v.getArray()) + return varArray->contains (idToCheck.toString()); + + jassertfalse; + return false; + } + + void valueChanged (Value&) override + { + if (isMultiChoice) + setEnabled (checkMultiChoiceVar()); + else + setEnabled (valueWithDefault.get()); + } }; diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp index d5d3021d85..84f526fa8f 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp @@ -2230,7 +2230,11 @@ private: pointer_sized_int handleGetNumMidiInputChannels() { #if JucePlugin_WantsMidiInput || JucePlugin_IsMidiEffect - return 16; + #ifdef JucePlugin_VSTNumMidiInputs + return JucePlugin_VSTNumMidiInputs; + #else + return 16; + #endif #else return 0; #endif @@ -2239,7 +2243,11 @@ private: pointer_sized_int handleGetNumMidiOutputChannels() { #if JucePlugin_ProducesMidiOutput || JucePlugin_IsMidiEffect - return 16; + #ifdef JucePlugin_VSTNumMidiOutputs + return JucePlugin_VSTNumMidiOutputs; + #else + return 16; + #endif #else return 0; #endif diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp index 984d441642..5f1a6b5754 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -2047,7 +2047,13 @@ public: { info.mediaType = Vst::kEvent; info.direction = dir; + + #ifdef JucePlugin_VSTNumMidiInputs + info.channelCount = JucePlugin_VSTNumMidiInputs; + #else info.channelCount = 16; + #endif + toString128 (info.name, TRANS("MIDI Input")); info.busType = Vst::kMain; return kResultTrue; @@ -2059,7 +2065,13 @@ public: { info.mediaType = Vst::kEvent; info.direction = dir; + + #ifdef JucePlugin_VSTNumMidiOutputs + info.channelCount = JucePlugin_VSTNumMidiOutputs; + #else info.channelCount = 16; + #endif + toString128 (info.name, TRANS("MIDI Output")); info.busType = Vst::kMain; return kResultTrue;