/****************************************** END CPU UTILIZATION *******/ static PaError Pa_QueryDevices( void ) { int numBytes; sDefaultInputDeviceID = paNoDevice; sDefaultOutputDeviceID = paNoDevice; /* Enumerate once just to count devices. */ sNumDevices = 0; // for default device DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL ); #if SUPPORT_AUDIO_CAPTURE DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL ); #endif /* SUPPORT_AUDIO_CAPTURE */ /* Allocate structures to hold device info. */ numBytes = sNumDevices * sizeof(internalPortAudioDevice); sDevices = (internalPortAudioDevice *)PaHost_AllocateFastMemory( numBytes ); /* MEM */ if( sDevices == NULL ) return paInsufficientMemory; /* Enumerate again to fill in structures. */ sDeviceIndex = 0; sEnumerationError = 0; DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)0 ); #if SUPPORT_AUDIO_CAPTURE if( sEnumerationError != paNoError ) return sEnumerationError; sEnumerationError = 0; DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)1 ); #endif /* SUPPORT_AUDIO_CAPTURE */ return sEnumerationError; }
const QList<audioDevice> DXAudioInputRegistrar::getDeviceChoices() { QList<dsDevice> qlInput; qlInput << dsDevice(DXAudioInput::tr("Default DirectSound Voice Input"), DSDEVID_DefaultVoiceCapture); DirectSoundCaptureEnumerate(DSEnumProc, reinterpret_cast<void *>(&qlInput)); QList<audioDevice> qlReturn; const GUID *lpguid = NULL; if (! g.s.qbaDXInput.isEmpty()) { lpguid = reinterpret_cast<LPGUID>(g.s.qbaDXInput.data()); } else { lpguid = &DSDEVID_DefaultVoiceCapture; } foreach(dsDevice d, qlInput) { if (d.second == *lpguid) { qlReturn << audioDevice(d.first, QByteArray(reinterpret_cast<const char *>(&d.second), sizeof(GUID))); } } foreach(dsDevice d, qlInput) { if (d.second != *lpguid) { qlReturn << audioDevice(d.first, QByteArray(reinterpret_cast<const char *>(&d.second), sizeof(GUID))); } } return qlReturn; }
signed int DAUDIO_GetDirectAudioDeviceDescription(signed int mixerIndex, DirectAudioDeviceDescription* desc) { if (!DS_lockCache()) { return false; } /* set the deviceID field to the cache index */ desc->deviceID = findCacheItemByMixerIndex(mixerIndex); if (desc->deviceID < 0) { DS_unlockCache(); return false; } desc->maxSimulLines = 0; if (g_audioDeviceCache[desc->deviceID].isSource) { DirectSoundEnumerate((LPDSENUMCALLBACK) DS_GetDescEnum, desc); StringCchCopy(desc->description, DAUDIO_STRING_LENGTH, L"DirectSound Playback"); //strncpy(desc->description, "DirectSound Playback", DAUDIO_STRING_LENGTH); } else { DirectSoundCaptureEnumerate((LPDSENUMCALLBACK) DS_GetDescEnum, desc); StringCchCopy(desc->description, DAUDIO_STRING_LENGTH, L"DirectSound Capture"); //strncpy(desc->description, "DirectSound Capture", DAUDIO_STRING_LENGTH); } /*desc->vendor; desc->version;*/ DS_unlockCache(); return (desc->maxSimulLines == -1)?true:false; }
bool FVoiceCaptureDeviceWindows::Init() { HRESULT hr = DirectSoundCreate8(NULL, &DirectSound, NULL); if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to init DirectSound %d"), hr); return false; } bool bHmdAvailable = IModularFeatures::Get().IsModularFeatureAvailable(IHeadMountedDisplayModule::GetModularFeatureName()); HmdVoiceCaptureDeviceIndex = bHmdAvailable ? CVarHmdDirectSoundVoiceCaptureDeviceIndex.GetValueOnGameThread() : -1; VoiceCaptureDeviceCount = 0; VoiceCaptureDeviceGuid = DSDEVID_DefaultVoiceCapture; hr = DirectSoundCaptureEnumerate((LPDSENUMCALLBACK)CaptureDeviceCallback, this); if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to enumerate capture devices %d"), hr); return false; } bool bDuckingOptOut = false; if (GConfig) { if (!GConfig->GetBool(TEXT("Voice"), TEXT("bDuckingOptOut"), bDuckingOptOut, GEngineIni)) { bDuckingOptOut = false; } } FAudioDuckingWindows::UpdateAudioDucking(bDuckingOptOut); bInitialized = true; return true; }
///// implemented functions of DirectAudio.h //该函数主要是枚举输入输出设备 signed int DAUDIO_GetDirectAudioDeviceCount() { DS_RefreshCacheStruct rs; signed int oldCount; signed int cacheIndex; if (!DS_lockCache()) { return 0; } if (g_lastCacheRefreshTime == 0 || (unsigned long long) timeGetTime() > (unsigned long long) (g_lastCacheRefreshTime + WAIT_BETWEEN_CACHE_REFRESH_MILLIS)) { /* first, initialize any old cache items */ for (cacheIndex = 0; cacheIndex < g_cacheCount; cacheIndex++) { g_audioDeviceCache[cacheIndex].mixerIndex = -1; } /* enumerate all devices and either add them to the device cache, * or refresh the mixer number */ rs.currMixerIndex = 0; rs.isSource = true; DirectSoundEnumerate((LPDSENUMCALLBACK) DS_RefreshCacheEnum, &rs);//枚举系统输出声音的设备 /* if we only got the Primary Sound Driver (GUID=NULL), * then there aren't any playback devices installed */ if (rs.currMixerIndex == 1) { cacheIndex = findCacheItemByGUID(NULL, true); if (cacheIndex == 0) { rs.currMixerIndex = 0; g_audioDeviceCache[0].mixerIndex = -1; //TRACE0("Removing stale Primary Sound Driver from list.\n"); } } oldCount = rs.currMixerIndex; rs.isSource = false; DirectSoundCaptureEnumerate((LPDSENUMCALLBACK) DS_RefreshCacheEnum, &rs);//枚举系统输入声音的设备 /* if we only got the Primary Sound Capture Driver (GUID=NULL), * then there aren't any capture devices installed */ if ((rs.currMixerIndex - oldCount) == 1) { cacheIndex = findCacheItemByGUID(NULL, false); if (cacheIndex != -1) { rs.currMixerIndex = oldCount; g_audioDeviceCache[cacheIndex].mixerIndex = -1; //TRACE0("Removing stale Primary Sound Capture Driver from list.\n"); } } g_mixerCount = rs.currMixerIndex; g_lastCacheRefreshTime = (unsigned long long) timeGetTime(); } DS_unlockCache(); return g_mixerCount; }
/* * Init sound library. */ PJ_DEF(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory) { HRESULT hr; unsigned i; if (++snd_init_count != 1) return PJ_SUCCESS; pool_factory = factory; /* Enumerate sound playback devices */ hr = DirectSoundEnumerate(&DSEnumCallback, NULL); if (FAILED(hr)) return PJ_RETURN_OS_ERROR(hr); /* Enumerate sound capture devices */ hr = DirectSoundCaptureEnumerate(&DSEnumCallback, (void*)1); if (FAILED(hr)) return PJ_RETURN_OS_ERROR(hr); PJ_LOG(4,(THIS_FILE, "DirectSound initialized, found %d devices:", dev_count)); for (i=0; i<dev_count; ++i) { PJ_LOG(4,(THIS_FILE, " dev_id %d: %s (in=%d, out=%d)", i, dev_info[i].info.name, dev_info[i].info.input_count, dev_info[i].info.output_count)); } return PJ_SUCCESS; }
uint32 nuiAudioDeviceAPI_DirectSound::GetDeviceCount() const { mDeviceIDs.clear(); mDeviceMap.clear(); // Add the default device first: DeviceDesc desc; desc.mInName = _T("Default device"); desc.mOutName = _T("Default device"); mDeviceIDs.push_back(desc); mDeviceMap[_T("Default device")] = 0; HRESULT hr = DirectSoundEnumerate(&nuiAudioDeviceAPI_DirectSound::DSEnumOutputCallback, (LPVOID)this); hr = DirectSoundCaptureEnumerate(&nuiAudioDeviceAPI_DirectSound::DSEnumInputCallback, (LPVOID)this); return (uint32)mDeviceIDs.size(); }
bool FVoiceCaptureDeviceWindows::Init() { HRESULT hr = DirectSoundCreate8(NULL, &DirectSound, NULL); if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to init DirectSound %d"), hr); return false; } hr = DirectSoundCaptureEnumerate((LPDSENUMCALLBACK)CaptureDeviceCallback, this); if (FAILED(hr)) { UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to enumerate devices %d"), hr); return false; } bInitialized = true; return true; }
static gboolean gst_directsound_src_open (GstAudioSrc * asrc) { GstDirectSoundSrc *dsoundsrc; HRESULT hRes; /* Result for windows functions */ GST_DEBUG_OBJECT (asrc, "opening directsoundsrc"); dsoundsrc = GST_DIRECTSOUND_SRC (asrc); /* Open dsound.dll */ dsoundsrc->DSoundDLL = LoadLibrary ("dsound.dll"); if (!dsoundsrc->DSoundDLL) { goto dsound_open; } /* Building the DLL Calls */ pDSoundCaptureCreate = (void *) GetProcAddress (dsoundsrc->DSoundDLL, TEXT ("DirectSoundCaptureCreate")); /* If everything is not ok */ if (!pDSoundCaptureCreate) { goto capture_function; } hRes = DirectSoundCaptureEnumerate ((LPDSENUMCALLBACK) gst_directsound_enum_callback, (VOID *) dsoundsrc); if (FAILED (hRes)) { goto capture_enumerate; } /* Create capture object */ hRes = pDSoundCaptureCreate (dsoundsrc->device_guid, &dsoundsrc->pDSC, NULL); if (FAILED (hRes)) { goto capture_object; } gst_directsound_src_mixer_init (dsoundsrc); return TRUE; capture_function: { FreeLibrary (dsoundsrc->DSoundDLL); GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to get capturecreate function"), (NULL)); return FALSE; } capture_enumerate: { FreeLibrary (dsoundsrc->DSoundDLL); GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to enumerate audio capture devices"), (NULL)); return FALSE; } capture_object: { FreeLibrary (dsoundsrc->DSoundDLL); GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to create capture object"), (NULL)); return FALSE; } dsound_open: { DWORD err = GetLastError (); GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to open dsound.dll"), (NULL)); g_print ("0x%lx\n", HRESULT_FROM_WIN32 (err)); return FALSE; } }
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); }
/* nInterval is in SECONDS. The buffer we create is 3 times the interval, so we make three notifications that will be placed at every interval. pProc will be called at approximately the interval specified. */ HRESULT WaveCapture::Initialize(int nDevice, WAVEFORMATEX* pFormat, WAVECAPTUREPROC pProc, PVOID pUser, int nInterval) { DSCCAPS dsc; DSCBUFFERDESC1 dscbDesc; HRESULT hr; DSBPOSITIONNOTIFY NotifyPositions[3]; IDirectSoundNotify* pdsn; this->Uninitialize(); this->pProc = pProc; this->pUser = pUser; this->nInterval = nInterval; // Validation. if(pFormat->wFormatTag != WAVE_FORMAT_PCM) { return E_FAIL; } // Copy the wave format for our own purposes. memcpy(&this->Format, pFormat, sizeof(WAVEFORMATEX)); m_iDevice = nDevice; memset(&m_Device, 0, sizeof(GUID)); DirectSoundCaptureEnumerate(WaveCapture::DSEnumCallback, this); // Create DirectSoundCapture object. if(FAILED(hr = DirectSoundCaptureCreate(&m_Device, &this->pdsc, NULL))) { return E_FAIL; } /* Here is where we should check the capabilities of the sound card against the format that was passed in. */ dsc.dwSize = sizeof(DSCCAPS); if(FAILED(hr = this->pdsc->GetCaps(&dsc))) { SAFE_RELEASE(this->pdsc); return E_FAIL; } /* Create the capture buffer. */ dscbDesc.dwSize = sizeof(dscbDesc); dscbDesc.dwFlags = DSCBCAPS_WAVEMAPPED; dscbDesc.dwBufferBytes = (pFormat->nAvgBytesPerSec * nInterval) * 3; dscbDesc.dwReserved = 0; dscbDesc.lpwfxFormat = &this->Format; if(FAILED(hr = this->pdsc->CreateCaptureBuffer((DSCBUFFERDESC*)&dscbDesc, &this->pdsb, NULL))) { SAFE_RELEASE(this->pdsc); return E_FAIL; } /* Create the notifications */ this->hEvents[0] = CreateEvent(NULL, FALSE, FALSE, NULL); this->hEvents[1] = CreateEvent(NULL, FALSE, FALSE, NULL); this->hEvents[2] = CreateEvent(NULL, FALSE, FALSE, NULL); this->hEvents[3] = CreateEvent(NULL, FALSE, FALSE, NULL); NotifyPositions[0].dwOffset = 0; NotifyPositions[0].hEventNotify = this->hEvents[0]; NotifyPositions[1].dwOffset = (this->Format.nAvgBytesPerSec * nInterval); NotifyPositions[1].hEventNotify = this->hEvents[1]; NotifyPositions[2].dwOffset = (this->Format.nAvgBytesPerSec * nInterval) * 2; NotifyPositions[2].hEventNotify = this->hEvents[2]; if(FAILED(hr = this->pdsb->QueryInterface(IID_IDirectSoundNotify, (PVOID*)&pdsn))) { SAFE_RELEASE(this->pdsb); SAFE_RELEASE(this->pdsc); return E_FAIL; } if(FAILED(hr = pdsn->SetNotificationPositions(3, NotifyPositions))) { SAFE_RELEASE(pdsn); SAFE_RELEASE(this->pdsb); SAFE_RELEASE(this->pdsc); return E_FAIL; } SAFE_RELEASE(pdsn); /* Create our own buffer so when we pass data to pProc, the data is ALWAYS contiguous. */ this->nBufferSize = (pFormat->nAvgBytesPerSec * nInterval) * 3; this->pBuffer = (PBYTE)malloc(this->nBufferSize); /* Initialize our own information. */ this->dwLastPosition = 0; this->nPassesLeft = 1; /* Now create our recording thread so life can continue. */ UINT dwThreadId; this->hThread = (HANDLE)_beginthreadex( 0, 0, WaveCapture::RecordingThread, this, 0, &dwThreadId); return S_OK; }
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; }