From 60c664c83c4a1b1f6ce5de38bcc4981e34510b2b Mon Sep 17 00:00:00 2001 From: hogliux Date: Tue, 8 Aug 2017 14:29:37 +0100 Subject: [PATCH] WASAPI: Fixed an issue where the AudioIODevice would not be stopped if the system goes to sleep --- .../native/juce_win32_WASAPI.cpp | 54 ++++++++++++++----- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp index 52d0235fc2..7fb96aaee3 100644 --- a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp +++ b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp @@ -357,7 +357,8 @@ public: actualBufferSize (0), bytesPerSample (0), bytesPerFrame (0), - sampleRateHasChanged (false) + sampleRateHasChanged (false), + shouldClose (false) { clientEvent = CreateEvent (nullptr, false, false, nullptr); @@ -468,6 +469,11 @@ public: sampleRateHasChanged = true; } + void deviceBecameInactive() + { + shouldClose = true; + } + //============================================================================== ComSmartPtr device; ComSmartPtr client; @@ -482,7 +488,7 @@ public: Array channelMaps; UINT32 actualBufferSize; int bytesPerSample, bytesPerFrame; - bool sampleRateHasChanged; + bool sampleRateHasChanged, shouldClose; virtual void updateFormat (bool isFloat) = 0; @@ -498,10 +504,17 @@ private: JUCE_COMRESULT OnSimpleVolumeChanged (float, BOOL, LPCGUID) { return S_OK; } JUCE_COMRESULT OnChannelVolumeChanged (DWORD, float*, DWORD, LPCGUID) { return S_OK; } JUCE_COMRESULT OnGroupingParamChanged (LPCGUID, LPCGUID) { return S_OK; } - JUCE_COMRESULT OnStateChanged (AudioSessionState) { return S_OK; } + JUCE_COMRESULT OnStateChanged(AudioSessionState state) + { + if (state == AudioSessionStateInactive || state == AudioSessionStateExpired) + owner.deviceBecameInactive(); + + return S_OK; + } JUCE_COMRESULT OnSessionDisconnected (AudioSessionDisconnectReason reason) { + Logger::writeToLog("OnSessionDisconnected"); if (reason == DisconnectReasonFormatChanged) owner.deviceSampleRateChanged(); @@ -969,7 +982,8 @@ public: isStarted (false), currentBufferSizeSamples (0), currentSampleRate (0), - callback (nullptr) + callback (nullptr), + deviceBecameInactive (false) { } @@ -1107,6 +1121,8 @@ public: if (inputDevice != nullptr) ResetEvent (inputDevice->clientEvent); if (outputDevice != nullptr) ResetEvent (outputDevice->clientEvent); + deviceBecameInactive = false; + startThread (8); Thread::sleep (5); @@ -1226,8 +1242,14 @@ public: while (! threadShouldExit()) { - if (inputDevice != nullptr) + if (outputDevice != nullptr && outputDevice->shouldClose) + deviceBecameInactive = true; + + if (inputDevice != nullptr && ! deviceBecameInactive) { + if (inputDevice->shouldClose) + deviceBecameInactive = true; + if (outputDevice == nullptr) { if (WaitForSingleObject (inputDevice->clientEvent, 1000) == WAIT_TIMEOUT) @@ -1253,6 +1275,7 @@ public: } } + if (! deviceBecameInactive) { const ScopedTryLock sl (startStopLock); @@ -1263,7 +1286,7 @@ public: outs.clear(); } - if (outputDevice != nullptr) + if (outputDevice != nullptr && !deviceBecameInactive) { // Note that this function is handed the input device so it can check for the event and make sure // the input reservoir is filled up correctly even when bufferSize > device actualBufferSize @@ -1276,7 +1299,7 @@ public: } } - if (sampleRateHasChanged) + if (sampleRateHasChanged || deviceBecameInactive) { triggerAsyncUpdate(); break; // Quit the thread... will restart it later! @@ -1303,7 +1326,7 @@ private: bool isOpen_, isStarted; int currentBufferSizeSamples; double currentSampleRate; - bool sampleRateChangedByOutput; + bool sampleRateChangedByOutput, deviceBecameInactive; AudioIODeviceCallback* callback; CriticalSection startStopLock; @@ -1354,12 +1377,17 @@ private: outputDevice = nullptr; inputDevice = nullptr; - initialise(); - open (lastKnownInputChannels, lastKnownOutputChannels, - getChangedSampleRate(), currentBufferSizeSamples); + // sample rate change + if (! deviceBecameInactive) + { + initialise(); + + open (lastKnownInputChannels, lastKnownOutputChannels, + getChangedSampleRate(), currentBufferSizeSamples); - start (callback); + start (callback); + } } double getChangedSampleRate() const @@ -1481,7 +1509,7 @@ private: HRESULT STDMETHODCALLTYPE OnDeviceAdded (LPCWSTR) { return notify(); } HRESULT STDMETHODCALLTYPE OnDeviceRemoved (LPCWSTR) { return notify(); } - HRESULT STDMETHODCALLTYPE OnDeviceStateChanged (LPCWSTR, DWORD) { return notify(); } + HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR, DWORD) { return notify(); } HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged (EDataFlow, ERole, LPCWSTR) { return notify(); } HRESULT STDMETHODCALLTYPE OnPropertyValueChanged (LPCWSTR, const PROPERTYKEY) { return notify(); }