HRESULT SetCapturenotification(LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB){ #define cEvent 3 LPDIRECTSOUNDNOTIFY8 pDSBNotify; WAVEFORMATEX wfx; HANDLE rghEvent[cEvent]; DSBPOSITIONNOTIFY rgdsbpn[cEvent]; HRESULT hr; if (NULL == pDSCB) return E_INVALIDARG; if (FAILED(hr = pDSCB->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&pDSBNotify))){ return hr; } if (FAILED(hr = pDSCB->GetFormat(&wfx, sizeof(WAVEFORMATEX), NULL))) return hr; for (int i = 0; i< cEvent; ++i){ rghEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL); if (rghEvent[i] == NULL){ hr = GetLastError(); return hr; } } rgdsbpn[0].dwOffset = wfx.nAvgBytesPerSec/2 - 1; rgdsbpn[0].hEventNotify = rghEvent[0]; rgdsbpn[1].dwOffset = wfx.nAvgBytesPerSec - 1; rgdsbpn[1].hEventNotify = rghEvent[1]; rgdsbpn[2].dwOffset = DSBPN_OFFSETSTOP; rgdsbpn[2].hEventNotify = rghEvent[2]; hr = pDSBNotify->SetNotificationPositions(cEvent, rgdsbpn); pDSBNotify->Release(); return hr; }
//设置播放通知,一般用处有二: //1. 通知程序写入下一段声音数据 //2. 通知做某一个操作 HRESULT SetStopNotification(HANDLE hEvent, LPDIRECTSOUNDBUFFER8 lpDsbSecondary){ LPDIRECTSOUNDNOTIFY8 lpDsNotify; DSBPOSITIONNOTIFY PositionNotify; HRESULT hr; if (SUCCEEDED(hr = lpDsbSecondary->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)lpDsNotify) )){ PositionNotify.dwOffset = DSBPN_OFFSETSTOP; PositionNotify.hEventNotify = hEvent; hr = lpDsNotify->SetNotificationPositions(1, &PositionNotify); lpDsNotify->Release(); } return hr; }
void DXAudioInput::run() { LPDIRECTSOUNDCAPTURE8 pDSCapture; LPDIRECTSOUNDCAPTUREBUFFER pDSCaptureBuffer; LPDIRECTSOUNDNOTIFY8 pDSNotify; DWORD dwBufferSize; bool bOk; DWORD dwReadyBytes = 0; DWORD dwLastReadPos = 0; DWORD dwReadPosition; DWORD dwCapturePosition; LPVOID aptr1, aptr2; DWORD nbytes1, nbytes2; HRESULT hr; WAVEFORMATEX wfx; DSCBUFFERDESC dscbd; pDSCapture = NULL; pDSCaptureBuffer = NULL; pDSNotify = NULL; bOk = false; bool failed = false; float safety = 2.0f; bool didsleep = false; bool firstsleep = false; Timer t; ZeroMemory(&wfx, sizeof(wfx)); wfx.wFormatTag = WAVE_FORMAT_PCM; ZeroMemory(&dscbd, sizeof(dscbd)); dscbd.dwSize = sizeof(dscbd); dscbd.dwBufferBytes = dwBufferSize = iFrameSize * sizeof(short) * NBUFFBLOCKS; dscbd.lpwfxFormat = &wfx; wfx.nChannels = 1; wfx.nSamplesPerSec = iSampleRate; wfx.nBlockAlign = 2; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.wBitsPerSample = 16; // Create IDirectSoundCapture using the preferred capture device if (! g.s.qbaDXInput.isEmpty()) { LPGUID lpguid = reinterpret_cast<LPGUID>(g.s.qbaDXInput.data()); if (FAILED(hr = DirectSoundCaptureCreate8(lpguid, &pDSCapture, NULL))) { failed = true; } } if (! pDSCapture && FAILED(hr = DirectSoundCaptureCreate8(&DSDEVID_DefaultVoiceCapture, &pDSCapture, NULL))) qWarning("DXAudioInput: DirectSoundCaptureCreate failed: hr=0x%08lx", hr); else if (FAILED(hr = pDSCapture->CreateCaptureBuffer(&dscbd, &pDSCaptureBuffer, NULL))) qWarning("DXAudioInput: CreateCaptureBuffer failed: hr=0x%08lx", hr); else if (FAILED(hr = pDSCaptureBuffer->QueryInterface(IID_IDirectSoundNotify, reinterpret_cast<void **>(&pDSNotify)))) qWarning("DXAudioInput: QueryInterface (Notify) failed: hr=0x%08lx", hr); else bOk = true; if (failed) g.mw->msgBox(tr("Opening chosen DirectSound Input failed. Default device will be used.")); qWarning("DXAudioInput: Initialized"); if (! bOk) goto cleanup; if (FAILED(hr = pDSCaptureBuffer->Start(DSCBSTART_LOOPING))) { qWarning("DXAudioInput: Start failed: hr=0x%08lx", hr); } else { while (bRunning) { firstsleep = true; didsleep = false; do { if (FAILED(hr = pDSCaptureBuffer->GetCurrentPosition(&dwCapturePosition, &dwReadPosition))) { qWarning("DXAudioInput: GetCurrentPosition failed: hr=0x%08lx", hr); bRunning = false; break; } if (dwReadPosition < dwLastReadPos) dwReadyBytes = (dwBufferSize - dwLastReadPos) + dwReadPosition; else dwReadyBytes = dwReadPosition - dwLastReadPos; if (static_cast<int>(dwReadyBytes) < sizeof(short) * iFrameSize) { double msecleft = 20.0 - (dwReadyBytes * 20.0) / (sizeof(short) * iFrameSize); if (didsleep) safety *= 1.1f; else if (firstsleep) safety *= 0.998f; int msec = static_cast<int>(msecleft + (firstsleep ? safety : 0.0)); msleep(msec); didsleep = true; firstsleep = false; } } while (static_cast<int>(dwReadyBytes) < sizeof(short) * iFrameSize); // Desynchonized? if (dwReadyBytes > (dwBufferSize / 2)) { qWarning("DXAudioInput: Lost synchronization"); dwLastReadPos = dwReadPosition; } else if (bRunning) { if (FAILED(hr = pDSCaptureBuffer->Lock(dwLastReadPos, sizeof(short) * iFrameSize, &aptr1, &nbytes1, &aptr2, &nbytes2, 0))) { qWarning("DXAudioInput: Lock from %ld (%d bytes) failed: hr=0x%08lx",dwLastReadPos, sizeof(short) * iFrameSize, hr); bRunning = false; break; } if (aptr1 && nbytes1) CopyMemory(psMic, aptr1, nbytes1); if (aptr2 && nbytes2) CopyMemory(psMic+nbytes1/2, aptr2, nbytes2); if (FAILED(hr = pDSCaptureBuffer->Unlock(aptr1, nbytes1, aptr2, nbytes2))) { qWarning("DXAudioInput: Unlock failed: hr=0x%08lx", hr); bRunning = false; break; } dwLastReadPos = (dwLastReadPos + sizeof(short) * iFrameSize) % dwBufferSize; encodeAudioFrame(); } } if (! FAILED(hr)) pDSCaptureBuffer->Stop(); } if (FAILED(hr)) { g.mw->msgBox(tr("Lost DirectSound input device.")); } cleanup: if (! bOk) { g.mw->msgBox(tr("Opening chosen DirectSound Input device failed. No microphone capture will be done.")); } if (pDSNotify) pDSNotify->Release(); if (pDSCaptureBuffer) pDSCaptureBuffer->Release(); if (pDSCapture) pDSCapture->Release(); }
void DXAudioOutput::run() { HRESULT hr; DSBUFFERDESC dsbdesc; WAVEFORMATEXTENSIBLE wfx; WAVEFORMATEXTENSIBLE wfxSet; int ns = 0; unsigned int chanmasks[32]; LPDIRECTSOUND8 pDS = NULL; LPDIRECTSOUNDBUFFER pDSBPrimary = NULL; LPDIRECTSOUNDBUFFER pDSBOutput = NULL; LPDIRECTSOUNDNOTIFY8 pDSNotify = NULL; DWORD dwBufferSize; DWORD dwLastWritePos; DWORD dwLastPlayPos; DWORD dwTotalPlayPos; int iLastwriteblock; LPVOID aptr1, aptr2; DWORD nbytes1, nbytes2; int playblock; int nowriteblock; DWORD dwPlayPosition, dwWritePosition; unsigned int iByteSize; bool bOk; DWORD dwSpeakerConfig; bool failed = false; bOk = false; DWORD dwMask = 0; bool bHead = false; ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; if (! g.s.qbaDXOutput.isEmpty()) { LPGUID lpguid = reinterpret_cast<LPGUID>(g.s.qbaDXOutput.data()); if (FAILED(hr = DirectSoundCreate8(lpguid, &pDS, NULL))) { failed = true; } } if (! pDS && FAILED(hr = DirectSoundCreate8(&DSDEVID_DefaultVoicePlayback, &pDS, NULL))) { qWarning("DXAudioOutput: DirectSoundCreate failed: hr=0x%08lx", hr); goto cleanup; } else if (FAILED(hr = pDS->SetCooperativeLevel(g.mw->winId(), DSSCL_PRIORITY))) { qWarning("DXAudioOutput: SetCooperativeLevel failed: hr=0x%08lx", hr); goto cleanup; } else if (FAILED(hr = pDS->CreateSoundBuffer(&dsbdesc, &pDSBPrimary, NULL))) { qWarning("DXAudioOutput: CreateSoundBuffer (Primary) failed: hr=0x%08lx", hr); goto cleanup; } pDS->GetSpeakerConfig(&dwSpeakerConfig); switch (DSSPEAKER_CONFIG(dwSpeakerConfig)) { case DSSPEAKER_HEADPHONE: dwMask = KSAUDIO_SPEAKER_STEREO; bHead = true; break; case DSSPEAKER_MONO: dwMask = KSAUDIO_SPEAKER_MONO; break; case DSSPEAKER_QUAD: dwMask = KSAUDIO_SPEAKER_QUAD; break; case DSSPEAKER_STEREO: dwMask = KSAUDIO_SPEAKER_STEREO; break; case DSSPEAKER_SURROUND: dwMask = KSAUDIO_SPEAKER_SURROUND; break; case DSSPEAKER_5POINT1: dwMask = KSAUDIO_SPEAKER_5POINT1; break; case DSSPEAKER_7POINT1: dwMask = KSAUDIO_SPEAKER_7POINT1; break; case DSSPEAKER_7POINT1_SURROUND: dwMask = KSAUDIO_SPEAKER_7POINT1_SURROUND; break; case DSSPEAKER_5POINT1_SURROUND: dwMask = KSAUDIO_SPEAKER_5POINT1_SURROUND; break; default: dwMask = 0; break; } if (! g.s.doPositionalAudio()) dwMask = KSAUDIO_SPEAKER_MONO; for (int i=0;i<32;i++) { if (dwMask & (1 << i)) { chanmasks[ns++] = 1 << i; } } iMixerFreq = SAMPLE_RATE; iChannels = ns; eSampleFormat = SampleShort; iByteSize = iFrameSize * sizeof(short) * ns; ZeroMemory(&wfxSet, sizeof(wfxSet)); wfxSet.Format.wFormatTag = WAVE_FORMAT_PCM; ZeroMemory(&wfx, sizeof(wfx)); wfx.Format.wFormatTag = WAVE_FORMAT_PCM; wfx.Format.nChannels = qMax(ns, 1); wfx.Format.nSamplesPerSec = SAMPLE_RATE; wfx.Format.nBlockAlign = sizeof(short) * wfx.Format.nChannels; wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign; wfx.Format.wBitsPerSample = 16; if (FAILED(hr = pDSBPrimary->SetFormat(reinterpret_cast<WAVEFORMATEX *>(&wfx)))) { qWarning("DXAudioOutput: SetFormat failed: hr=0x%08lx", hr); goto cleanup; } if (FAILED(hr = pDSBPrimary->GetFormat(reinterpret_cast<WAVEFORMATEX *>(&wfxSet), sizeof(wfxSet), NULL))) { qWarning("DXAudioOutput: GetFormat failed: hr=0x%08lx", hr); goto cleanup; } qWarning("DXAudioOutput: Primary buffer of %ld Hz, %d channels, %d bits",wfxSet.Format.nSamplesPerSec,wfxSet.Format.nChannels,wfxSet.Format.wBitsPerSample); ZeroMemory(&wfx, sizeof(wfx)); wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfx.Format.nChannels = ns; wfx.Format.nSamplesPerSec = SAMPLE_RATE; wfx.Format.nBlockAlign = sizeof(short) * wfx.Format.nChannels; wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign; wfx.Format.wBitsPerSample = 16; wfx.Format.cbSize = 32; wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample; wfx.dwChannelMask = dwMask; wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; dsbdesc.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; dsbdesc.dwBufferBytes = wfx.Format.nChannels * iFrameSize * sizeof(short) * NBLOCKS; dsbdesc.lpwfxFormat = reinterpret_cast<WAVEFORMATEX *>(&wfx); if (FAILED(hr = pDS->CreateSoundBuffer(&dsbdesc, &pDSBOutput, NULL))) { qWarning("DXAudioOutputUser: CreateSoundBuffer (Secondary) failed: hr=0x%08lx", hr); goto cleanup; } if (FAILED(hr = pDSBOutput->QueryInterface(IID_IDirectSoundNotify, reinterpret_cast<void **>(&pDSNotify)))) { qWarning("DXAudioOutputUser: QueryInterface (Notify) failed: hr=0x%08lx", hr); goto cleanup; } qWarning("DXAudioOutputUser: New %dHz output buffer of %ld bytes", SAMPLE_RATE, dsbdesc.dwBufferBytes); if (failed) g.mw->msgBox(tr("Opening chosen DirectSound Output failed. Default device will be used.")); initializeMixer(chanmasks, bHead); if (FAILED(hr = pDSBOutput->Lock(0, 0, &aptr1, &nbytes1, &aptr2, &nbytes2, DSBLOCK_ENTIREBUFFER))) { qWarning("DXAudioOutputUser: Initial Lock failed: hr=0x%08lx", hr); goto cleanup; } dwBufferSize = nbytes1 + nbytes2; if (aptr1) ZeroMemory(aptr1, nbytes1); if (aptr2) ZeroMemory(aptr2, nbytes2); if (FAILED(hr = pDSBOutput->Unlock(aptr1, nbytes1, aptr2, nbytes2))) { qWarning("DXAudioOutputUser: Initial Unlock failed: hr=0x%08lx", hr); goto cleanup; } if (FAILED(hr = pDSBOutput->Play(0, 0, DSBPLAY_LOOPING))) { qWarning("DXAudioOutputUser: Play failed: hr=0x%08lx", hr); goto cleanup; } dwLastWritePos = 0; dwLastPlayPos = 0; dwTotalPlayPos = 0; iLastwriteblock = (NBLOCKS - 1 + g.s.iOutputDelay) % NBLOCKS; bOk = true; while (bRunning && ! FAILED(hr)) { if (FAILED(hr = pDSBOutput->GetCurrentPosition(&dwPlayPosition, &dwWritePosition))) { qWarning("DXAudioOutputUser: GetCurrentPosition failed: hr=0x%08lx", hr); break; } playblock = dwWritePosition / iByteSize; nowriteblock = (playblock + g.s.iOutputDelay + 1) % NBLOCKS; for (int block=(iLastwriteblock + 1) % NBLOCKS;(!FAILED(hr)) && (block!=nowriteblock);block=(block + 1) % NBLOCKS) { iLastwriteblock = block; if (FAILED(hr = pDSBOutput->Lock(block * iByteSize, iByteSize, &aptr1, &nbytes1, &aptr2, &nbytes2, 0))) { qWarning("DXAudioOutput: Lock block %u (%d bytes) failed: hr=0x%08lx",block, iByteSize, hr); break; } if (aptr2 || nbytes2) { qWarning("DXAudioOutput: Split buffer"); break; } if (!aptr1 || ! nbytes1) { qWarning("DXAudioOutput: Zerolock"); break; } if (! mix(reinterpret_cast<short *>(aptr1), iFrameSize)) ZeroMemory(aptr1, iByteSize); if (FAILED(hr = pDSBOutput->Unlock(aptr1, nbytes1, aptr2, nbytes2))) { qWarning("DXAudioOutput: Unlock %p(%lu) %p(%lu) failed: hr=0x%08lx",aptr1,nbytes1,aptr2,nbytes2,hr); break; } if (FAILED(hr = pDSBOutput->GetCurrentPosition(&dwPlayPosition, &dwWritePosition))) { qWarning("DXAudioOutputUser: GetCurrentPosition failed: hr=0x%08lx", hr); break; } playblock = dwWritePosition / iByteSize; nowriteblock = (playblock + g.s.iOutputDelay + 1) % NBLOCKS; } if (! FAILED(hr)) msleep(19); } if (FAILED(hr)) { g.mw->msgBox(tr("Lost DirectSound output device.")); } cleanup: if (! bOk) { g.mw->msgBox(tr("Opening chosen DirectSound Output failed. No audio will be heard.")); return; } if (pDSNotify) pDSNotify->Release(); if (pDSBOutput) { pDSBOutput->Stop(); pDSBOutput->Release(); } if (pDSBPrimary) pDSBPrimary->Release(); if (pDS) pDS->Release(); }
bool DirectSound::init(long sampleRate) { HRESULT hr; DWORD freq; DSBUFFERDESC dsbdesc; int i; hr = CoCreateInstance( CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (LPVOID *)&pDirectSound ); if( hr != S_OK ) { systemMessage( IDS_CANNOT_CREATE_DIRECTSOUND, NULL, hr ); return false; } pDirectSound->Initialize( &DSDEVID_DefaultPlayback ); if( hr != DS_OK ) { systemMessage( IDS_CANNOT_CREATE_DIRECTSOUND, NULL, hr ); return false; } if( FAILED( hr = pDirectSound->SetCooperativeLevel( theApp.m_pMainWnd->GetSafeHwnd(), DSSCL_EXCLUSIVE ) ) ) { systemMessage( IDS_CANNOT_SETCOOPERATIVELEVEL, _T("Cannot SetCooperativeLevel %08x"), hr ); return false; } // Create primary sound buffer ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; if( dsoundDisableHardwareAcceleration ) { dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE; } if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbPrimary, NULL ) ) ) { systemMessage(IDS_CANNOT_CREATESOUNDBUFFER, _T("Cannot CreateSoundBuffer %08x"), hr); return false; } freq = sampleRate; // calculate the number of samples per frame first // then multiply it with the size of a sample frame (16 bit * stereo) soundBufferLen = ( freq / 60 ) * 4; soundBufferTotalLen = soundBufferLen * 10; soundNextPosition = 0; ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; wfx.nSamplesPerSec = freq; wfx.wBitsPerSample = 16; wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; if( FAILED( hr = dsbPrimary->SetFormat( &wfx ) ) ) { systemMessage( IDS_CANNOT_SETFORMAT_PRIMARY, _T("CreateSoundBuffer(primary) failed %08x"), hr ); return false; } // Create secondary sound buffer ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS; if( dsoundDisableHardwareAcceleration ) { dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE; } dsbdesc.dwBufferBytes = soundBufferTotalLen; dsbdesc.lpwfxFormat = &wfx; if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbSecondary, NULL ) ) ) { systemMessage( IDS_CANNOT_CREATESOUNDBUFFER, _T("CreateSoundBuffer(secondary) failed %08x"), hr ); return false; } if( FAILED( hr = dsbSecondary->SetCurrentPosition( 0 ) ) ) { systemMessage( 0, _T("dsbSecondary->SetCurrentPosition failed %08x"), hr ); return false; } if( SUCCEEDED( hr = dsbSecondary->QueryInterface( IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify ) ) ) { dsbEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); DSBPOSITIONNOTIFY notify[10]; for( i = 0; i < 10; i++ ) { notify[i].dwOffset = i * soundBufferLen; notify[i].hEventNotify = dsbEvent; } if( FAILED( dsbNotify->SetNotificationPositions( 10, notify ) ) ) { dsbNotify->Release(); dsbNotify = NULL; CloseHandle(dsbEvent); dsbEvent = NULL; } } // Play primary buffer if( FAILED( hr = dsbPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ) ) { systemMessage( IDS_CANNOT_PLAY_PRIMARY, _T("Cannot Play primary %08x"), hr ); return false; } return true; }
bool SoundRecoder::createBuffer(LPGUID guid) { //デバイスの作成 HMODULE library = LoadLibraryA("dsound.dll"); if(!library) return false; HRESULT (WINAPI *DirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8*,LPUNKNOWN) = (HRESULT (WINAPI *)(LPCGUID,LPDIRECTSOUNDCAPTURE8*,LPUNKNOWN)) GetProcAddress(library,"DirectSoundCaptureCreate8"); DirectSoundCaptureCreate8(guid,&m_soundCapture,NULL); FreeLibrary(library); //デバイスが作成できなかったら終了 if(!m_soundCapture) return false; if(m_soundCaptureBuffer) { m_soundCaptureBuffer->Release(); m_soundCaptureBuffer = NULL; } DSCBUFFERDESC dscbd; WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, m_bufferChannel, m_bufferRate, m_bufferRate*m_bufferChannel*m_bufferBit/8, m_bufferChannel*m_bufferBit/8, m_bufferBit, 0 }; m_bufferSize = wfx.nAvgBytesPerSec*m_bufferMSec/1000; dscbd.dwSize = sizeof(DSCBUFFERDESC); dscbd.dwFlags = 0; dscbd.dwBufferBytes = m_bufferSize; dscbd.dwReserved = 0; dscbd.lpwfxFormat = &wfx; dscbd.dwFXCount = 0; dscbd.lpDSCFXDesc = NULL; m_latency = m_bufferSize / m_notifyCount; LPDIRECTSOUNDCAPTUREBUFFER soundBuffer = NULL; m_soundCapture->CreateCaptureBuffer(&dscbd, &soundBuffer, NULL); if(!soundBuffer) return false; soundBuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8,(LPVOID*)&m_soundCaptureBuffer); soundBuffer->Release(); if(!m_soundCaptureBuffer) return false; INT i; for(i=0;i<m_notifyCount;i++) { m_positionNotify[i].dwOffset = (dscbd.dwBufferBytes /m_notifyCount)*i ; } LPDIRECTSOUNDNOTIFY8 dsNotify; m_soundCaptureBuffer->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&dsNotify); dsNotify->SetNotificationPositions(m_notifyCount, m_positionNotify); dsNotify->Release(); return true; }
bool FVoiceCaptureWindows::CreateNotifications(uint32 BufferSize) { bool bSuccess = true; LPDIRECTSOUNDNOTIFY8 NotifyInt = NULL; HRESULT hr = CV->VoiceCaptureBuffer8->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&NotifyInt); if (SUCCEEDED(hr)) { DSBPOSITIONNOTIFY NotifyEvents[NUM_EVENTS]; // Create events. for (int i = 0; i < NUM_EVENTS; i++) { CV->Events[i] = CreateEvent(NULL, true, false, NULL); if (CV->Events[i] == INVALID_HANDLE_VALUE) { UE_LOG(LogVoiceCapture, Warning, TEXT("Error creating sync event")); bSuccess = false; } } if (bSuccess) { // Evenly distribute notifications throughout the buffer uint32 NumSegments = NUM_EVENTS - 1; uint32 BufferSegSize = BufferSize / NumSegments; for (uint32 i = 0; i < NumSegments; i++) { NotifyEvents[i].dwOffset = ((i + 1) * BufferSegSize) - 1; NotifyEvents[i].hEventNotify = CV->Events[i]; } // when buffer stops NotifyEvents[STOP_EVENT].dwOffset = DSBPN_OFFSETSTOP; NotifyEvents[STOP_EVENT].hEventNotify = CV->Events[STOP_EVENT]; hr = NotifyInt->SetNotificationPositions(NUM_EVENTS, NotifyEvents); if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to set notifications 0x%08x"), hr); bSuccess = false; } float BufferSegMs = BufferSegSize / ((CV->WavFormat.nSamplesPerSec / 1000.0) * (CV->WavFormat.wBitsPerSample / 8.0)); UE_LOG(LogVoiceCapture, Display, TEXT("%d notifications, every %d bytes [%f ms]"), NumSegments, BufferSegSize, BufferSegMs); } NotifyInt->Release(); } else { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to create voice notification interface 0x%08x"), hr); } if (!bSuccess) { for (int i = 0; i < NUM_EVENTS; i++) { if (CV->Events[i] != INVALID_HANDLE_VALUE) { CloseHandle(CV->Events[i]); CV->Events[i] = INVALID_HANDLE_VALUE; } } } return bSuccess; }