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

Fixed a bug where the AU/AUv3 wrapper would create a spurious input bus when no inputs where specified in the Projucer's legacy channel configuration field

This commit is contained in:
hogliux 2016-12-01 10:47:52 +00:00
parent a3ef455696
commit b86e1331ac
3 changed files with 105 additions and 26 deletions

View file

@ -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<size_t> (juceFilter->getBusCount (true)));
pulledSucceeded.calloc (static_cast<size_t> (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<int> (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<UInt32> (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<int> (GetScope(kAudioUnitScope_Input). GetNumberOfElements());
const int numOutputElements = static_cast<int> (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<Array<AudioChannelLayoutTag> >& 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<AudioChannelLayoutTag> 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);

View file

@ -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<AudioChannelSet>& 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<int> (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<int> (maxFrames));
@ -869,7 +869,7 @@ private:
{
ScopedPointer<NSMutableArray<AUAudioUnitBus*> > array = [[NSMutableArray<AUAudioUnitBus*> 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<BusBuffer>& 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)

View file

@ -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<AUChannelInfo> 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<AudioChannelSet>& 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<AudioChannelSet>& 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[] =