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 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; }