diff --git a/examples/Plugins/AudioPluginDemo.h b/examples/Plugins/AudioPluginDemo.h index ce147cb9b9..365e0ab02c 100644 --- a/examples/Plugins/AudioPluginDemo.h +++ b/examples/Plugins/AudioPluginDemo.h @@ -185,8 +185,6 @@ public: { std::make_unique ("gain", "Gain", NormalisableRange (0.0f, 1.0f), 0.9f), std::make_unique ("delay", "Delay Feedback", NormalisableRange (0.0f, 1.0f), 0.5f) }) { - lastPosInfo.resetToDefault(); - // Add a sub-tree to store the state of our UI state.state.addChild ({ "uiState", { { "width", 400 }, { "height", 200 } }, {} }, -1, nullptr); @@ -324,6 +322,33 @@ public: return trackProperties; } + class SpinLockedPosInfo + { + public: + SpinLockedPosInfo() { info.resetToDefault(); } + + // Wait-free, but setting new info may fail if the main thread is currently + // calling `get`. This is unlikely to matter in practice because + // we'll be calling `set` much more frequently than `get`. + void set (const AudioPlayHead::CurrentPositionInfo& newInfo) + { + const juce::SpinLock::ScopedTryLockType lock (mutex); + + if (lock.isLocked()) + info = newInfo; + } + + AudioPlayHead::CurrentPositionInfo get() const noexcept + { + const juce::SpinLock::ScopedLockType lock (mutex); + return info; + } + + private: + juce::SpinLock mutex; + AudioPlayHead::CurrentPositionInfo info; + }; + //============================================================================== // These properties are public so that our editor component can access them // A bit of a hacky way to do it, but it's only a demo! Obviously in your own @@ -335,7 +360,7 @@ public: // this keeps a copy of the last set of time info that was acquired during an audio // callback - the UI component will read this and display it. - AudioPlayHead::CurrentPositionInfo lastPosInfo; + SpinLockedPosInfo lastPosInfo; // Our plug-in's current state AudioProcessorValueTreeState state; @@ -422,7 +447,7 @@ private: void timerCallback() override { - updateTimecodeDisplay (getProcessor().lastPosInfo); + updateTimecodeDisplay (getProcessor().lastPosInfo.get()); } void hostMIDIControllerIsAvailable (bool controllerIsAvailable) override @@ -622,19 +647,23 @@ private: void updateCurrentTimeInfoFromHost() { - if (auto* ph = getPlayHead()) + const auto newInfo = [&] { - AudioPlayHead::CurrentPositionInfo newTime; - - if (ph->getCurrentPosition (newTime)) + if (auto* ph = getPlayHead()) { - lastPosInfo = newTime; // Successfully got the current time from the host.. - return; - } - } + AudioPlayHead::CurrentPositionInfo result; - // If the host fails to provide the current time, we'll just reset our copy to a default.. - lastPosInfo.resetToDefault(); + if (ph->getCurrentPosition (result)) + return result; + } + + // If the host fails to provide the current time, we'll just use default values + AudioPlayHead::CurrentPositionInfo result; + result.resetToDefault(); + return result; + }(); + + lastPosInfo.set (newInfo); } static BusesProperties getBusesProperties()