diff --git a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp index 50ca20569a..97f7330340 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp +++ b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp @@ -34,9 +34,10 @@ MidiMessageCollector::~MidiMessageCollector() //============================================================================== void MidiMessageCollector::reset (const double newSampleRate) { + const ScopedLock sl (midiCallbackLock); + jassert (newSampleRate > 0); - const ScopedLock sl (midiCallbackLock); #if JUCE_DEBUG hasCalledReset = true; #endif @@ -47,6 +48,8 @@ void MidiMessageCollector::reset (const double newSampleRate) void MidiMessageCollector::addMessageToQueue (const MidiMessage& message) { + const ScopedLock sl (midiCallbackLock); + #if JUCE_DEBUG jassert (hasCalledReset); // you need to call reset() to set the correct sample rate before using this object #endif @@ -55,8 +58,6 @@ void MidiMessageCollector::addMessageToQueue (const MidiMessage& message) // for details of what the number should be. jassert (message.getTimeStamp() != 0); - const ScopedLock sl (midiCallbackLock); - auto sampleNumber = (int) ((message.getTimeStamp() - 0.001 * lastCallbackTime) * sampleRate); incomingMessages.addEvent (message, sampleNumber); @@ -70,6 +71,8 @@ void MidiMessageCollector::addMessageToQueue (const MidiMessage& message) void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer, const int numSamples) { + const ScopedLock sl (midiCallbackLock); + #if JUCE_DEBUG jassert (hasCalledReset); // you need to call reset() to set the correct sample rate before using this object #endif @@ -79,7 +82,6 @@ void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer, auto timeNow = Time::getMillisecondCounterHiRes(); auto msElapsed = timeNow - lastCallbackTime; - const ScopedLock sl (midiCallbackLock); lastCallbackTime = timeNow; if (! incomingMessages.isEmpty()) diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index e8208f2ccf..b6eb6b8596 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -2052,7 +2052,8 @@ private: //============================================================================== String name; CriticalSection lock; - bool wantsMidiMessages = false, initialised = false, isPowerOn = false; + std::atomic wantsMidiMessages { false }; + bool initialised = false, isPowerOn = false; bool lastProcessBlockCallWasBypass = false, vstSupportsBypass = false; mutable StringArray programNames; AudioBuffer outOfPlaceBuffer; diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp index 123b2e396e..37014a9295 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp @@ -806,6 +806,8 @@ AudioProcessorGraph::Node::Node (NodeID n, std::unique_ptr p) no void AudioProcessorGraph::Node::prepare (double newSampleRate, int newBlockSize, AudioProcessorGraph* graph, ProcessingPrecision precision) { + const ScopedLock lock (processorLock); + if (! isPrepared) { isPrepared = true; @@ -822,6 +824,8 @@ void AudioProcessorGraph::Node::prepare (double newSampleRate, int newBlockSize, void AudioProcessorGraph::Node::unprepare() { + const ScopedLock lock (processorLock); + if (isPrepared) { isPrepared = false; @@ -831,6 +835,8 @@ void AudioProcessorGraph::Node::unprepare() void AudioProcessorGraph::Node::setParentGraph (AudioProcessorGraph* const graph) const { + const ScopedLock lock (processorLock); + if (auto* ioProc = dynamic_cast (processor.get())) ioProc->setParentGraph (graph); } @@ -940,7 +946,12 @@ AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (std::unique_ptrsetPlayHead (getPlayHead()); Node::Ptr n (new Node (nodeID, std::move (newProcessor))); - nodes.add (n.get()); + + { + const ScopedLock sl (getCallbackLock()); + nodes.add (n.get()); + } + n->setParentGraph (this); topologyChanged(); return n; @@ -1233,7 +1244,7 @@ void AudioProcessorGraph::buildRenderingSequence() const ScopedLock sl (getCallbackLock()); - std::swap (renderSequenceFloat, newSequenceF); + std::swap (renderSequenceFloat, newSequenceF); std::swap (renderSequenceDouble, newSequenceD); } diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index f7ce5789fb..c8a1a0b5c5 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -143,7 +143,8 @@ public: const std::unique_ptr processor; Array inputs, outputs; - bool isPrepared = false, bypassed = false; + bool isPrepared = false; + std::atomic bypassed { false }; Node (NodeID, std::unique_ptr) noexcept; @@ -151,6 +152,8 @@ public: void prepare (double newSampleRate, int newBlockSize, AudioProcessorGraph*, ProcessingPrecision); void unprepare(); + CriticalSection processorLock; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Node) };