int wf_directsound_activate(RdpsndServerContext* context) { HRESULT hr; wfInfo* wfi; LPDIRECTSOUNDCAPTUREBUFFER pDSCB; wfi = wf_info_get_instance(); if (!wfi) { WLog_ERR(TAG, "Failed to wfi instance"); return 1; } WLog_DBG(TAG, "RDPSND (direct sound) Activated"); hr = DirectSoundCaptureCreate8(NULL, &cap, NULL); if (FAILED(hr)) { WLog_ERR(TAG, "Failed to create sound capture device"); return 1; } WLog_INFO(TAG, "Created sound capture device"); dscbd.dwSize = sizeof(DSCBUFFERDESC); dscbd.dwFlags = 0; dscbd.dwBufferBytes = wfi->agreed_format->nAvgBytesPerSec; dscbd.dwReserved = 0; dscbd.lpwfxFormat = wfi->agreed_format; dscbd.dwFXCount = 0; dscbd.lpDSCFXDesc = NULL; hr = cap->lpVtbl->CreateCaptureBuffer(cap, &dscbd, &pDSCB, NULL); if (FAILED(hr)) { WLog_ERR(TAG, "Failed to create capture buffer"); } WLog_INFO(TAG, "Created capture buffer"); hr = pDSCB->lpVtbl->QueryInterface(pDSCB, &IID_IDirectSoundCaptureBuffer8, (LPVOID*)&capBuf); if (FAILED(hr)) { WLog_ERR(TAG, "Failed to QI capture buffer"); } WLog_INFO(TAG, "Created IDirectSoundCaptureBuffer8"); pDSCB->lpVtbl->Release(pDSCB); lastPos = 0; CreateThread(NULL, 0, wf_rdpsnd_directsound_thread, latestPeer, 0, NULL); return 0; }
sBool sSetSoundInHandler(sInt freq,sSoundHandler handler,sInt latency) { HRESULT hr; DSCBUFFERDESC desc; IDirectSoundCaptureBuffer *cbuf; static WAVEFORMATEX wfx = { WAVE_FORMAT_PCM,2,freq,freq*4,4,16,0}; // los gehts sClearSoundInHandler(); sLockSound(); cbuf = 0; DXSIRate = freq; DXSISamples = latency; DXSIHandler = handler; // create device hr = DirectSoundCaptureCreate8(0,&DXSI,0); if(FAILED(hr)) goto error; // create buffer sSetMem(&desc,0,sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwBufferBytes = latency*4; desc.lpwfxFormat = &wfx; hr = DXSI->CreateCaptureBuffer(&desc,&cbuf,0); if(FAILED(hr)) goto error; hr = cbuf->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)&DXSIBuffer); sRelease(cbuf); if(FAILED(hr)) goto error; // kick it! hr = DXSIBuffer->Start(DSCBSTART_LOOPING); if(FAILED(hr)) goto error; sUnlockSound(); return 1; error: sRelease(DXSIBuffer); sRelease(DXSI); sUnlockSound(); return 0; }
static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context) { HRESULT hr; LPDIRECTSOUNDCAPTUREBUFFER pDSCB; WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, 2, 44100, BYTESPERSEC, 4, 16, 0}; printf("RDPSND Activated\n"); hr = DirectSoundCaptureCreate8(NULL, &cap, NULL); if (FAILED(hr)) { _tprintf(_T("Failed to create sound capture device\n")); return; } _tprintf(_T("Created sound capture device\n")); dscbd.dwSize = sizeof(DSCBUFFERDESC); dscbd.dwFlags = 0; dscbd.dwBufferBytes = BYTESPERSEC; dscbd.dwReserved = 0; dscbd.lpwfxFormat = &wfx; dscbd.dwFXCount = 0; dscbd.lpDSCFXDesc = NULL; hr = cap->lpVtbl->CreateCaptureBuffer(cap, &dscbd, &pDSCB, NULL); if (FAILED(hr)) { _tprintf(_T("Failed to create capture buffer\n")); } _tprintf(_T("Created capture buffer")); hr = pDSCB->lpVtbl->QueryInterface(pDSCB, &IID_IDirectSoundCaptureBuffer8, (LPVOID*)&capBuf); if (FAILED(hr)) { _tprintf(_T("Failed to QI capture buffer\n")); } _tprintf(_T("Created IDirectSoundCaptureBuffer8\n")); pDSCB->lpVtbl->Release(pDSCB); context->SelectFormat(context, 4); context->SetVolume(context, 0x7FFF, 0x7FFF); capturePos = 0; CreateThread(NULL, 0, wf_rdpsnd_thread, latestPeer, 0, NULL); }
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(); }
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; }
int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = CoInitialize(0); if (SUCCEEDED(hr)) { hr = DirectSoundCaptureEnumerate((LPDSENUMCALLBACK)&callback_enumerate_capture_devices, NULL); } if (g_capture_guids_count > 0) { IDirectSoundCapture8 * p_capture_itf = NULL; g_selected_capture_device_idx = 0; hr = DirectSoundCaptureCreate8(&g_capture_guids[g_selected_capture_device_idx], &p_capture_itf, NULL); if (SUCCEEDED(hr)) { DSCCAPS dsCaps; ZeroMemory(&dsCaps, sizeof(dsCaps)); dsCaps.dwSize = sizeof(dsCaps); hr = p_capture_itf->GetCaps(&dsCaps); if (SUCCEEDED(hr)) { printf("dwFlags: "); if (dsCaps.dwFlags & DSCCAPS_CERTIFIED ) printf("DSCAPS_CERTIFIED | "); if (dsCaps.dwFlags & DSCCAPS_EMULDRIVER) printf("DSCCAPS_EMULDRIVER | "); if (dsCaps.dwFlags & DSCCAPS_MULTIPLECAPTURE) printf("DSCCAPS_MULTIPLECAPTURE | "); printf("\n"); size_t idx; printf("dwFormat: 0x%8.8x\n", dsCaps.dwFormats); for (idx = 0; idx < sizeof(g_wave_format_table)/sizeof(g_wave_format_table[0]); ++idx) { if (dsCaps.dwFormats & g_wave_format_table[idx].dwFormat_) printf("\t%s %s\n", g_wave_format_table[idx].tag_, g_wave_format_table[idx].text_desc_); } IDirectSoundCaptureBuffer8 * p_capture_buffer = NULL; hr = CreateCaptureBuffer(p_capture_itf, &p_capture_buffer); if (SUCCEEDED(hr)) { /* Now we have a valid Capture buffer interface. We can now capture WAV data */ DSCBCAPS dscbCaps; DWORD dwStatus = 0; WAVEFORMATEX wavFormatEx; ZeroMemory(&wavFormatEx, sizeof(wavFormatEx)); dscbCaps.dwSize = sizeof(dscbCaps); p_capture_buffer->GetCaps(&dscbCaps); p_capture_buffer->GetFormat(&wavFormatEx, sizeof(wavFormatEx), NULL); p_capture_buffer->GetStatus(&dwStatus); p_capture_buffer->Start(0); do { static unsigned int count = 0; #if 1 DWORD dwCapPos, dwReadPos; if (0 == (count & 0x0ff)) { p_capture_buffer->GetCurrentPosition(&dwCapPos, &dwReadPos); fprintf(stdout, "%8.8x %8.8x \n", dwCapPos, dwReadPos); } #endif p_capture_buffer->GetStatus(&dwStatus); if (0 == (DSCBSTATUS_CAPTURING & dwStatus)) break; Sleep(1); ++count; }while (1); LPVOID pAudioPtr1, pAudioPtr2; DWORD dwAudioBytes1, dwAudioBytes2; hr = p_capture_buffer->Lock(0, 0, &pAudioPtr1, &dwAudioBytes1, &pAudioPtr2, &dwAudioBytes2, DSCBLOCK_ENTIREBUFFER); CopyMemory(&g_wav_data_buffer[0], pAudioPtr1, dwAudioBytes1); { HANDLE hOutFile; hOutFile = CreateFile("caputre.dat", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != hOutFile) { DWORD dwBytesWritten; WriteFile(hOutFile, &g_wav_data_buffer, sizeof(g_wav_data_buffer), &dwBytesWritten, NULL); CloseHandle(hOutFile); } } p_capture_buffer->Release(); } } p_capture_itf->Release(); } } return SUCCEEDED(hr); }
bool FVoiceCaptureWindows::Init(int32 SampleRate, int32 NumChannels) { if (SampleRate < 8000 || SampleRate > 48000) { UE_LOG(LogVoiceCapture, Warning, TEXT("Voice capture doesn't support %d hz"), SampleRate); return false; } if (NumChannels < 0 || NumChannels > 2) { UE_LOG(LogVoiceCapture, Warning, TEXT("Voice capture only supports 1 or 2 channels")); return false; } FVoiceCaptureDeviceWindows* VoiceDev = FVoiceCaptureDeviceWindows::Get(); if (!VoiceDev) { UE_LOG(LogVoiceCapture, Warning, TEXT("No voice capture interface.")); return false; } // DSDEVID_DefaultCapture WAVEINCAPS HRESULT hr = DirectSoundCaptureCreate8(&DSDEVID_DefaultVoiceCapture, &CV->VoiceCaptureDev, NULL); if (FAILED(hr)) { //DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION, DSERR_OUTOFMEMORY UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to create capture device 0x%08x"), hr); return false; } // Device capabilities CV->VoiceCaptureDevCaps.dwSize = sizeof(DSCCAPS); hr = CV->VoiceCaptureDev->GetCaps(&CV->VoiceCaptureDevCaps); if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to get mic device caps 0x%08x"), hr); return false; } // Wave format setup CV->WavFormat.wFormatTag = WAVE_FORMAT_PCM; CV->WavFormat.nChannels = NumChannels; CV->WavFormat.wBitsPerSample = 16; CV->WavFormat.nSamplesPerSec = SampleRate; CV->WavFormat.nBlockAlign = (CV->WavFormat.nChannels * CV->WavFormat.wBitsPerSample) / 8; CV->WavFormat.nAvgBytesPerSec = CV->WavFormat.nBlockAlign * CV->WavFormat.nSamplesPerSec; CV->WavFormat.cbSize = 0; // Buffer setup CV->VoiceCaptureBufferDesc.dwSize = sizeof(DSCBUFFERDESC); CV->VoiceCaptureBufferDesc.dwFlags = 0; CV->VoiceCaptureBufferDesc.dwBufferBytes = CV->WavFormat.nAvgBytesPerSec / 2; // .5 sec buffer CV->VoiceCaptureBufferDesc.dwReserved = 0; CV->VoiceCaptureBufferDesc.lpwfxFormat = &CV->WavFormat; CV->VoiceCaptureBufferDesc.dwFXCount = 0; CV->VoiceCaptureBufferDesc.lpDSCFXDesc = NULL; LPDIRECTSOUNDCAPTUREBUFFER VoiceBuffer = NULL; hr = CV->VoiceCaptureDev->CreateCaptureBuffer(&CV->VoiceCaptureBufferDesc, &VoiceBuffer, NULL); if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to create voice capture buffer 0x%08x"), hr); return false; } hr = VoiceBuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)&CV->VoiceCaptureBuffer8); VoiceBuffer->Release(); VoiceBuffer = NULL; if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to create voice capture buffer 0x%08x"), hr); return false; } CV->VoiceCaptureBufferCaps8.dwSize = sizeof(DSCBCAPS); hr = CV->VoiceCaptureBuffer8->GetCaps(&CV->VoiceCaptureBufferCaps8); if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to get voice buffer caps 0x%08x"), hr); return false; } // TEST ------------------------ if (0) { DWORD SizeWritten8 = 0; CV->VoiceCaptureBuffer8->GetFormat(NULL, sizeof(WAVEFORMATEX), &SizeWritten8); LPWAVEFORMATEX BufferFormat8 = (WAVEFORMATEX*)FMemory::Malloc(SizeWritten8); CV->VoiceCaptureBuffer8->GetFormat(BufferFormat8, SizeWritten8, &SizeWritten8); FMemory::Free(BufferFormat8); } // TEST ------------------------ if (!CreateNotifications(CV->VoiceCaptureBufferCaps8.dwBufferBytes)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to create voice buffer notifications")); return false; } VoiceCaptureState = EVoiceCaptureState::NotCapturing; return true; }
bool DS_addDeviceRef(signed int deviceID) { HWND ownerWindow; HRESULT res = DS_OK; LPDIRECTSOUND8 devPlay; LPDIRECTSOUNDCAPTURE8 devCapture; LPGUID lpGuid = NULL; if (g_audioDeviceCache[deviceID].dev == NULL) { /* Create DirectSound */ //TRACE1("Creating DirectSound object for device %d\n", deviceID); lpGuid = &(g_audioDeviceCache[deviceID].guid); if (isEqualGUID(lpGuid, NULL)) { lpGuid = NULL; } if (g_audioDeviceCache[deviceID].isSource) { #if 0 //CoInitialize(NULL); res = DirectSoundCreate8(lpGuid, &devPlay, NULL); //生成DirectSound接口对象 #else res = CoInitializeEx(NULL, 0); res = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (LPVOID*)&devPlay); devPlay->Initialize(NULL); #endif g_audioDeviceCache[deviceID].dev = (void*) devPlay; } else { res = DirectSoundCaptureCreate8(lpGuid, &devCapture, NULL); g_audioDeviceCache[deviceID].dev = (void*) devCapture; } g_audioDeviceCache[deviceID].refCount = 0; if (FAILED(res)) { ERROR1("DS_addDeviceRef: ERROR: Failed to create DirectSound: %s", TranslateDSError(res)); g_audioDeviceCache[deviceID].dev = NULL; return false; } if (g_audioDeviceCache[deviceID].isSource) { ownerWindow = GetForegroundWindow(); if (ownerWindow == NULL) { ownerWindow = GetDesktopWindow(); } //TRACE0("DS_addDeviceRef: Setting cooperative level\n"); res = devPlay->SetCooperativeLevel(ownerWindow, DSSCL_PRIORITY); //设置应用程序对声音设备的合作级别 if (FAILED(res)) { ERROR1("DS_addDeviceRef: ERROR: Failed to set cooperative level: %s", TranslateDSError(res)); return false; } } } g_audioDeviceCache[deviceID].refCount++; return true; }
static int _dsound_open_recorder(ALLEGRO_AUDIO_RECORDER *r) { HRESULT hr; if (capture_device != NULL) { /* FIXME: It's wrong to assume only a single recording device, but since there is no enumeration of devices, it doesn't matter for now. */ ALLEGRO_ERROR("Already recording.\n"); return 1; } ALLEGRO_INFO("Creating default capture device.\n"); /* FIXME: Use default device until we have device enumeration */ hr = DirectSoundCaptureCreate8(NULL, &capture_device, NULL); if (FAILED(hr)) { ALLEGRO_ERROR("DirectSoundCaptureCreate8 failed: %s\n", ds_get_error(hr)); return 1; } hr = device->SetCooperativeLevel(get_window(), DSSCL_PRIORITY); if (FAILED(hr)) { ALLEGRO_ERROR("SetCooperativeLevel failed: %s\n", ds_get_error(hr)); return 1; } DSOUND_RECORD_DATA *extra = (DSOUND_RECORD_DATA *) al_calloc(1, sizeof(*extra)); DSCCAPS dsccaps; dsccaps.dwSize = sizeof(DSCCAPS); hr = capture_device->GetCaps(&dsccaps); if (FAILED(hr)) { ALLEGRO_ERROR("DirectSoundCaptureCreate8::GetCaps failed: %s\n", ds_get_error(hr)); } else { ALLEGRO_INFO("caps: %lu %lu\n", dsccaps.dwFormats, dsccaps.dwFormats & WAVE_FORMAT_2M16); } memset(&extra->wave_fmt, 0, sizeof(extra->wave_fmt)); extra->wave_fmt.wFormatTag = WAVE_FORMAT_PCM; extra->wave_fmt.nChannels = (WORD)al_get_channel_count(r->chan_conf); extra->wave_fmt.nSamplesPerSec = r->frequency; extra->wave_fmt.wBitsPerSample = (WORD)al_get_audio_depth_size(r->depth) * 8; extra->wave_fmt.nBlockAlign = extra->wave_fmt.nChannels * extra->wave_fmt.wBitsPerSample / 8; extra->wave_fmt.nAvgBytesPerSec = extra->wave_fmt.nSamplesPerSec * extra->wave_fmt.nBlockAlign; memset(&extra->desc, 0, sizeof(extra->desc)); extra->desc.dwSize = sizeof(extra->desc); extra->desc.lpwfxFormat = &extra->wave_fmt; extra->desc.dwBufferBytes = extra->wave_fmt.nAvgBytesPerSec * 5; hr = capture_device->CreateCaptureBuffer(&extra->desc, &extra->buffer, NULL); if (FAILED(hr)) { al_free(extra); ALLEGRO_ERROR("Unable to create Capture Buffer\n"); return 1; } extra->buffer->QueryInterface(_al_IID_IDirectSoundCaptureBuffer8, (void **) &extra->buffer8); r->extra = extra; r->thread = al_create_thread(_dsound_update_recorder, r); return 0; }
bool FVoiceCaptureWindows::Init(int32 SampleRate, int32 NumChannels) { if (SampleRate < 8000 || SampleRate > 48000) { UE_LOG(LogVoice, Warning, TEXT("Voice capture doesn't support %d hz"), SampleRate); return false; } if (NumChannels < 0 || NumChannels > 2) { UE_LOG(LogVoice, Warning, TEXT("Voice capture only supports 1 or 2 channels")); return false; } // @todo move this to voice module (only init/deinit once ever) if (FAILED(DirectSoundCreate8(NULL, &DirectSound, NULL))) { UE_LOG(LogVoice, Warning, TEXT("Failed to init DirectSound")); return false; } if (FAILED(DirectSoundCaptureEnumerate((LPDSENUMCALLBACK)CaptureDeviceCallback, this))) { UE_LOG(LogVoice, Warning, TEXT("Failed to enumerate devices")); return false; } // DSDEVID_DefaultCapture WAVEINCAPS if (FAILED(DirectSoundCaptureCreate8(&DSDEVID_DefaultVoiceCapture, &VoiceCaptureDev, NULL))) { UE_LOG(LogVoice, Warning, TEXT("Failed to create capture device")); return false; } // Device capabilities VoiceCaptureDevCaps.dwSize = sizeof(DSCCAPS); if (FAILED(VoiceCaptureDev->GetCaps(&VoiceCaptureDevCaps))) { UE_LOG(LogVoice, Warning, TEXT("Failed to get mic device caps")); return false; } // Wave format setup WavFormat.wFormatTag = WAVE_FORMAT_PCM; WavFormat.nChannels = NumChannels; WavFormat.wBitsPerSample = 16; WavFormat.nSamplesPerSec = SampleRate; WavFormat.nBlockAlign = (WavFormat.nChannels * WavFormat.wBitsPerSample) / 8; WavFormat.nAvgBytesPerSec = WavFormat.nBlockAlign * WavFormat.nSamplesPerSec; WavFormat.cbSize = 0; // Buffer setup VoiceCaptureBufferDesc.dwSize = sizeof(DSCBUFFERDESC); VoiceCaptureBufferDesc.dwFlags = 0; VoiceCaptureBufferDesc.dwBufferBytes = WavFormat.nAvgBytesPerSec / 2; // .5 sec buffer VoiceCaptureBufferDesc.dwReserved = 0; VoiceCaptureBufferDesc.lpwfxFormat = &WavFormat; VoiceCaptureBufferDesc.dwFXCount = 0; VoiceCaptureBufferDesc.lpDSCFXDesc = NULL; LPDIRECTSOUNDCAPTUREBUFFER VoiceBuffer = NULL; if (FAILED(VoiceCaptureDev->CreateCaptureBuffer(&VoiceCaptureBufferDesc, &VoiceBuffer, NULL))) { UE_LOG(LogVoice, Warning, TEXT("Failed to create voice capture buffer")); return false; } HRESULT BufferCreateHR = VoiceBuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)&VoiceCaptureBuffer8); VoiceBuffer->Release(); VoiceBuffer = NULL; if (FAILED(BufferCreateHR)) { UE_LOG(LogVoice, Warning, TEXT("Failed to create voice capture buffer")); return false; } VoiceCaptureBufferCaps8.dwSize = sizeof(DSCBCAPS); if (FAILED(VoiceCaptureBuffer8->GetCaps(&VoiceCaptureBufferCaps8))) { UE_LOG(LogVoice, Warning, TEXT("Failed to get voice buffer caps")); return false; } // TEST ------------------------ if (0) { DWORD SizeWritten8 = 0; VoiceCaptureBuffer8->GetFormat(NULL, sizeof(WAVEFORMATEX), &SizeWritten8); LPWAVEFORMATEX BufferFormat8 = (WAVEFORMATEX*)FMemory::Malloc(SizeWritten8); VoiceCaptureBuffer8->GetFormat(BufferFormat8, SizeWritten8, &SizeWritten8); FMemory::Free(BufferFormat8); } // TEST ------------------------ if (!CreateNotifications(VoiceCaptureBufferCaps8.dwBufferBytes)) { UE_LOG(LogVoice, Warning, TEXT("Failed to create voice buffer notifications")); return false; } VoiceCaptureState = EVoiceCaptureState::NotCapturing; return true; }
HRESULT CAudio::InitializeCapture(IAnalyzed* analyzed) { ENTER_SECTION(this); m_Analyzed = analyzed; // Get the address of the create function LPDIRECTSOUNDCAPTURECREATE8 DirectSoundCaptureCreate8 = (LPDIRECTSOUNDCAPTURECREATE8)GetProcAddress(m_DS,"DirectSoundCaptureCreate8"); if(!DirectSoundCaptureCreate8) { TRACE("Failed to find \"DirectSoundCaptureCreate8\" in \"%s\".\n",DSDLL); return E_FAIL; } // Create our main capture object HRESULT hr = DirectSoundCaptureCreate8(&DSDEVID_DefaultCapture, &m_SoundCapture, NULL); if(FAILED(hr)) { TRACE("Failed to load create direct sound capture.\n",DSDLL); return E_FAIL; } // Create the wave format description WAVEFORMATEX waveform; ZeroMemory(&waveform,sizeof(waveform)); waveform.cbSize = sizeof(waveform); waveform.nChannels = AUDIO_CHANNELS; waveform.nSamplesPerSec = AUDIO_FREQUENCY; waveform.wBitsPerSample = AUDIO_BITS; waveform.nBlockAlign = (waveform.nChannels * waveform.wBitsPerSample) / 8; waveform.nAvgBytesPerSec = waveform.nSamplesPerSec * waveform.nBlockAlign; waveform.wFormatTag = WAVE_FORMAT_PCM; // Create the record buffer format description DSCBUFFERDESC bufferdesc; ZeroMemory(&bufferdesc,sizeof(bufferdesc)); bufferdesc.dwSize = sizeof(bufferdesc); bufferdesc.dwFlags = 0; bufferdesc.dwBufferBytes = AUDIO_BUFFERSIZE; bufferdesc.dwFXCount = 0; bufferdesc.lpDSCFXDesc = 0; bufferdesc.lpwfxFormat = &waveform; // Create the capture buffer hr = m_SoundCapture->CreateCaptureBuffer(&bufferdesc, &m_CaptureBuffer, NULL); if(FAILED(hr)) { TRACE("Failed to create direct sound capture buffer."); return E_FAIL; } if(FAILED(StartCapture())) { TRACE("Failed to start capture.\n"); return E_FAIL; } // Create the renderer thread m_Capture = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)CaptureThread,this,NULL,&m_CaptureId); if(!m_Capture) return E_FAIL; return S_OK; }