Browse Source

Improved the thread safety of AudioProcessorGraph

tags/2021-05-28
reuk Tom Poole 6 years ago
parent
commit
42be540c27
4 changed files with 25 additions and 8 deletions
  1. +6
    -4
      modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp
  2. +2
    -1
      modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
  3. +13
    -2
      modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
  4. +4
    -1
      modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h

+ 6
- 4
modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp View File

@@ -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())


+ 2
- 1
modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp View File

@@ -2052,7 +2052,8 @@ private:
//==============================================================================
String name;
CriticalSection lock;
bool wantsMidiMessages = false, initialised = false, isPowerOn = false;
std::atomic<bool> wantsMidiMessages { false };
bool initialised = false, isPowerOn = false;
bool lastProcessBlockCallWasBypass = false, vstSupportsBypass = false;
mutable StringArray programNames;
AudioBuffer<float> outOfPlaceBuffer;


+ 13
- 2
modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp View File

@@ -806,6 +806,8 @@ AudioProcessorGraph::Node::Node (NodeID n, std::unique_ptr<AudioProcessor> 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<AudioProcessorGraph::AudioGraphIOProcessor*> (processor.get()))
ioProc->setParentGraph (graph);
}
@@ -940,7 +946,12 @@ AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (std::unique_ptr<Aud
newProcessor->setPlayHead (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);
}


+ 4
- 1
modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h View File

@@ -143,7 +143,8 @@ public:
const std::unique_ptr<AudioProcessor> processor;
Array<Connection> inputs, outputs;
bool isPrepared = false, bypassed = false;
bool isPrepared = false;
std::atomic<bool> bypassed { false };
Node (NodeID, std::unique_ptr<AudioProcessor>) 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)
};


Loading…
Cancel
Save