diff --git a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm index 7bf151d44a..18082648b3 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm @@ -117,7 +117,9 @@ class JuceAU : public AudioProcessorHolder, public: JuceAU (AudioUnit component) : AudioProcessorHolder(activePlugins.size() + activeUIs.size() == 0), - MusicDeviceBase (component, (UInt32) juceFilter->getBusCount (true), (UInt32) juceFilter->getBusCount (false)), + MusicDeviceBase (component, + (UInt32) AudioUnitHelpers::getBusCount (juceFilter, true), + (UInt32) AudioUnitHelpers::getBusCount (juceFilter, false)), isBypassed (false), mapper (*juceFilter) { @@ -189,7 +191,7 @@ public: return err; mapper.alloc(); - pulledSucceeded.calloc (static_cast (juceFilter->getBusCount (true))); + pulledSucceeded.calloc (static_cast (AudioUnitHelpers::getBusCount (juceFilter, true))); prepareToPlay(); @@ -263,6 +265,11 @@ public: //============================================================================== bool BusCountWritable (AudioUnitScope scope) override { + #ifdef JucePlugin_PreferredChannelConfigurations + ignoreUnused (scope); + + return false; + #else bool isInput; if (scopeToDirection (scope, isInput) != noErr) @@ -274,8 +281,9 @@ public: if (isInput) return false; #endif - const int busCount = juceFilter->getBusCount (isInput); + const int busCount = AudioUnitHelpers::getBusCount (juceFilter, isInput); return (juceFilter->canAddBus (isInput) || (busCount > 0 && juceFilter->canRemoveBus (isInput))); + #endif } OSStatus SetBusCount (AudioUnitScope scope, UInt32 count) override @@ -286,9 +294,12 @@ public: if ((err = scopeToDirection (scope, isInput)) != noErr) return err; - if (count != (UInt32) juceFilter->getBusCount (isInput)) + if (count != (UInt32) AudioUnitHelpers::getBusCount (juceFilter, isInput)) { - const int busCount = juceFilter->getBusCount (isInput); + #ifdef JucePlugin_PreferredChannelConfigurations + return kAudioUnitErr_PropertyNotWritable; + #else + const int busCount = AudioUnitHelpers::getBusCount (juceFilter, isInput); if ((! juceFilter->canAddBus (isInput)) && ((busCount == 0) || (! juceFilter->canRemoveBus (isInput)))) return kAudioUnitErr_PropertyNotWritable; @@ -328,7 +339,7 @@ public: if (err != noErr) { // restore bus state - const int newBusCount = juceFilter->getBusCount (isInput); + const int newBusCount = AudioUnitHelpers::getBusCount (juceFilter, isInput); for (int i = newBusCount; i != busCount; i += (busCount > newBusCount ? 1 : -1)) { if (busCount > newBusCount) @@ -346,6 +357,7 @@ public: if (err != noErr) return err; + #endif } return noErr; @@ -862,7 +874,7 @@ public: ComponentResult Version() override { return JucePlugin_VersionCode; } bool SupportsTail() override { return true; } Float64 GetTailTime() override { return juceFilter->getTailLengthSeconds(); } - double getSampleRate() { return juceFilter->getBusCount (false) > 0 ? GetOutput(0)->GetStreamFormat().mSampleRate : 44100.0; } + double getSampleRate() { return AudioUnitHelpers::getBusCount (juceFilter, false) > 0 ? GetOutput(0)->GetStreamFormat().mSampleRate : 44100.0; } Float64 GetLatency() override { @@ -1652,7 +1664,7 @@ private: busIdx = static_cast (element); if ((err = scopeToDirection (scope, isInput)) != noErr) return err; - if (isPositiveAndBelow (busIdx, juceFilter->getBusCount (isInput))) return noErr; + if (isPositiveAndBelow (busIdx, AudioUnitHelpers::getBusCount (juceFilter, isInput))) return noErr; return kAudioUnitErr_InvalidElement; } @@ -1736,8 +1748,8 @@ private: OSStatus syncAudioUnitWithProcessor() { OSStatus err = noErr; - const int enabledInputs = juceFilter->getBusCount (true); - const int enabledOutputs = juceFilter->getBusCount (false); + const int enabledInputs = AudioUnitHelpers::getBusCount (juceFilter, true); + const int enabledOutputs = AudioUnitHelpers::getBusCount (juceFilter, false); if ((err = MusicDeviceBase::SetBusCount (kAudioUnitScope_Input, static_cast (enabledInputs))) != noErr) return err; @@ -1758,8 +1770,8 @@ private: OSStatus syncProcessorWithAudioUnit() { - const int numInputBuses = juceFilter->getBusCount (true); - const int numOutputBuses = juceFilter->getBusCount (false); + const int numInputBuses = AudioUnitHelpers::getBusCount (juceFilter, true); + const int numOutputBuses = AudioUnitHelpers::getBusCount (juceFilter, false); const int numInputElements = static_cast (GetScope(kAudioUnitScope_Input). GetNumberOfElements()); const int numOutputElements = static_cast (GetScope(kAudioUnitScope_Output).GetNumberOfElements()); @@ -1794,7 +1806,7 @@ private: return kAudioUnitErr_FormatNotSupported; #endif - if (! juceFilter->setBusesLayout (requestedLayouts)) + if (! AudioUnitHelpers::setBusesLayout (juceFilter, requestedLayouts)) return kAudioUnitErr_FormatNotSupported; // update total channel count @@ -1898,7 +1910,7 @@ private: Array >& layouts = isInput ? supportedInputLayouts : supportedOutputLayouts; layouts.clear(); - const int numBuses = juceFilter->getBusCount (isInput); + const int numBuses = AudioUnitHelpers::getBusCount (juceFilter, isInput); for (int busNr = 0; busNr < numBuses; ++busNr) { Array busLayouts; @@ -1912,8 +1924,8 @@ private: { currentInputLayout.clear(); currentOutputLayout.clear(); - currentInputLayout. resize (juceFilter->getBusCount (true)); - currentOutputLayout.resize (juceFilter->getBusCount (false)); + currentInputLayout. resize (AudioUnitHelpers::getBusCount (juceFilter, true)); + currentOutputLayout.resize (AudioUnitHelpers::getBusCount (juceFilter, false)); addSupportedLayoutTagsForDirection (true); addSupportedLayoutTagsForDirection (false); diff --git a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm index 60a58b1604..884b1cc6f1 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm @@ -542,7 +542,7 @@ public: for (int dir = 0; dir < 2; ++dir) { const bool isInput = (dir == 0); - const int n = processor.getBusCount (isInput); + const int n = AudioUnitHelpers::getBusCount (&processor, isInput); Array& channelSets = (isInput ? layouts.inputBuses : layouts.outputBuses); AUAudioUnitBusArray* auBuses = (isInput ? [getAudioUnit() inputBusses] : [getAudioUnit() outputBusses]); @@ -578,7 +578,7 @@ public: } #endif - if (! processor.setBusesLayout (layouts)) + if (! AudioUnitHelpers::setBusesLayout (&getAudioProcessor(), layouts)) { if (outError != nullptr) *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:kAudioUnitErr_FormatNotSupported userInfo:nullptr]; @@ -596,7 +596,7 @@ public: audioBuffer.prepare (totalInChannels, totalOutChannels, static_cast (maxFrames)); - double sampleRate = (jmax (processor.getBusCount (true), processor.getBusCount (false)) > 0 ? + double sampleRate = (jmax (AudioUnitHelpers::getBusCount (&processor, true), AudioUnitHelpers::getBusCount (&processor, false)) > 0 ? [[[([inputBusses count] > 0 ? inputBusses : outputBusses) objectAtIndexedSubscript: 0] format] sampleRate] : 44100.0); processor.setRateAndBufferSizeDetails (sampleRate, static_cast (maxFrames)); @@ -869,7 +869,7 @@ private: { ScopedPointer > array = [[NSMutableArray alloc] init]; AudioProcessor& processor = getAudioProcessor(); - const int n = processor.getBusCount (isInput); + const int n = AudioUnitHelpers::getBusCount (&processor, isInput); for (int i = 0; i < n; ++i) { @@ -996,7 +996,7 @@ private: OwnedArray& busBuffers = isInput ? inBusBuffers : outBusBuffers; busBuffers.clear(); - const int n = getAudioProcessor().getBusCount (isInput); + const int n = AudioUnitHelpers::getBusCount (&getAudioProcessor(), isInput); const AUAudioFrameCount maxFrames = [getAudioUnit() maximumFramesToRender]; for (int busIdx = 0; busIdx < n; ++busIdx) diff --git a/modules/juce_audio_processors/format_types/juce_AU_Shared.h b/modules/juce_audio_processors/format_types/juce_AU_Shared.h index 5ef785780d..1b56028199 100644 --- a/modules/juce_audio_processors/format_types/juce_AU_Shared.h +++ b/modules/juce_audio_processors/format_types/juce_AU_Shared.h @@ -324,8 +324,8 @@ struct AudioUnitHelpers void alloc() { - const int numInputBuses = processor.getBusCount (true); - const int numOutputBuses = processor.getBusCount (false); + const int numInputBuses = AudioUnitHelpers::getBusCount (&processor, true); + const int numOutputBuses = AudioUnitHelpers::getBusCount (&processor, false); initializeChannelMapArray (true, numInputBuses); initializeChannelMapArray (false, numOutputBuses); @@ -611,10 +611,10 @@ struct AudioUnitHelpers { Array channelInfo; - const bool hasMainInputBus = (processor.getBusCount (true) > 0); - const bool hasMainOutputBus = (processor.getBusCount (false) > 0); + const bool hasMainInputBus = (AudioUnitHelpers::getBusCount (&processor, true) > 0); + const bool hasMainOutputBus = (AudioUnitHelpers::getBusCount (&processor, false) > 0); - if ((! hasMainInputBus) && (! hasMainOutputBus)) + if ((! hasMainInputBus) && (! hasMainOutputBus)) { // midi effect plug-in: no audio AUChannelInfo info; @@ -743,6 +743,73 @@ struct AudioUnitHelpers return channelInfo; } + + //============================================================================== + static int getBusCount (const AudioProcessor* juceFilter, bool isInput) + { + int busCount = juceFilter->getBusCount (isInput); + + #ifdef JucePlugin_PreferredChannelConfigurations + short configs[][2] = {JucePlugin_PreferredChannelConfigurations}; + const int numConfigs = sizeof (configs) / sizeof (short[2]); + + bool hasOnlyZeroChannels = true; + + for (int i = 0; i < numConfigs && hasOnlyZeroChannels == true; ++i) + if (configs[i][isInput ? 0 : 1] != 0) + hasOnlyZeroChannels = false; + + busCount = jmin (busCount, hasOnlyZeroChannels ? 0 : 1); + #endif + + return busCount; + } + + static bool setBusesLayout (AudioProcessor* juceFilter, const AudioProcessor::BusesLayout& requestedLayouts) + { + #ifdef JucePlugin_PreferredChannelConfigurations + AudioProcessor::BusesLayout copy (requestedLayouts); + + for (int dir = 0; dir < 2; ++dir) + { + const bool isInput = (dir == 0); + + const int actualBuses = juceFilter->getBusCount (isInput); + const int auNumBuses = getBusCount (juceFilter, isInput); + Array& buses = (isInput ? copy.inputBuses : copy.outputBuses); + + for (int i = auNumBuses; i < actualBuses; ++i) + buses.add (AudioChannelSet::disabled()); + } + + return juceFilter->setBusesLayout (copy); + #else + return juceFilter->setBusesLayout (requestedLayouts); + #endif + } + + static AudioProcessor::BusesLayout getBusesLayout (const AudioProcessor* juceFilter) + { + #ifdef JucePlugin_PreferredChannelConfigurations + AudioProcessor::BusesLayout layout = juceFilter->getBusesLayout(); + + for (int dir = 0; dir < 2; ++dir) + { + const bool isInput = (dir == 0); + + const int actualBuses = juceFilter->getBusCount (isInput); + const int auNumBuses = getBusCount (juceFilter, isInput); + Array& buses = (isInput ? layout.inputBuses : layout.outputBuses); + + for (int i = auNumBuses; i < actualBuses; ++i) + buses.removeLast(); + } + + return layout; + #else + return juceFilter->getBusesLayout(); + #endif + } }; AudioUnitHelpers::AUChannelStreamOrder AudioUnitHelpers::StreamOrder::auChannelStreamOrder[] =