diff --git a/src/Qt/AudioPlaybackThread.cpp b/src/Qt/AudioPlaybackThread.cpp index 10f6c7518..ca63042e8 100644 --- a/src/Qt/AudioPlaybackThread.cpp +++ b/src/Qt/AudioPlaybackThread.cpp @@ -25,6 +25,8 @@ #include // for std::this_thread::sleep_for #include // for std::chrono::milliseconds #include +#include +#include using namespace juce; @@ -241,16 +243,21 @@ namespace openshot } } - // Play the audio + // Override Play and Stop to notify of state changes void AudioPlaybackThread::Play() { - // Start playing is_playing = true; + NotifyTransportStateChanged(); } - // Stop the audio void AudioPlaybackThread::Stop() { - // Stop playing is_playing = false; + NotifyTransportStateChanged(); + } + + void AudioPlaybackThread::NotifyTransportStateChanged() + { + std::lock_guard lock(transportMutex); + transportCondition.notify_all(); } // Start audio thread @@ -286,8 +293,13 @@ namespace openshot // Start the transport transport.start(); - while (!threadShouldExit() && transport.isPlaying() && is_playing) - std::this_thread::sleep_for(std::chrono::milliseconds(2)); + while (!threadShouldExit() && transport.isPlaying() && is_playing) { + // Wait until transport state changes or thread should exit + std::unique_lock lock(transportMutex); + transportCondition.wait_for(lock, std::chrono::milliseconds(10), [this]() { + return threadShouldExit() || !transport.isPlaying() || !is_playing; + }); + } // Stop audio and shutdown transport Stop(); diff --git a/src/Qt/AudioPlaybackThread.h b/src/Qt/AudioPlaybackThread.h index 8122e4f0b..582e95f13 100644 --- a/src/Qt/AudioPlaybackThread.h +++ b/src/Qt/AudioPlaybackThread.h @@ -86,12 +86,17 @@ class AudioDeviceManagerSingleton { bool is_playing; juce::TimeSliceThread time_thread; openshot::VideoCacheThread *videoCache; /// The cache thread (for pre-roll checking) + std::mutex transportMutex; + std::condition_variable transportCondition; /// Constructor AudioPlaybackThread(openshot::VideoCacheThread* cache); /// Destructor ~AudioPlaybackThread(); + /// Notify all + void NotifyTransportStateChanged(); + /// Set the current thread's reader void Reader(openshot::ReaderBase *reader);