1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

AAX Client: Query processor instead of relying on JucePlugin_IsMidiEffect

This commit is contained in:
reuk 2024-10-17 16:55:31 +01:00
parent 499abb7637
commit 4a87eb3c40
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C

View file

@ -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<float> 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<int32> 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