Browse Source

Fixed trying to write to invalid input buffer when AUs connected to the input of an AU fail

tags/2021-05-28
hogliux 9 years ago
parent
commit
ef50b8d89f
1 changed files with 33 additions and 30 deletions
  1. +33
    -30
      modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm

+ 33
- 30
modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm View File

@@ -189,6 +189,7 @@ public:
return err;
mapper.alloc();
pulledSucceeded.calloc (static_cast<size_t> (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<float*> (buffer->mBuffers[inLayoutMap[ch]].mData));
audioBuffer.setBuffer (chIdx++, interleaved || badData ? nullptr : static_cast<float*> (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<bool> pulledSucceeded;
//==============================================================================
Array<AUChannelInfo> 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<UInt32> (busIdx))->AsIOElement())
{
bufferList = &element->GetBufferList();
AUIOElement* element = GetElement (isInput ? kAudioUnitScope_Input : kAudioUnitScope_Output, static_cast<UInt32> (busIdx))->AsIOElement();
jassert (element != nullptr);
if (bufferList->mNumberBuffers > 0)
{
interleaved = AudioUnitHelpers::isAudioBufferInterleaved (*bufferList);
numChannels = static_cast<int> (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<int> (interleaved ? bufferList->mBuffers[0].mNumberChannels : bufferList->mNumberBuffers);
}
//==============================================================================


Loading…
Cancel
Save