EDIT: I did not pass the appropriate flags into the initialize method, I think the Audio Sessions page on MSDN is slightly misleading in this regard as it seems to suggest it is default behavior, however the default behavior is that sessions are associated with the process, to allow them to terminate when a stream is released you need to pass:
AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED
http://msdn.microsoft.com/en-us/library/windows/desktop/dd370789(v=vs.85).aspx
Ok so I've been trying to get some audio working, essentially I want to have multiple windows open under the same process playing audio and video (audio is muted on all but topmost). I am having a problem when it comes to audio sessions, I create a unique session for each stream however the session doesn't close when I thought I closed down the stream.
My understanding is that sndvol will display sessions in active / inactive states and when you release all references to streams the session will set to expired and no longer appear in sndvol, however I find that for every stream I open a new session appears in sndvol but it won't be removed until the whole process ends, rather than when the audio thread ends (ie when I close a window / change inputs).
Here is my audio thread, I've stripped it down to its bare bones and the IAudioSessionControl
interface is just used to help me figure out the state of the session to debug, in the 'audio loop' it is active, everywhere else inactive, however I thought it would expire after I release pAudioClient
am I wrong here, what else should I be releasing?
WORD WINAPI
AudioThread (
LPVOID lpThreadParameter )
{
HRESULT hr;
PAUDIOPARMS pAudioParms = (PAUDIOPARMS)lpThreadParameter;
IMMDeviceEnumerator *pEnumerator = NULL;
IMMDevice *pDevice = NULL;
IAudioClient *pAudioClient = NULL;
IAudioSessionControl *pAudioSessionControl;
AudioSessionState audioSessionState;
GUID sessionGUID;
WAVEFORMATEXTENSIBLE *pwfx = NULL;
/* Initialise WASAPI interfaces and find audio endpoint. */
hr = CoCreateInstance ( &CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
&IID_IMMDeviceEnumerator, (void**)&pEnumerator);
EXIT_ON_ERROR(hr)
hr = pEnumerator->lpVtbl->GetDefaultAudioEndpoint(pEnumerator, eRender,
eConsole, &pDevice);
EXIT_ON_ERROR(hr)
SAFE_RELEASE ( pEnumerator );
hr = pDevice->lpVtbl->Activate(pDevice, &IID_IAudioClient, CLSCTX_ALL,
NULL, (void**)&pAudioClient);
EXIT_ON_ERROR(hr)
SAFE_RELEASE ( pDevice );
hr = pAudioClient->lpVtbl->GetMixFormat(pAudioClient,&pwfx);
CoCreateGuid ( &sessionGUID );
hr = pAudioClient->lpVtbl->Initialize ( pAudioClient, AUDCLNT_SHAREMODE_SHARED,
0, 853333, 0, pwfx, &sessionGUID );
if ( pwfx )
CoTaskMemFree ( pwfx );
hr = pAudioClient->lpVtbl->GetService ( pAudioClient, &IID_IAudioSessionControl, (void**)&pAudioSessionControl );
pAudioSessionControl->lpVtbl->GetState ( pAudioSessionControl, &audioSessionState );
hr = pAudioClient->lpVtbl->Start(pAudioClient);
EXIT_ON_ERROR(hr)
/* Allow OpenSharedAudio thread to continue. */
SetEvent ( pAudioParms->HStartEvent );
while (!pAudioParms->BClose)
{
/* Audio Loop. */
pAudioSessionControl->lpVtbl->GetState ( pAudioSessionControl, &audioSessionState );
}
hr = pAudioClient->lpVtbl->Stop(pAudioClient);
EXIT_ON_ERROR(hr)
Exit:
SAFE_RELEASE ( pAudioClient );
pAudioParms->Error = hr;
pAudioSessionControl->lpVtbl->GetState ( pAudioSessionControl, &audioSessionState );
SAFE_RELEASE ( pAudioSessionControl );
/* Allow OpenSharedAudio thread to continue. */
SetEvent ( pAudioParms->HStartEvent );
return 0;
}
I have SAFE_RELEASE()
defined as follows:
#define SAFE_RELEASE(pUnk) \
if ((pUnk) != NULL) \
{ (pUnk)->lpVtbl->Release(pUnk); (pUnk) = NULL; }