From 4a87eb3c40b6c3d62a70471e12bfffdf1bd205aa Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 17 Oct 2024 16:55:31 +0100 Subject: [PATCH] AAX Client: Query processor instead of relying on JucePlugin_IsMidiEffect --- .../juce_audio_plugin_client_AAX.cpp | 158 ++++++++---------- 1 file changed, 72 insertions(+), 86 deletions(-) diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp index 84769113e1..0e341cc91c 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp @@ -501,15 +501,8 @@ namespace AAXClasses float** outputChannels; int32_t* bufferSize; int32_t* bypass; - - #if JucePlugin_WantsMidiInput || JucePlugin_IsMidiEffect AAX_IMIDINode* midiNodeIn; - #endif - - #if JucePlugin_ProducesMidiOutput || JucePlugin_IsSynth || JucePlugin_IsMidiEffect AAX_IMIDINode* midiNodeOut; - #endif - PluginInstanceInfo* pluginInstance; int32_t* isPrepared; float* const* meterTapBuffers; @@ -524,15 +517,8 @@ namespace AAXClasses outputChannels = AAX_FIELD_INDEX (JUCEAlgorithmContext, outputChannels), bufferSize = AAX_FIELD_INDEX (JUCEAlgorithmContext, bufferSize), bypass = AAX_FIELD_INDEX (JUCEAlgorithmContext, bypass), - - #if JucePlugin_WantsMidiInput || JucePlugin_IsMidiEffect midiNodeIn = AAX_FIELD_INDEX (JUCEAlgorithmContext, midiNodeIn), - #endif - - #if JucePlugin_ProducesMidiOutput || JucePlugin_IsSynth || JucePlugin_IsMidiEffect midiNodeOut = AAX_FIELD_INDEX (JUCEAlgorithmContext, midiNodeOut), - #endif - pluginInstance = AAX_FIELD_INDEX (JUCEAlgorithmContext, pluginInstance), preparedFlag = AAX_FIELD_INDEX (JUCEAlgorithmContext, isPrepared), @@ -542,19 +528,6 @@ namespace AAXClasses }; }; - #if JucePlugin_WantsMidiInput || JucePlugin_IsMidiEffect - static AAX_IMIDINode* getMidiNodeIn (const JUCEAlgorithmContext& c) noexcept { return c.midiNodeIn; } - #else - static AAX_IMIDINode* getMidiNodeIn (const JUCEAlgorithmContext&) noexcept { return nullptr; } - #endif - - #if JucePlugin_ProducesMidiOutput || JucePlugin_IsSynth || JucePlugin_IsMidiEffect - AAX_IMIDINode* midiNodeOut; - static AAX_IMIDINode* getMidiNodeOut (const JUCEAlgorithmContext& c) noexcept { return c.midiNodeOut; } - #else - static AAX_IMIDINode* getMidiNodeOut (const JUCEAlgorithmContext&) noexcept { return nullptr; } - #endif - //============================================================================== class JuceAAX_Processor; @@ -1658,13 +1631,17 @@ namespace AAXClasses friend class JuceAAX_GUI; friend void AAX_CALLBACK AAXClasses::algorithmProcessCallback (JUCEAlgorithmContext* const instancesBegin[], const void* const instancesEnd); - void process (float* const* channels, const int numChans, const int bufferSize, - const bool bypass, [[maybe_unused]] AAX_IMIDINode* midiNodeIn, [[maybe_unused]] AAX_IMIDINode* midiNodesOut) + void process (float* const* channels, + const int numChans, + const int bufferSize, + const bool bypass, + AAX_IMIDINode* midiNodeIn, + AAX_IMIDINode* midiNodesOut) { AudioBuffer buffer (channels, numChans, bufferSize); midiBuffer.clear(); - #if JucePlugin_WantsMidiInput || JucePlugin_IsMidiEffect + if (midiNodeIn != nullptr) { auto* midiStream = midiNodeIn->GetNodeBuffer(); auto numMidiEvents = midiStream->mBufferSize; @@ -1678,7 +1655,6 @@ namespace AAXClasses jlimit (0, (int) bufferSize - 1, (int) m.mTimestamp)); } } - #endif { if (lastBufferSize != bufferSize) @@ -1701,7 +1677,7 @@ namespace AAXClasses pluginInstance->processBlock (buffer, midiBuffer); } - #if JucePlugin_ProducesMidiOutput || JucePlugin_IsMidiEffect + if (midiNodesOut != nullptr) { AAX_CMidiPacket packet; packet.mIsImmediate = false; @@ -1720,7 +1696,6 @@ namespace AAXClasses } } } - #endif } bool isBypassPartOfRegularParemeters() const @@ -1827,14 +1802,16 @@ namespace AAXClasses { [[maybe_unused]] auto& audioProcessor = getPluginInstance(); - #if JucePlugin_IsMidiEffect - // MIDI effect plug-ins do not support any audio channels - jassert (audioProcessor.getTotalNumInputChannels() == 0 - && audioProcessor.getTotalNumOutputChannels() == 0); + if (audioProcessor.isMidiEffect()) + { + // MIDI effect plug-ins do not support any audio channels + jassert (audioProcessor.getTotalNumInputChannels() == 0 + && audioProcessor.getTotalNumOutputChannels() == 0); + + inputSet = outputSet = AudioChannelSet(); + return true; + } - inputSet = outputSet = AudioChannelSet(); - return true; - #else auto inputBuses = audioProcessor.getBusCount (true); auto outputBuses = audioProcessor.getBusCount (false); @@ -1857,7 +1834,6 @@ namespace AAXClasses return false; return true; - #endif } AAX_Result preparePlugin() @@ -2013,9 +1989,15 @@ namespace AAXClasses auto numMeters = i.pluginInstance->parameters.aaxMeters.size(); float* const meterTapBuffers = (i.meterTapBuffers != nullptr && numMeters > 0 ? *i.meterTapBuffers : nullptr); - i.pluginInstance->parameters.process (i.inputChannels, i.outputChannels, sideChainBufferIdx, - *(i.bufferSize), *(i.bypass) != 0, - getMidiNodeIn (i), getMidiNodeOut (i), + const auto& parameters = i.pluginInstance->parameters; + + i.pluginInstance->parameters.process (i.inputChannels, + i.outputChannels, + sideChainBufferIdx, + *(i.bufferSize), + *(i.bypass) != 0, + parameters.supportsMidiIn ? i.midiNodeIn : nullptr, + parameters.supportsMidiOut ? i.midiNodeOut : nullptr, meterTapBuffers); } } @@ -2264,6 +2246,9 @@ namespace AAXClasses int lastBufferSize = maxSamplesPerBlock, maxBufferSize = maxSamplesPerBlock; bool hasSidechain = false, canDisableSidechain = false, lastSideChainState = false; + const bool supportsMidiIn = pluginInstance->isMidiEffect() || pluginInstance->acceptsMidi(); + const bool supportsMidiOut = pluginInstance->isMidiEffect() || pluginInstance->producesMidi(); + /* Pro Tools 2021 sends TransportStateChanged on the main thread, but we read the recording state on the audio thread. I'm not sure whether Pro Tools ensures that these calls are mutually @@ -2436,9 +2421,8 @@ namespace AAXClasses aaxInputFormat = aaxOutputFormat; #endif - #if JucePlugin_IsMidiEffect - aaxInputFormat = aaxOutputFormat = AAX_eStemFormat_Mono; - #endif + if (processor.isMidiEffect()) + aaxInputFormat = aaxOutputFormat = AAX_eStemFormat_Mono; check (desc.AddAudioIn (JUCEAlgorithmIDs::inputChannels)); check (desc.AddAudioOut (JUCEAlgorithmIDs::outputChannels)); @@ -2446,15 +2430,13 @@ namespace AAXClasses check (desc.AddAudioBufferLength (JUCEAlgorithmIDs::bufferSize)); check (desc.AddDataInPort (JUCEAlgorithmIDs::bypass, sizeof (int32_t))); - #if JucePlugin_WantsMidiInput || JucePlugin_IsMidiEffect - check (desc.AddMIDINode (JUCEAlgorithmIDs::midiNodeIn, AAX_eMIDINodeType_LocalInput, - JucePlugin_Name, 0xffff)); - #endif + if (processor.acceptsMidi() || processor.isMidiEffect()) + check (desc.AddMIDINode (JUCEAlgorithmIDs::midiNodeIn, AAX_eMIDINodeType_LocalInput, + JucePlugin_Name, 0xffff)); - #if JucePlugin_ProducesMidiOutput || JucePlugin_IsSynth || JucePlugin_IsMidiEffect - check (desc.AddMIDINode (JUCEAlgorithmIDs::midiNodeOut, AAX_eMIDINodeType_LocalOutput, - JucePlugin_Name " Out", 0xffff)); - #endif + if (processor.producesMidi() || processor.isMidiEffect()) + check (desc.AddMIDINode (JUCEAlgorithmIDs::midiNodeOut, AAX_eMIDINodeType_LocalOutput, + JucePlugin_Name " Out", 0xffff)); check (desc.AddPrivateData (JUCEAlgorithmIDs::pluginInstance, sizeof (PluginInstanceInfo))); check (desc.AddPrivateData (JUCEAlgorithmIDs::preparedFlag, sizeof (int32_t))); @@ -2626,49 +2608,53 @@ namespace AAXClasses check (descriptor.AddProcPtr ((void*) JuceAAX_Processor::Create, kAAX_ProcPtrID_Create_EffectParameters)); Array pluginIds; - #if JucePlugin_IsMidiEffect - // MIDI effect plug-ins do not support any audio channels - jassert (numInputBuses == 0 && numOutputBuses == 0); - if (auto* desc = descriptor.NewComponentDescriptor()) + if (plugin->isMidiEffect()) { - createDescriptor (*desc, plugin->getBusesLayout(), *plugin, pluginIds, numMeters); - check (descriptor.AddComponent (desc)); - } - #else - const int numIns = numInputBuses > 0 ? numElementsInArray (aaxFormats) : 0; - const int numOuts = numOutputBuses > 0 ? numElementsInArray (aaxFormats) : 0; + // MIDI effect plug-ins do not support any audio channels + jassert (numInputBuses == 0 && numOutputBuses == 0); - for (int inIdx = 0; inIdx < jmax (numIns, 1); ++inIdx) - { - auto aaxInFormat = numIns > 0 ? aaxFormats[inIdx] : AAX_eStemFormat_None; - auto inLayout = channelSetFromStemFormat (aaxInFormat, false); - - for (int outIdx = 0; outIdx < jmax (numOuts, 1); ++outIdx) + if (auto* desc = descriptor.NewComponentDescriptor()) { - auto aaxOutFormat = numOuts > 0 ? aaxFormats[outIdx] : AAX_eStemFormat_None; - auto outLayout = channelSetFromStemFormat (aaxOutFormat, false); + createDescriptor (*desc, plugin->getBusesLayout(), *plugin, pluginIds, numMeters); + check (descriptor.AddComponent (desc)); + } + } + else + { + const int numIns = numInputBuses > 0 ? numElementsInArray (aaxFormats) : 0; + const int numOuts = numOutputBuses > 0 ? numElementsInArray (aaxFormats) : 0; - if (hostSupportsStemFormat (aaxInFormat, featureInfo) - && hostSupportsStemFormat (aaxOutFormat, featureInfo)) + for (int inIdx = 0; inIdx < jmax (numIns, 1); ++inIdx) + { + auto aaxInFormat = numIns > 0 ? aaxFormats[inIdx] : AAX_eStemFormat_None; + auto inLayout = channelSetFromStemFormat (aaxInFormat, false); + + for (int outIdx = 0; outIdx < jmax (numOuts, 1); ++outIdx) { - AudioProcessor::BusesLayout fullLayout; + auto aaxOutFormat = numOuts > 0 ? aaxFormats[outIdx] : AAX_eStemFormat_None; + auto outLayout = channelSetFromStemFormat (aaxOutFormat, false); - if (! JuceAAX_Processor::fullBusesLayoutFromMainLayout (*plugin, inLayout, outLayout, fullLayout)) - continue; - - if (auto* desc = descriptor.NewComponentDescriptor()) + if (hostSupportsStemFormat (aaxInFormat, featureInfo) + && hostSupportsStemFormat (aaxOutFormat, featureInfo)) { - createDescriptor (*desc, fullLayout, *plugin, pluginIds, numMeters); - check (descriptor.AddComponent (desc)); + AudioProcessor::BusesLayout fullLayout; + + if (! JuceAAX_Processor::fullBusesLayoutFromMainLayout (*plugin, inLayout, outLayout, fullLayout)) + continue; + + if (auto* desc = descriptor.NewComponentDescriptor()) + { + createDescriptor (*desc, fullLayout, *plugin, pluginIds, numMeters); + check (descriptor.AddComponent (desc)); + } } } } - } - // You don't have any supported layouts - jassert (pluginIds.size() > 0); - #endif + // You don't have any supported layouts + jassert (pluginIds.size() > 0); + } } } // namespace AAXClasses