From 7d28d7dec26c89f0f989ef47a2ccff8b0769656b Mon Sep 17 00:00:00 2001 From: hogliux Date: Mon, 13 Feb 2017 11:57:22 +0000 Subject: [PATCH] Added a fix to generate the AAX plug-in ID from the channel configuration (and not an arbitrary order in which JUCE probes configurations) Also added the method AudioProcessor::getAAXPluginIDForMainBusConfig for developers to override the generation of AAX plug-in IDs so that their plug-ins remain backward compatible --- .../AAX/juce_AAX_Wrapper.cpp | 28 +++++++++---- .../processors/juce_AudioProcessor.cpp | 39 +++++++++++++++++++ .../processors/juce_AudioProcessor.h | 14 +++++++ 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp index dd98b97582..f512dc9439 100644 --- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp @@ -1734,8 +1734,10 @@ namespace AAXClasses return meterIdx; } - static void createDescriptor (AAX_IComponentDescriptor& desc, int configIndex, - const AudioProcessor::BusesLayout& fullLayout, AudioProcessor& processor, + static void createDescriptor (AAX_IComponentDescriptor& desc, + const AudioProcessor::BusesLayout& fullLayout, + AudioProcessor& processor, + Array& pluginIds, const int numMeters) { AAX_EStemFormat aaxInputFormat = getFormatForAudioChannelSet (fullLayout.getMainInputChannelSet(), false); @@ -1797,10 +1799,22 @@ namespace AAXClasses // This value needs to match the RTAS wrapper's Type ID, so that // the host knows that the RTAS/AAX plugins are equivalent. - properties->AddProperty (AAX_eProperty_PlugInID_Native, 'jcaa' + configIndex); + const int32 pluginID = processor.getAAXPluginIDForMainBusConfig (fullLayout.getMainInputChannelSet(), + fullLayout.getMainOutputChannelSet(), + false); + + // The plugin id generated from your AudioProcessor's getAAXPluginIDForMainBusConfig callback + // it not unique. Please fix your implementation! + jassert (! pluginIds.contains (pluginID)); + pluginIds.add (pluginID); + + properties->AddProperty (AAX_eProperty_PlugInID_Native, pluginID); #if ! JucePlugin_AAXDisableAudioSuite - properties->AddProperty (AAX_eProperty_PlugInID_AudioSuite, 'jyaa' + configIndex); + properties->AddProperty (AAX_eProperty_PlugInID_AudioSuite, + processor.getAAXPluginIDForMainBusConfig (fullLayout.getMainInputChannelSet(), + fullLayout.getMainOutputChannelSet(), + true)); #endif #if JucePlugin_AAXDisableMultiMono @@ -1879,7 +1893,7 @@ namespace AAXClasses } #else - int configIndex = 0; + Array pluginIds; const int numIns = numInputBuses > 0 ? AAX_eStemFormatNum : 0; const int numOuts = numOutputBuses > 0 ? AAX_eStemFormatNum : 0; @@ -1900,14 +1914,14 @@ namespace AAXClasses if (AAX_IComponentDescriptor* const desc = descriptor.NewComponentDescriptor()) { - createDescriptor (*desc, configIndex++, fullLayout, *plugin, numMeters); + createDescriptor (*desc, fullLayout, *plugin, pluginIds, numMeters); check (descriptor.AddComponent (desc)); } } } // You don't have any supported layouts - jassert (configIndex > 0); + jassert (pluginIds.size() > 0); #endif } } diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index d19a72b4c5..a17816d22e 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -1302,6 +1302,45 @@ AudioProcessor::BusesProperties AudioProcessor::BusesProperties::withOutput (con return retval; } +//============================================================================== +int32 AudioProcessor::getAAXPluginIDForMainBusConfig (const AudioChannelSet& mainInputLayout, + const AudioChannelSet& mainOutputLayout, + const bool idForAudioSuite) const +{ + int uniqueFormatId = 0; + for (int dir = 0; dir < 2; ++dir) + { + const bool isInput = (dir == 0); + const AudioChannelSet& set = (isInput ? mainInputLayout : mainOutputLayout); + int aaxFormatIndex = 0; + + if (set == AudioChannelSet::disabled()) aaxFormatIndex = 0; + else if (set == AudioChannelSet::mono()) aaxFormatIndex = 1; + else if (set == AudioChannelSet::stereo()) aaxFormatIndex = 2; + else if (set == AudioChannelSet::createLCR()) aaxFormatIndex = 3; + else if (set == AudioChannelSet::createLCRS()) aaxFormatIndex = 4; + else if (set == AudioChannelSet::quadraphonic()) aaxFormatIndex = 5; + else if (set == AudioChannelSet::create5point0()) aaxFormatIndex = 6; + else if (set == AudioChannelSet::create5point1()) aaxFormatIndex = 7; + else if (set == AudioChannelSet::create6point0()) aaxFormatIndex = 8; + else if (set == AudioChannelSet::create6point1()) aaxFormatIndex = 9; + else if (set == AudioChannelSet::create7point0()) aaxFormatIndex = 10; + else if (set == AudioChannelSet::create7point1()) aaxFormatIndex = 11; + else if (set == AudioChannelSet::create7point0SDDS()) aaxFormatIndex = 12; + else if (set == AudioChannelSet::create7point1SDDS()) aaxFormatIndex = 13; + else + { + // AAX does not support this format and the wrapper should not have + // called this method with this layout + jassertfalse; + } + + uniqueFormatId = (uniqueFormatId * 16) + aaxFormatIndex; + } + + return (idForAudioSuite ? 0x6a796161 /* 'jyaa' */ : 0x6a636161 /* 'jcaa' */) + uniqueFormatId; +} + //============================================================================== void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index d6ea2a7504..5903e38f5e 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1263,6 +1263,20 @@ public: */ void setRateAndBufferSizeDetails (double sampleRate, int blockSize) noexcept; + //============================================================================== + /** AAX plug-ins need to report a unique "plug-in id" for every audio layout + configuration that your AudioProcessor supports on the main bus. Override this + function if you want your AudioProcessor to use a custom "plug-in id" (for example + to stay backward compatible with older versions of JUCE). + + The default implementation will compute a unique integer from the input and output + layout and add this value to the 4 character code 'jcaa' (for native AAX) or 'jyaa' + (for AudioSuite plug-ins). + */ + virtual int32 getAAXPluginIDForMainBusConfig (const AudioChannelSet& mainInputLayout, + const AudioChannelSet& mainOutputLayout, + bool idForAudioSuite) const; + //============================================================================== /** Not for public use - this is called before deleting an editor component. */ void editorBeingDeleted (AudioProcessorEditor*) noexcept;