|
|
@@ -522,7 +522,7 @@ struct AAXClasses |
|
|
|
{
|
|
|
|
public:
|
|
|
|
JuceAAX_Processor() : pluginInstance (createPluginFilterOfType (AudioProcessor::wrapperType_AAX)),
|
|
|
|
busUtils (*pluginInstance, false, maxAAXChannels),
|
|
|
|
isPrepared (false), busUtils (*pluginInstance, false, maxAAXChannels),
|
|
|
|
sampleRate (0), lastBufferSize (1024), maxBufferSize (1024),
|
|
|
|
hasSidechain (false)
|
|
|
|
{
|
|
|
@@ -540,6 +540,17 @@ struct AAXClasses |
|
|
|
return new JuceAAX_Processor();
|
|
|
|
}
|
|
|
|
|
|
|
|
AAX_Result Uninitialize() override
|
|
|
|
{
|
|
|
|
if (isPrepared && pluginInstance != nullptr)
|
|
|
|
{
|
|
|
|
isPrepared = false;
|
|
|
|
pluginInstance->releaseResources();
|
|
|
|
}
|
|
|
|
|
|
|
|
return AAX_CEffectParameters::Uninitialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
AAX_Result EffectInit() override
|
|
|
|
{
|
|
|
|
AAX_Result err;
|
|
|
@@ -1103,6 +1114,7 @@ struct AAXClasses |
|
|
|
AAX_Result preparePlugin()
|
|
|
|
{
|
|
|
|
AudioProcessor& audioProcessor = getPluginInstance();
|
|
|
|
bool hasSomethingChanged = false;
|
|
|
|
|
|
|
|
#if JucePlugin_IsMidiEffect
|
|
|
|
// MIDI effect plug-ins do not support any audio channels
|
|
|
@@ -1120,39 +1132,74 @@ struct AAXClasses |
|
|
|
|
|
|
|
if ( (inputSet == AudioChannelSet::disabled() && inputStemFormat != AAX_eStemFormat_None)
|
|
|
|
|| (outputSet == AudioChannelSet::disabled() && outputStemFormat != AAX_eStemFormat_None))
|
|
|
|
{
|
|
|
|
if (isPrepared)
|
|
|
|
{
|
|
|
|
isPrepared = false;
|
|
|
|
audioProcessor.releaseResources();
|
|
|
|
}
|
|
|
|
|
|
|
|
return AAX_ERROR_UNIMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool success = true;
|
|
|
|
|
|
|
|
if (busUtils.getBusCount (true) > 0)
|
|
|
|
success = audioProcessor.setPreferredBusArrangement (true, 0, inputSet);
|
|
|
|
success = setPreferredBusArrangement (busUtils, true, 0, inputSet, hasSomethingChanged);
|
|
|
|
|
|
|
|
if (success && busUtils.getBusCount (false) > 0)
|
|
|
|
success = audioProcessor.setPreferredBusArrangement (false, 0, outputSet);
|
|
|
|
success = setPreferredBusArrangement (busUtils, false, 0, outputSet, hasSomethingChanged);
|
|
|
|
|
|
|
|
// This should never happen as the plugin reported that this layout is supported
|
|
|
|
jassert (success);
|
|
|
|
|
|
|
|
hasSidechain = enableAuxBusesForCurrentFormat (busUtils, inputSet, outputSet);
|
|
|
|
if (hasSidechain)
|
|
|
|
hasSidechain = enableAuxBusesForCurrentFormat (busUtils, inputSet, outputSet, hasSomethingChanged);
|
|
|
|
if (hasSidechain && hasSomethingChanged)
|
|
|
|
sideChainBuffer.realloc (static_cast<size_t> (maxBufferSize));
|
|
|
|
|
|
|
|
// recheck the format
|
|
|
|
if ( (busUtils.getBusCount (true) > 0 && busUtils.getChannelSet (true, 0) != inputSet)
|
|
|
|
|| (busUtils.getBusCount (false) > 0 && busUtils.getChannelSet (false, 0) != outputSet)
|
|
|
|
|| (hasSidechain && busUtils.getNumChannels(true, 1) != 1))
|
|
|
|
{
|
|
|
|
if (isPrepared)
|
|
|
|
{
|
|
|
|
isPrepared = false;
|
|
|
|
audioProcessor.releaseResources();
|
|
|
|
}
|
|
|
|
|
|
|
|
return AAX_ERROR_UNIMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
rebuildChannelMapArrays (true);
|
|
|
|
rebuildChannelMapArrays (false);
|
|
|
|
if (hasSomethingChanged)
|
|
|
|
{
|
|
|
|
rebuildChannelMapArrays (true);
|
|
|
|
rebuildChannelMapArrays (false);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
audioProcessor.setRateAndBufferSizeDetails (sampleRate, maxBufferSize);
|
|
|
|
audioProcessor.prepareToPlay (sampleRate, lastBufferSize);
|
|
|
|
maxBufferSize = lastBufferSize;
|
|
|
|
hasSomethingChanged = (sampleRate != audioProcessor.getSampleRate()
|
|
|
|
|| maxBufferSize != lastBufferSize
|
|
|
|
|| hasSomethingChanged);
|
|
|
|
|
|
|
|
if (hasSomethingChanged || (! isPrepared))
|
|
|
|
{
|
|
|
|
if (isPrepared)
|
|
|
|
{
|
|
|
|
isPrepared = false;
|
|
|
|
audioProcessor.releaseResources();
|
|
|
|
}
|
|
|
|
|
|
|
|
audioProcessor.setRateAndBufferSizeDetails (sampleRate, lastBufferSize);
|
|
|
|
audioProcessor.prepareToPlay (sampleRate, lastBufferSize);
|
|
|
|
maxBufferSize = lastBufferSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
check (Controller()->SetSignalLatency (audioProcessor.getLatencySamples()));
|
|
|
|
|
|
|
|
isPrepared = true;
|
|
|
|
|
|
|
|
return AAX_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
@@ -1197,6 +1244,7 @@ struct AAXClasses |
|
|
|
ScopedJuceInitialiser_GUI libraryInitialiser;
|
|
|
|
|
|
|
|
ScopedPointer<AudioProcessor> pluginInstance;
|
|
|
|
bool isPrepared;
|
|
|
|
PluginBusUtilities busUtils;
|
|
|
|
MidiBuffer midiBuffer;
|
|
|
|
Array<float*> channelList;
|
|
|
@@ -1271,7 +1319,8 @@ struct AAXClasses |
|
|
|
}
|
|
|
|
|
|
|
|
static bool enableAuxBusesForCurrentFormat (PluginBusUtilities& busUtils, const AudioChannelSet& inputLayout,
|
|
|
|
const AudioChannelSet& outputLayout)
|
|
|
|
const AudioChannelSet& outputLayout,
|
|
|
|
bool& hasSomethingChanged)
|
|
|
|
{
|
|
|
|
const int numOutBuses = busUtils.getBusCount (false);
|
|
|
|
const int numInputBuses = busUtils.getBusCount(true);
|
|
|
@@ -1289,7 +1338,7 @@ struct AAXClasses |
|
|
|
if (layout == AudioChannelSet::disabled())
|
|
|
|
{
|
|
|
|
layout = busUtils.getDefaultLayoutForBus (false, busIdx);
|
|
|
|
busUtils.processor.setPreferredBusArrangement (false, busIdx, layout);
|
|
|
|
setPreferredBusArrangement (busUtils, false, busIdx, layout, hasSomethingChanged);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
@@ -1297,15 +1346,17 @@ struct AAXClasses |
|
|
|
bool success = true;
|
|
|
|
|
|
|
|
if (numInputBuses > 0)
|
|
|
|
success = busUtils.processor.setPreferredBusArrangement (true, 0, inputLayout);
|
|
|
|
success = setPreferredBusArrangement (busUtils, true, 0, inputLayout, hasSomethingChanged);
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
success = busUtils.processor.setPreferredBusArrangement (false, 0, outputLayout);
|
|
|
|
success = setPreferredBusArrangement (busUtils, false, 0, outputLayout, hasSomethingChanged);
|
|
|
|
|
|
|
|
// was the above successful
|
|
|
|
if (success && (numInputBuses == 0 || busUtils.getChannelSet (true, 0) == inputLayout)
|
|
|
|
&& busUtils.getChannelSet (false, 0) == outputLayout)
|
|
|
|
layoutRestorer.release();
|
|
|
|
else
|
|
|
|
hasSomethingChanged = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// does the plug-in have side-chain support? Check the following:
|
|
|
@@ -1319,10 +1370,12 @@ struct AAXClasses |
|
|
|
|
|
|
|
const AudioChannelSet set = busUtils.getDefaultLayoutForChannelNumAndBus (true, 1, 1);
|
|
|
|
if (! set.isDisabled())
|
|
|
|
hasSidechain = busUtils.processor.setPreferredBusArrangement (true, 1, set);
|
|
|
|
hasSidechain = setPreferredBusArrangement (busUtils, true, 1, set, hasSomethingChanged);
|
|
|
|
|
|
|
|
if (! hasSidechain)
|
|
|
|
success = busUtils.processor.setPreferredBusArrangement (true, 1, AudioChannelSet::disabled());
|
|
|
|
success = setPreferredBusArrangement (busUtils, true, 1,
|
|
|
|
AudioChannelSet::disabled(),
|
|
|
|
hasSomethingChanged);
|
|
|
|
|
|
|
|
// AAX requires your processor's first sidechain to be either mono or that
|
|
|
|
// it can be disabled
|
|
|
@@ -1331,7 +1384,9 @@ struct AAXClasses |
|
|
|
// disable all other input buses
|
|
|
|
for (int busIdx = 2; busIdx < numInputBuses; ++busIdx)
|
|
|
|
{
|
|
|
|
success = busUtils.processor.setPreferredBusArrangement (true, busIdx, AudioChannelSet::disabled());
|
|
|
|
success = setPreferredBusArrangement (busUtils, true, busIdx,
|
|
|
|
AudioChannelSet::disabled(),
|
|
|
|
hasSomethingChanged);
|
|
|
|
|
|
|
|
// AAX can only have a single side-chain input. Therefore, your processor must either
|
|
|
|
// only have a single side-chain input or allow disabling all other side-chains
|
|
|
@@ -1341,21 +1396,34 @@ struct AAXClasses |
|
|
|
if (hasSidechain)
|
|
|
|
{
|
|
|
|
if (busUtils.getBusCount (false) == 0 || busUtils.getBusCount (true) == 0 ||
|
|
|
|
(busUtils.getChannelSet (true, 0) == inputLayout && busUtils.getChannelSet (false, 0) == outputLayout))
|
|
|
|
(busUtils.getChannelSet (true, 0) == inputLayout && busUtils.getChannelSet (false, 0) == outputLayout))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// restore the old layout
|
|
|
|
if (busUtils.getBusCount(true) > 0)
|
|
|
|
busUtils.processor.setPreferredBusArrangement (true, 0, inputLayout);
|
|
|
|
setPreferredBusArrangement (busUtils, true, 0, inputLayout, hasSomethingChanged);
|
|
|
|
|
|
|
|
if (busUtils.getBusCount (false) > 0)
|
|
|
|
busUtils.processor.setPreferredBusArrangement (false, 0, outputLayout);
|
|
|
|
setPreferredBusArrangement (busUtils, false, 0, outputLayout, hasSomethingChanged);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// wrap setPreferredBusArrangement calls with this to prevent excessive calls to the plug-in
|
|
|
|
static bool setPreferredBusArrangement (PluginBusUtilities& busUtils, bool isInput, int busIdx,
|
|
|
|
const AudioChannelSet& layout,
|
|
|
|
bool& didChangePlugin)
|
|
|
|
{
|
|
|
|
// no need to do anything
|
|
|
|
if (busUtils.getChannelSet (isInput, busIdx) == layout)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
didChangePlugin = true;
|
|
|
|
return busUtils.processor.setPreferredBusArrangement (isInput, busIdx, layout);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
static void createDescriptor (AAX_IComponentDescriptor& desc, int configIndex, PluginBusUtilities& busUtils,
|
|
|
|
const AudioChannelSet& inputLayout, const AudioChannelSet& outputLayout,
|
|
|
@@ -1418,7 +1486,8 @@ struct AAXClasses |
|
|
|
properties->AddProperty (AAX_eProperty_SupportsSaveRestore, false);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (enableAuxBusesForCurrentFormat (busUtils, inputLayout, outputLayout))
|
|
|
|
bool ignore;
|
|
|
|
if (enableAuxBusesForCurrentFormat (busUtils, inputLayout, outputLayout, ignore))
|
|
|
|
{
|
|
|
|
check (desc.AddSideChainIn (JUCEAlgorithmIDs::sideChainBuffers));
|
|
|
|
properties->AddProperty (AAX_eProperty_SupportsSideChainInput, true);
|
|
|
|