編集:初期化メソッドに適切なフラグを渡しませんでした。MSDN のオーディオ セッション ページは、これがデフォルトの動作であることを示唆しているように見えるため、この点で少し誤解を招くと思いますが、デフォルトの動作は、セッションがプロセスに関連付けられていることです。 、ストリームが解放されたときに終了できるようにするには、次を渡す必要があります。
AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED
http://msdn.microsoft.com/en-us/library/windows/desktop/dd370789(v=vs.85).aspx
基本的に、オーディオとビデオを再生する同じプロセスで複数のウィンドウを開きたいと思っています(オーディオは一番上を除いてミュートされています)。オーディオ セッションに関して問題があります。ストリームごとに一意のセッションを作成しますが、ストリームを閉じたと思ったときにセッションが閉じません。
私の理解では、sndvol はアクティブ/非アクティブ状態でセッションを表示し、ストリームへのすべての参照を解放すると、セッションは期限切れに設定され、sndvol には表示されなくなりますが、ストリームを開くたびに新しいセッションが sndvol に表示されることがわかりましたが、オーディオスレッドが終了するときではなく、プロセス全体が終了するまで削除されません(つまり、ウィンドウを閉じる/入力を変更するとき)。
ここに私のオーディオ スレッドがあります。私はそれを必要最低限の骨まで取り除きました。IAudioSessionControl
インターフェイスは、デバッグするセッションの状態を把握するのに役立つだけです。「オーディオ ループ」ではアクティブで、それ以外の場所では非アクティブですが、リリース後に期限切れになると思っていましたがpAudioClient
、ここで間違っていますか? 他に何をリリースすればよいですか?
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;
}
私はSAFE_RELEASE()
次のように定義しました。
#define SAFE_RELEASE(pUnk) \
if ((pUnk) != NULL) \
{ (pUnk)->lpVtbl->Release(pUnk); (pUnk) = NULL; }