Browse Source

WASAPI: Fixed an issue where the AudioIODevice would not be stopped if the system goes to sleep

tags/2021-05-28
hogliux 8 years ago
parent
commit
60c664c83c
1 changed files with 41 additions and 13 deletions
  1. +41
    -13
      modules/juce_audio_devices/native/juce_win32_WASAPI.cpp

+ 41
- 13
modules/juce_audio_devices/native/juce_win32_WASAPI.cpp View File

@@ -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<IMMDevice> device;
ComSmartPtr<IAudioClient> client;
@@ -482,7 +488,7 @@ public:
Array<int> 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(); }


Loading…
Cancel
Save