1

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, and timeSetEvent. Calling other wave functions will cause deadlock.

https://learn.microsoft.com/en-us/previous-versions/dd743869(v=vs.85)

Z0q
  • 1,689
  • 3
  • 28
  • 57
  • This automagically 'just works' for me. This is on Windows 11, what version of Windows are you testing on? – Paul Sanders Jan 22 '22 at 22:12
  • @PaulSanders I'm testing on Windows 11 as well. When I am playing audio and switch my audio device, it simply stops – Z0q Jan 22 '22 at 23:25
  • Please show a minimal sample to help us reproduce the issue. – Jeaninez - MSFT Jan 24 '22 at 06:35
  • @Jeaninez-MSFT The sample is added and I also added a little bounty to the question :) – Z0q Feb 14 '22 at 11:41
  • This is not a reproducing sample, just a small piece of code. – Simon Mourier Feb 16 '22 at 18:35
  • @SimonMourier Well, excuse me, but a little kindness is appreciated. I posted the code which seemed most relevant to the issue to me. The file to manage the audio is 880 lines of code – Z0q Feb 17 '22 at 22:23
  • I added a little more: the `WaveOutCallback()` callback, which seems relevant as well. I believe somewhere between `waveOutOpen()` and the callback, it goes wrong already – Z0q Feb 17 '22 at 22:46
  • I'm just saying that if you want help, you should maximize your chances of getting help. – Simon Mourier Feb 18 '22 at 07:12

0 Answers0