From 7d2310795f6432a6a17a2cbc9be8b36e330f7680 Mon Sep 17 00:00:00 2001 From: reuk Date: Fri, 13 Dec 2019 22:44:20 +0000 Subject: [PATCH] Threadsafety improvements --- .../juce_audio_basics/mpe/juce_MPEUtils.cpp | 2 +- .../processors/juce_AudioProcessorGraph.cpp | 42 ++++++++++++++----- .../processors/juce_AudioProcessorGraph.h | 3 +- .../juce_AudioProcessorValueTreeState.cpp | 5 ++- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/modules/juce_audio_basics/mpe/juce_MPEUtils.cpp b/modules/juce_audio_basics/mpe/juce_MPEUtils.cpp index b8d973c20a..8ebc185b70 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEUtils.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPEUtils.cpp @@ -49,7 +49,7 @@ MPEChannelAssigner::MPEChannelAssigner (Range channelRange) int MPEChannelAssigner::findMidiChannelForNewNote (int noteNumber) noexcept { - if (numChannels == 1) + if (numChannels <= 1) return firstChannel; for (auto ch = firstChannel; (isLegacy || zone->isLowerZone() ? ch <= lastChannel : ch >= lastChannel); ch += channelIncrement) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp index 5f5c00da4e..462c3120cb 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp @@ -885,6 +885,7 @@ AudioProcessorGraph::AudioProcessorGraph() AudioProcessorGraph::~AudioProcessorGraph() { + cancelPendingUpdate(); clearRenderingSequence(); clear(); } @@ -962,6 +963,8 @@ AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (std::unique_ptr= 0;) { if (nodes.getUnchecked(i)->nodeID == nodeId) @@ -1227,22 +1230,34 @@ void AudioProcessorGraph::buildRenderingSequence() RenderSequenceBuilder builderD (*this, *newSequenceD); } + struct SampleRateAndBlockSize final + { + double sampleRate; + int blockSize; + }; + + const auto blockDetails = [&] { const ScopedLock sl (getCallbackLock()); - newSequenceF->prepareBuffers (getBlockSize()); - newSequenceD->prepareBuffers (getBlockSize()); - } + auto details = SampleRateAndBlockSize { getSampleRate(), getBlockSize() }; + newSequenceF->prepareBuffers (details.blockSize); + newSequenceD->prepareBuffers (details.blockSize); + return details; + }(); if (anyNodesNeedPreparing()) { - { - const ScopedLock sl (getCallbackLock()); - renderSequenceFloat.reset(); - renderSequenceDouble.reset(); - } + const ScopedLock sl (getCallbackLock()); + renderSequenceFloat.reset(); + renderSequenceDouble.reset(); for (auto* node : nodes) - node->prepare (getSampleRate(), getBlockSize(), this, getProcessingPrecision()); + node->prepare (blockDetails.sampleRate, + blockDetails.blockSize, + this, + getProcessingPrecision()); + + isPrepared = 1; } const ScopedLock sl (getCallbackLock()); @@ -1254,13 +1269,16 @@ void AudioProcessorGraph::buildRenderingSequence() void AudioProcessorGraph::handleAsyncUpdate() { buildRenderingSequence(); - isPrepared = 1; } //============================================================================== void AudioProcessorGraph::prepareToPlay (double sampleRate, int estimatedSamplesPerBlock) { - setRateAndBufferSizeDetails (sampleRate, estimatedSamplesPerBlock); + { + const ScopedLock sl (getCallbackLock()); + setRateAndBufferSizeDetails (sampleRate, estimatedSamplesPerBlock); + } + clearRenderingSequence(); if (MessageManager::getInstance()->isThisTheMessageThread()) @@ -1278,6 +1296,8 @@ void AudioProcessorGraph::releaseResources() { const ScopedLock sl (getCallbackLock()); + cancelPendingUpdate(); + isPrepared = 0; for (auto* n : nodes) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index ec77862b5d..5fd6dfa98d 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -145,7 +145,8 @@ public: const std::unique_ptr processor; Array inputs, outputs; - std::atomic isPrepared { false }, bypassed { false }; + bool isPrepared = false; + std::atomic bypassed { false }; Node (NodeID, std::unique_ptr) noexcept; diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp index cd0185c261..252dad8f14 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp @@ -258,7 +258,10 @@ AudioProcessorValueTreeState::AudioProcessorValueTreeState (AudioProcessor& p, U state.addListener (this); } -AudioProcessorValueTreeState::~AudioProcessorValueTreeState() {} +AudioProcessorValueTreeState::~AudioProcessorValueTreeState() +{ + stopTimer(); +} //============================================================================== RangedAudioParameter* AudioProcessorValueTreeState::createAndAddParameter (const String& paramID,