//----------------------------------------------------------------------------- // Name: CStreamingSound::HandleWaveStreamNotification() // Desc: Handle the notification that tell us to put more wav data in the // circular buffer //----------------------------------------------------------------------------- HRESULT CStreamingSound::HandleWaveStreamNotification() { HRESULT hr; //DWORD dwCurrentPlayPos; //DWORD dwPlayDelta; //DWORD dwBytesWrittenToBuffer; //VOID* pDSLockedBuffer = NULL; //VOID* pDSLockedBuffer2 = NULL; //DWORD dwDSLockedBufferSize; //DWORD dwDSLockedBufferSize2; if( m_pDSB == NULL ) return CO_E_NOTINITIALIZED; // Restore the buffer if it was lost BOOL bRestored; if( FAILED( hr = RestoreBuffer( &bRestored ) ) ) return DXTRACE_ERR( TEXT("RestoreBuffer"), hr ); if( bRestored ) hr = FillBufferWithSound( TRUE ); //full it with data as it's restored else hr = FillBufferWithSound(FALSE); // add one frame into it for play // The buffer was restored, so we need to fill it with new data if( FAILED( hr) ) return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr ); return S_OK; }
HRESULT DDuplexAudio::HandleRenderNotification(void) { HRESULT hr; BOOL bRestored; if( FAILED( hr = RestoreBuffer( &bRestored ) ) ) return hr; if( bRestored ) hr = FillBufferWithSound( TRUE ); //full it with data as it's restored else hr = FillBufferWithSound(FALSE); // add one frame into it for play return hr; }
//----------------------------------------------------------------------------- // Name: CDSStreamingSound::Reset() // Desc: Resets the sound so it will begin playing at the beginning //----------------------------------------------------------------------------- HRESULT CDSStreamingSound::Reset() { HRESULT hr; if (!m_apDSBuffer[0] || !m_pWaveFile) return CO_E_NOTINITIALIZED; m_dwLastPlayPos = 0; m_dwPlayProgress = 0; m_dwNextWriteOffset = 0; m_dwTriggerWriteOffset = m_dwDSBufferSize - m_dwNotifySize; m_bFillNextNotificationWithSilence = FALSE; stopCount = 0; // Restore the buffer if it was lost BOOL bRestored; if (FAILED(hr = RestoreBuffer(m_apDSBuffer[0], &bRestored))) return DXTRACE_ERR(TEXT("RestoreBuffer"), hr); if (bRestored) if (FAILED(hr = FillBufferWithSound(m_apDSBuffer[0], FALSE))) return DXTRACE_ERR(TEXT("FillBufferWithSound"), hr); m_pWaveFile->Reset(); return m_apDSBuffer[0]->SetCurrentPosition(0L); }
/* =============== idAudioBufferWIN32::Play Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING in the dwFlags to loop the sound =============== */ int idAudioBufferWIN32::Play(dword dwPriority, dword dwFlags) { int hr; bool bRestored; if (m_apDSBuffer == NULL) { return -1; } // Restore the buffer if it was lost if (FAILED(hr = RestoreBuffer(m_apDSBuffer, &bRestored))) { common->Error(TEXT("RestoreBuffer"), hr); } if (bRestored) { // The buffer was restored, so we need to fill it with new data if (FAILED(hr = FillBufferWithSound(m_apDSBuffer, false))) { common->Error(TEXT("FillBufferWithSound"), hr); } // Make DirectSound do pre-processing on sound effects Reset(); } m_apDSBuffer->Play(0, dwPriority, dwFlags); return 0; }
//----------------------------------------------------------------------------- // Name: CStreamingSound::Reset() // Desc: Resets the sound so it will begin playing at the beginning //----------------------------------------------------------------------------- HRESULT CStreamingSound::Reset() { HRESULT hr; if( m_apDSBuffer[0] == NULL || m_pWaveFile == NULL ) return CO_E_NOTINITIALIZED; m_dwLastPlayPos = 0; m_dwPlayProgress = 0; m_dwNextWriteOffset = 0; m_bFillNextNotificationWithSilence = FALSE; // Restore the buffer if it was lost BOOL bRestored; if( FAILED( hr = RestoreBuffer( m_apDSBuffer[0], &bRestored ) ) ) return DXTRACE_ERR( TEXT("RestoreBuffer"), hr ); if( bRestored ) { // The buffer was restored, so we need to fill it with new data if( FAILED( hr = FillBufferWithSound( m_apDSBuffer[0], FALSE ) ) ) return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr ); } m_pWaveFile->ResetFile(); return m_apDSBuffer[0]->SetCurrentPosition( 0L ); }
//----------------------------------------------------------------------------- // Name: CSound::Play() // Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING // in the dwFlags to loop the sound //----------------------------------------------------------------------------- HRESULT CSound::Play( DWORD dwPriority, DWORD dwFlags ) { HRESULT hr; BOOL bRestored; if( m_apDSBuffer == NULL ) return CO_E_NOTINITIALIZED; LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer(); if( pDSB == NULL ) return DXTRACE_ERR( TEXT("GetFreeBuffer"), E_FAIL ); // Restore the buffer if it was lost if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) ) return DXTRACE_ERR( TEXT("RestoreBuffer"), hr ); if( bRestored ) { // The buffer was restored, so we need to fill it with new data if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) ) return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr ); // Make DirectSound do pre-processing on sound effects Reset(); } return pDSB->Play( 0, dwPriority, dwFlags ); }
//----------------------------------------------------------------------------- // Name: CDSSound::Play() // Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING // in the dwFlags to loop the sound //----------------------------------------------------------------------------- HRESULT CDSSound::Play(DWORD dwPriority, DWORD dwFlags, LONG lVolume, LONG lFrequency, LONG lPan, DWORD& outIndex) { HRESULT hr; BOOL bRestored; if (m_apDSBuffer == NULL) return CO_E_NOTINITIALIZED; LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer(outIndex); if (pDSB == NULL) return DXTRACE_ERR(TEXT("GetFreeBuffer"), E_FAIL); // Restore the buffer if it was lost if (FAILED(hr = RestoreBuffer(pDSB, &bRestored))) return DXTRACE_ERR(TEXT("RestoreBuffer"), hr); if (bRestored) { // The buffer was restored, so we need to fill it with new data if (FAILED(hr = FillBufferWithSound(pDSB, FALSE))) return DXTRACE_ERR(TEXT("FillBufferWithSound"), hr); } if (m_dwCreationFlags & DSBCAPS_CTRLVOLUME) pDSB->SetVolume(lVolume); if (lFrequency != -1 && (m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY)) pDSB->SetFrequency(lFrequency); if (m_dwCreationFlags & DSBCAPS_CTRLPAN) pDSB->SetPan(lPan); pDSB->SetCurrentPosition(0); return pDSB->Play(0, dwPriority, dwFlags); }
bool CN3SndObj::Create(const std::string& szFN, e_SndType eType) { if(NULL == s_lpDS) return false; if(SNDTYPE_2D != eType && SNDTYPE_3D != eType) return false; if(m_lpDSBuff) this->Init(); CWaveFile WaveFile; HRESULT hr = WaveFile.Open(szFN.c_str(), NULL, 1); //#define WAVEFILE_READ 1 if(FAILED(hr)) { #ifdef _N3GAME if(!szFN.empty()) CLogWriter::Write("CN3SndEng::LoadSource - WaveFile Open Failed.. (%s)", szFN.c_str()); #endif return false; } DSBUFFERDESC dsbd; ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) ); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwBufferBytes = WaveFile.GetSize(); dsbd.lpwfxFormat = WaveFile.m_pwfx; if(SNDTYPE_2D == eType) // 2D 음원 { dsbd.dwFlags = DSBCAPS_CTRLVOLUME; // | DSBCAPS_STATIC; } else if(SNDTYPE_3D == eType) //3D 음원.. { dsbd.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_MUTE3DATMAXDISTANCE; // | DSBCAPS_STATIC; dsbd.guid3DAlgorithm = DS3DALG_HRTF_LIGHT; } hr = s_lpDS->CreateSoundBuffer( &dsbd, &m_lpDSBuff, NULL ); if(FAILED(hr)) { #ifdef _N3GAME CLogWriter::Write("CN3SndObj::Create - CreateSoundBuffer Failed.. (%)", szFN.c_str()); #endif return false; } if(!FillBufferWithSound(&WaveFile)) { #ifdef _N3GAME CLogWriter::Write("CN3SndObj::Create - FillBufferWithSound Failed.. (%)", szFN.c_str()); #endif return false; } m_lpDSBuff->SetCurrentPosition(0); if(SNDTYPE_3D == eType) //3D 음원.. if(S_OK != m_lpDSBuff->QueryInterface(IID_IDirectSound3DBuffer, (VOID**)(&m_lpDS3DBuff))) return false; m_szFileName = szFN; // 파일 이름을 기록한다.. s_bNeedDeferredTick = true; // 3D Listener CommitDeferredSetting return true; }
/* =============== idAudioBufferWIN32::idAudioBuffer =============== */ idAudioBufferWIN32::idAudioBufferWIN32( LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile* pWaveFile ) { m_apDSBuffer = apDSBuffer; m_dwDSBufferSize = dwDSBufferSize; m_pWaveFile = pWaveFile; if (pWaveFile) { FillBufferWithSound( m_apDSBuffer, false ); m_apDSBuffer->SetCurrentPosition(0); } }
//----------------------------------------------------------------------------- // Name: CDSSound::CDSSound() // Desc: Constructs the class //----------------------------------------------------------------------------- CDSSound::CDSSound(LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD DSBufferSize, DWORD dwNumBuffers, Audio::CAudioFile* pWaveFile, DWORD dwCreationFlags) { m_apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers]; n_assert(m_apDSBuffer); for (DWORD i = 0; i < dwNumBuffers; ++i) m_apDSBuffer[i] = apDSBuffer[i]; m_dwDSBufferSize = DSBufferSize; m_dwNumBuffers = dwNumBuffers; m_pWaveFile = pWaveFile; m_dwCreationFlags = dwCreationFlags; FillBufferWithSound(m_apDSBuffer[0], FALSE); }
//----------------------------------------------------------------------------- // Name: CSound::Play3D() // Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING // in the dwFlags to loop the sound //----------------------------------------------------------------------------- HRESULT CSound::Play3D( LPDS3DBUFFER p3DBuffer, DWORD dwPriority, DWORD dwFlags, LONG lFrequency ) { HRESULT hr; BOOL bRestored; DWORD dwBaseFrequency; if( m_apDSBuffer == NULL ) return CO_E_NOTINITIALIZED; IDirectSoundBuffer* pDSB = GetFreeBuffer(); if( pDSB == NULL ) return DXTRACE_ERR( TEXT("GetFreeBuffer"), E_FAIL ); // Restore the buffer if it was lost if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) ) return DXTRACE_ERR( TEXT("RestoreBuffer"), hr ); if( bRestored ) { // The buffer was restored, so we need to fill it with new data if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) ) return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr ); } if( m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY ) { pDSB->GetFrequency( &dwBaseFrequency ); pDSB->SetFrequency( dwBaseFrequency + lFrequency ); } // QI for the 3D buffer IDirectSound3DBuffer* pDS3DBuffer; hr = pDSB->QueryInterface( IID_IDirectSound3DBuffer, (VOID**) &pDS3DBuffer ); if( SUCCEEDED( hr ) ) { hr = pDS3DBuffer->SetAllParameters( p3DBuffer, DS3D_IMMEDIATE ); if( SUCCEEDED( hr ) ) { hr = pDSB->Play( 0, dwPriority, dwFlags ); } pDS3DBuffer->Release(); } return hr; }
//----------------------------------------------------------------------------- // Name: CSound::CSound() // Desc: Constructs the class //----------------------------------------------------------------------------- CSound::CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize, DWORD dwNumBuffers, CPCMFile* CPCMFile ) { DWORD i; m_apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers]; for( i=0; i<dwNumBuffers; i++ ) m_apDSBuffer[i] = apDSBuffer[i]; m_dwDSBufferSize = dwDSBufferSize; m_dwNumBuffers = dwNumBuffers; m_pPCMFile = CPCMFile; FillBufferWithSound( m_apDSBuffer[0], FALSE ); // Make DirectSound do pre-processing on sound effects for( i=0; i<dwNumBuffers; i++ ) m_apDSBuffer[i]->SetCurrentPosition(0); }
//----------------------------------------------------------------------------- // Name: CSound::CSound() // Desc: Constructs the class //----------------------------------------------------------------------------- CSound::CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize, DWORD dwNumBuffers, CWaveFile* pWaveFile, DWORD dwCreationFlags ) { DWORD i; m_apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers]; if( NULL != m_apDSBuffer ) { for( i=0; i<dwNumBuffers; i++ ) m_apDSBuffer[i] = apDSBuffer[i]; m_dwDSBufferSize = dwDSBufferSize; m_dwNumBuffers = dwNumBuffers; m_pWaveFile = pWaveFile; m_dwCreationFlags = dwCreationFlags; FillBufferWithSound( m_apDSBuffer[0], FALSE ); } }
//----------------------------------------------------------------------------- // Name: CDSSound::Play3D() // Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING // in the dwFlags to loop the sound //----------------------------------------------------------------------------- HRESULT CDSSound::Play3D(LPDS3DBUFFER p3DBuffer, DWORD dwPriority, DWORD dwFlags, LONG lVolume, LONG lFrequency, DWORD& outIndex) { HRESULT hr; BOOL bRestored; DWORD dwBaseFrequency; if (!m_apDSBuffer) return CO_E_NOTINITIALIZED; LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer(outIndex); if (!pDSB) return DXTRACE_ERR(TEXT("GetFreeBuffer"), E_FAIL); // Restore the buffer if it was lost if (FAILED(hr = RestoreBuffer(pDSB, &bRestored))) return DXTRACE_ERR(TEXT("RestoreBuffer"), hr); if (bRestored) if (FAILED(hr = FillBufferWithSound(pDSB, FALSE))) return DXTRACE_ERR(TEXT("FillBufferWithSound"), hr); if (m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY) { pDSB->GetFrequency(&dwBaseFrequency); pDSB->SetFrequency(dwBaseFrequency + lFrequency); } if (m_dwCreationFlags & DSBCAPS_CTRLVOLUME) pDSB->SetVolume(lVolume); // QI for the 3D buffer LPDIRECTSOUND3DBUFFER pDS3DBuffer; hr = pDSB->QueryInterface(IID_IDirectSound3DBuffer, (VOID**) &pDS3DBuffer); if (SUCCEEDED(hr)) { hr = pDS3DBuffer->SetAllParameters(p3DBuffer, DS3D_IMMEDIATE); if (SUCCEEDED(hr)) { hr = pDSB->SetCurrentPosition(0); hr = pDSB->Play(0, dwPriority, dwFlags); } pDS3DBuffer->Release(); } return hr; }
//----------------------------------------------------------------------------- // Name: CSound::CSound() // Desc: Constructs the class //----------------------------------------------------------------------------- CSound::CSound( IDirectSoundBuffer** apDSBuffer, DWORD dwDSBufferSize, DWORD dwNumBuffers, CWaveFile* pWaveFile, DWORD dwCreationFlags ) { DWORD i; if( dwNumBuffers <= 0 ) return; m_apDSBuffer = new IDirectSoundBuffer*[dwNumBuffers]; if( NULL != m_apDSBuffer ) { for( i=0; i<dwNumBuffers; i++ ) m_apDSBuffer[i] = apDSBuffer[i]; m_dwDSBufferSize = dwDSBufferSize; m_dwNumBuffers = dwNumBuffers; m_pWaveFile = pWaveFile; m_dwCreationFlags = dwCreationFlags; FillBufferWithSound( m_apDSBuffer[0], FALSE ); } }
// //////////////////////////////////////////////////////////////////// // // //////////////////////////////////////////////////////////////////// bool DirectSound8AudioBuffer::VOnRestore() { HRESULT hr; BOOL bRestored; // Restore the buffer if it was lost if(FAILED(hr = RestoreBuffer(&bRestored))) { GF_LOG_TRACE_ERR("DirectSound8AudioBuffer::VOnRestore()", "Failed to restore the buffer"); return (false); } if(bRestored) { // The buffer was restored, so we need to fill it with new data if(FAILED(hr = FillBufferWithSound())) { GF_LOG_TRACE_ERR("DirectSound8AudioBuffer::VOnRestore()", "Failed to fill the buffer with sound"); return (false); } } else { GF_LOG_TRACE_ERR("DirectSound8AudioBuffer::VOnRestore()", "Failed to restore the buffer so cannot fill it with sound"); } return (true); }
// //////////////////////////////////////////////////////////////////// // // //////////////////////////////////////////////////////////////////// DirectSound8AudioBuffer::DirectSound8AudioBuffer(LPDIRECTSOUNDBUFFER sample, shared_ptr<SoundResHandle> resource)\ : AudioBuffer(resource), m_Sample(sample) { FillBufferWithSound(); }
//----------------------------------------------------------------------------- // Name: CDSStreamingSound::HandleWaveStreamNotification() // Desc: Handle the notification that tells us to put more wav data in the // circular buffer //----------------------------------------------------------------------------- HRESULT CDSStreamingSound::HandleWaveStreamNotification(BOOL bLoopedPlay) { if (!m_apDSBuffer || !m_pWaveFile) return CO_E_NOTINITIALIZED; HRESULT hr; DWORD dwCurrentPlayPos; DWORD dwPlayDelta; DWORD dwBytesWrittenToBuffer; VOID* pDSLockedBuffer = NULL; VOID* pDSLockedBuffer2 = NULL; DWORD dwDSLockedBufferSize; DWORD dwDSLockedBufferSize2; // Restore the buffer if it was lost BOOL bRestored; if (FAILED(hr = RestoreBuffer(m_apDSBuffer[0], &bRestored))) return DXTRACE_ERR(TEXT("RestoreBuffer"), hr); if (bRestored) { // The buffer was restored, so we need to fill it with new data if (FAILED(hr = FillBufferWithSound(m_apDSBuffer[0], FALSE))) return DXTRACE_ERR(TEXT("FillBufferWithSound"), hr); return S_OK; } // Lock the DirectSound buffer if (FAILED(hr = m_apDSBuffer[0]->Lock(m_dwNextWriteOffset, m_dwNotifySize, &pDSLockedBuffer, &dwDSLockedBufferSize, &pDSLockedBuffer2, &dwDSLockedBufferSize2, 0L))) return DXTRACE_ERR(TEXT("Lock"), hr); // m_dwDSBufferSize and m_dwNextWriteOffset are both multiples of m_dwNotifySize, // it should the second buffer, so it should never be valid if (pDSLockedBuffer2) return E_UNEXPECTED; WORD BitsPerSample = m_pWaveFile->GetFormat()->wBitsPerSample; if (!m_bFillNextNotificationWithSilence) { dwBytesWrittenToBuffer = m_pWaveFile->Read((char*) pDSLockedBuffer, dwDSLockedBufferSize); } else { // Fill the DirectSound buffer with silence this->stopCount++; FillMemory(pDSLockedBuffer, dwDSLockedBufferSize, (BYTE)(BitsPerSample == 8 ? 128 : 0)); dwBytesWrittenToBuffer = dwDSLockedBufferSize; } // If the number of bytes written is less than the // amount we requested, we have a short file. if (dwBytesWrittenToBuffer < dwDSLockedBufferSize) { if (!bLoopedPlay) { // Fill in silence for the rest of the buffer. FillMemory((BYTE*) pDSLockedBuffer + dwBytesWrittenToBuffer, dwDSLockedBufferSize - dwBytesWrittenToBuffer, (BYTE)(BitsPerSample == 8 ? 128 : 0)); // Any future notifications should just fill the buffer with silence m_bFillNextNotificationWithSilence = TRUE; } else { // We are looping, so reset the file and fill the buffer with wav data DWORD dwReadSoFar = dwBytesWrittenToBuffer; // From previous call above. while (dwReadSoFar < dwDSLockedBufferSize) { // This will keep reading in until the buffer is full (for very short files). m_pWaveFile->Reset(); dwBytesWrittenToBuffer = m_pWaveFile->Read((char*)pDSLockedBuffer + dwReadSoFar, dwDSLockedBufferSize - dwReadSoFar); n_assert(dwBytesWrittenToBuffer > 0); dwReadSoFar += dwBytesWrittenToBuffer; } } } // Unlock the DirectSound buffer m_apDSBuffer[0]->Unlock(pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0); // Figure out how much data has been played so far. When we have played // past the end of the file, we will either need to start filling the // buffer with silence or starting reading from the beginning of the file, // depending if the user wants to loop the sound if (FAILED(hr = m_apDSBuffer[0]->GetCurrentPosition(&dwCurrentPlayPos, NULL))) return DXTRACE_ERR(TEXT("GetCurrentPosition"), hr); // Check to see if the position counter looped if (dwCurrentPlayPos < m_dwLastPlayPos) dwPlayDelta = (m_dwDSBufferSize - m_dwLastPlayPos) + dwCurrentPlayPos; else dwPlayDelta = dwCurrentPlayPos - m_dwLastPlayPos; m_dwPlayProgress += dwPlayDelta; m_dwLastPlayPos = dwCurrentPlayPos; // If we are now filling the buffer with silence, then we have found the end so // check to see if the entire sound has played, if it has then stop the buffer. if (m_bFillNextNotificationWithSilence) { // We don't want to cut off the sound before it's done playing. if (m_dwPlayProgress >= (DWORD)m_pWaveFile->GetSize()) m_apDSBuffer[0]->Stop(); } // Update where the buffer will lock (for next time) m_dwNextWriteOffset += dwDSLockedBufferSize; m_dwTriggerWriteOffset = m_dwNextWriteOffset - m_dwNotifySize; m_dwNextWriteOffset %= m_dwDSBufferSize; // Circular buffer m_dwTriggerWriteOffset %= m_dwDSBufferSize; return S_OK; }
void DDuplexAudio::Execute(Thread::Arg arg) { DWORD dwResult; HRESULT hr; LOGINFO("DDuplexAudio Starting up ..."); ResetCapture(); ResetPlay(); FillBufferWithSound(TRUE); //full it first with silence first. if (FAILED(hr = StartCapture()) || FAILED(hr = StartPlay())) { LOGWARNING("DDuplexAudio::Execute:Failed to start Capturing or Playing,shutting down..."); Shutdown(); } while (!_is_shutdown_requested) { dwResult = MsgWaitForMultipleObjects( 2, &_events[0], FALSE, INFINITE, QS_ALLEVENTS ); switch( dwResult ) { case WAIT_OBJECT_0 + 0: // rendering notification is signaled // This means that DirectSound just finished playing // a piece of the buffer, so we need to fill the circular // buffer with new sound from the wav file if( FAILED( hr = HandleRenderNotification() ) ) { //DXTRACE_ERR( TEXT("RecordCapturedData"), hr ); //MessageBox( NULL, TEXT("Error handling DirectSound notifications. Sample will now exit."), TEXT("DirectSound Sample"), // MB_OK | MB_ICONERROR ); LOGDEBUG("DDuplexAudio::Execute:Failed to HandleRenderNotification,shutting down..."); _is_shutdown_requested = TRUE; } break; case WAIT_OBJECT_0 + 1: // capturing notification is signaled // This means that DirectSound just finished capturing // a piece of the buffer, so we can copy the captured data from the recorder buffer. if( FAILED( hr = HandleCaptureNotification() ) ) { //DXTRACE_ERR( TEXT("RecordCapturedData"), hr ); //MessageBox( NULL, TEXT("Error handling DirectSound notifications. Sample will now exit."), TEXT("DirectSound Sample"), // MB_OK | MB_ICONERROR ); LOGDEBUG("DDuplexAudio::Execute:Failed to HandleCaptureNotification,shutting down..."); _is_shutdown_requested = TRUE; } break; case WAIT_OBJECT_0 + 2: //// Windows messages are available //while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) //{ // if( !IsDialogMessage( hDlg, &msg ) ) // { // TranslateMessage( &msg ); // DispatchMessage( &msg ); // } // if( msg.message == WM_QUIT ) // bDone = TRUE; default : break; } } StopCapture(); StopPlay(); LOGINFO("DDuplexAudio shutdowned."); }