When a user switches their playback device on Windows, my audio playing through waveOutWrite()
simply stops. Is there a way to make it continue on the other device?
I am using the WAVE_MAPPER
flag in waveOutOpen()
.
Here is my WaveOutOpen() code as requested:
WAVEFORMATEX waveFormat;
waveFormat.wFormatTag = WAVE_FORMAT_PCM; // Uncompressed sound format
waveFormat.nChannels = 2;
waveFormat.wBitsPerSample = 16;
waveFormat.nSamplesPerSec = 44100;
waveFormat.nBlockAlign = waveFormat.nChannels * ( waveFormat.wBitsPerSample / 8 );
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
waveFormat.cbSize = 0;
// Open the audio device
MMRESULT mmresult = waveOutOpen( &waveOut, WAVE_MAPPER, &waveFormat, DWORD( WaveOutCallback ), (UINT) this, CALLBACK_FUNCTION );
if( mmresult != MMSYSERR_NOERROR )
{
printf( "Sound card cannot be opened (code %s).\n\n", std::to_string( mmresult ).c_str() );
return;
}
soundCardOpened = true;
Update:
After opening the sound card, it keeps calling the callback function, which I've called WaveOutCallback()
, with the uMsg parameter set to MM_WOM_DONE
. This is working properly. However, once I switch my sound device to my bluetooth speaker, it stops playing audio and stops calling this callback function as well.
void CALLBACK WaveOutCallback( HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
{
printf( "WaveOutCallback %i %i\n", uMsg, rand() );
if( uMsg != WOM_DONE )
return;
// Audio is managed here (includes a call to WaveOutWrite())
ManageAudio();
}
The bluetooth speaker is working using other applications.
Update 2
I've read that waveOutWrite()
sends WOM_DONE
to the waveOutProc procedure, which is called WaveOutCallback()
in my code (as shown above).
It seems to me that once I switch the device, the WOM_DONE
is not called anymore for the last output buffer. Actually, after the last WOM_DONE
message, the callback does not print a message anymore.
Update 3
I might need to move my waveOutWrite()
call outside of the waveOutProc()
, as described in the following reference?
Applications should not call any system-defined functions from inside a callback function, except for
EnterCriticalSection
,LeaveCriticalSection
,midiOutLongMsg
,midiOutShortMsg
,OutputDebugString
,PostMessage
,PostThreadMessage
,SetEvent
,timeGetSystemTime
,timeGetTime
,timeKillEvent
, andtimeSetEvent
. Calling other wave functions will cause deadlock.
https://learn.microsoft.com/en-us/previous-versions/dd743869(v=vs.85)