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 2ee222a9ea..4496f07ef2 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm @@ -189,6 +189,7 @@ public: return err; mapper.alloc(); + pulledSucceeded.calloc (static_cast (juceFilter->getBusCount (true))); prepareToPlay(); @@ -199,6 +200,7 @@ public: { MusicDeviceBase::Cleanup(); + pulledSucceeded.free(); mapper.release(); if (juceFilter != nullptr) @@ -1086,9 +1088,7 @@ public: // use output pointers for (int busIdx = 0; busIdx < numOutputBuses; ++busIdx) { - if (! GetAudioBufferList (false, busIdx, buffer, interleaved, numChannels)) - continue; - + GetAudioBufferList (false, busIdx, buffer, interleaved, numChannels); const int* outLayoutMap = mapper.get (false, busIdx); for (int ch = 0; ch < numChannels; ++ch) @@ -1099,22 +1099,35 @@ public: for (int busIdx = 0; chIdx < totalInChannels;) { int channelIndexInBus = juceFilter->getOffsetInBusBufferForAbsoluteChannelIndex (true, chIdx, busIdx); + const bool badData = ! pulledSucceeded[busIdx]; - if (! GetAudioBufferList (true, busIdx, buffer, interleaved, numChannels)) - continue; + if (! badData) + GetAudioBufferList (true, busIdx, buffer, interleaved, numChannels); const int* inLayoutMap = mapper.get (true, busIdx); const int n = juceFilter->getChannelCountOfBus (true, busIdx); for (int ch = channelIndexInBus; ch < n; ++ch) - audioBuffer.setBuffer (chIdx++, interleaved ? nullptr : static_cast (buffer->mBuffers[inLayoutMap[ch]].mData)); + audioBuffer.setBuffer (chIdx++, interleaved || badData ? nullptr : static_cast (buffer->mBuffers[inLayoutMap[ch]].mData)); } } // copy input { for (int busIdx = 0; busIdx < numInputBuses; ++busIdx) - audioBuffer.push (GetInput ((UInt32) busIdx)->GetBufferList(), mapper.get (true, busIdx)); + { + if (pulledSucceeded[busIdx]) + { + audioBuffer.push (GetInput ((UInt32) busIdx)->GetBufferList(), mapper.get (true, busIdx)); + } + else + { + const int n = juceFilter->getChannelCountOfBus (true, busIdx); + + for (int ch = 0; ch < n; ++ch) + zeromem (audioBuffer.push(), sizeof (float) * nFrames); + } + } // clear remaining channels for (int i = totalInChannels; i < totalOutChannels; ++i) @@ -1504,6 +1517,7 @@ private: AUMIDIOutputCallbackStruct midiCallback; AudioTimeStamp lastTimeStamp; int totalInChannels, totalOutChannels; + HeapBlock pulledSucceeded; //============================================================================== Array channelInfo; @@ -1517,24 +1531,17 @@ private: void pullInputAudio (AudioUnitRenderActionFlags& flags, const AudioTimeStamp& timestamp, const UInt32 nFrames) noexcept { const unsigned int numInputBuses = GetScope (kAudioUnitScope_Input).GetNumberOfElements(); - OSStatus err; for (unsigned int i = 0; i < numInputBuses; ++i) { if (AUInputElement* input = GetInput (i)) { - err = input->PullInput (flags, timestamp, i, nFrames); - - if (err != noErr) - { - if (input->WillAllocateBuffer()) - input->PrepareBuffer (nFrames); - else - input->PrepareNullBuffer (nFrames); - } + const bool succeeded = (input->PullInput (flags, timestamp, i, nFrames) == noErr); - if ((flags & kAudioUnitRenderAction_OutputIsSilence) != 0 || err != noErr) + if ((flags & kAudioUnitRenderAction_OutputIsSilence) != 0 && succeeded) AudioUnitHelpers::clearAudioBuffer (input->GetBufferList()); + + pulledSucceeded[i] = succeeded; } } } @@ -1608,21 +1615,17 @@ private: midiCallback.midiOutputCallback (midiCallback.userData, &lastTimeStamp, 0, packetList); } - bool GetAudioBufferList (bool isInput, int busIdx, AudioBufferList*& bufferList, bool& interleaved, int& numChannels) + void GetAudioBufferList (bool isInput, int busIdx, AudioBufferList*& bufferList, bool& interleaved, int& numChannels) { - if (AUIOElement* element = GetElement (isInput ? kAudioUnitScope_Input : kAudioUnitScope_Output, static_cast (busIdx))->AsIOElement()) - { - bufferList = &element->GetBufferList(); + AUIOElement* element = GetElement (isInput ? kAudioUnitScope_Input : kAudioUnitScope_Output, static_cast (busIdx))->AsIOElement(); + jassert (element != nullptr); - if (bufferList->mNumberBuffers > 0) - { - interleaved = AudioUnitHelpers::isAudioBufferInterleaved (*bufferList); - numChannels = static_cast (interleaved ? bufferList->mBuffers[0].mNumberChannels : bufferList->mNumberBuffers); - return true; - } - } + bufferList = &element->GetBufferList(); - return false; + jassert (bufferList->mNumberBuffers > 0); + + interleaved = AudioUnitHelpers::isAudioBufferInterleaved (*bufferList); + numChannels = static_cast (interleaved ? bufferList->mBuffers[0].mNumberChannels : bufferList->mNumberBuffers); } //==============================================================================