/****************************************** 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; }
//============================================================ // osd_enum_audio_devices //============================================================ int osd_enum_audio_devices() { audio_devices_number = 0; if(DirectSoundEnumerate (EnumCallBack, NULL)!=DS_OK) return 0; return audio_devices_number; }
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; }
const QList<audioDevice> DXAudioOutputRegistrar::getDeviceChoices() { QList<dsDevice> qlOutput; qlOutput << dsDevice(DXAudioOutput::tr("Default DirectSound Voice Output"), DSDEVID_DefaultVoicePlayback); DirectSoundEnumerate(DSEnumProc, reinterpret_cast<void *>(&qlOutput)); QList<audioDevice> qlReturn; const GUID *lpguid = NULL; if (! g.s.qbaDXOutput.isEmpty()) { lpguid = reinterpret_cast<LPGUID>(g.s.qbaDXOutput.data()); } else { lpguid = &DSDEVID_DefaultVoicePlayback; } foreach(dsDevice d, qlOutput) { if (d.second == *lpguid) { qlReturn << audioDevice(d.first, QByteArray(reinterpret_cast<const char *>(&d.second), sizeof(GUID))); } } foreach(dsDevice d, qlOutput) { if (d.second != *lpguid) { qlReturn << audioDevice(d.first, QByteArray(reinterpret_cast<const char *>(&d.second), sizeof(GUID))); } } return qlReturn; }
void DirectSoundLibrary::refreshDevices() { DirectSoundEnumerate(enumDevice, (void*)this); if (_devices.empty()) throwf("DirectSoundLibrary: No devices found."); }
///// 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; }
CString DSound::Init() { HRESULT hr; if( FAILED( hr = DirectSoundCreate(NULL, &m_pDS, NULL) ) ) return hr_ssprintf( hr, "DirectSoundCreate" ); #ifndef _XBOX static bool bShownInfo = false; if( !bShownInfo ) { bShownInfo = true; DirectSoundEnumerate( EnumCallback, 0 ); DSCAPS Caps; Caps.dwSize = sizeof(Caps); HRESULT hr; if( FAILED(hr = m_pDS->GetCaps(&Caps)) ) { LOG->Warn( hr_ssprintf(hr, "m_pDS->GetCaps failed") ); } else { LOG->Info( "DirectSound sample rates: %i..%i %s", Caps.dwMinSecondarySampleRate, Caps.dwMaxSecondarySampleRate, (Caps.dwFlags & DSCAPS_CONTINUOUSRATE)?"(continuous)":"" ); } } /* Try to set primary mixing privileges */ hr = m_pDS->SetCooperativeLevel( GetDesktopWindow(), DSSCL_PRIORITY ); #endif SetPrimaryBufferMode(); return ""; }
/* * 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; }
static int Detect() { DX_Context ds; g_lpDSDevice = NULL; sysMemZero(g_pDSHandles, DSOUNDMAXBUFFER * sizeof(DS_handle)); ds.lpGUID = NULL; if (RLX.Audio.WaveDeviceId) { ds.index = 0; ds.mode = 1; DirectSoundEnumerate((LPDSENUMCALLBACKA)DSEnumCallback, &ds); } if (SYS_DXTRACE(DirectSoundCreate(ds.lpGUID, &g_lpDSDevice, NULL))) { if (ds.lpGUID) { ds.lpGUID = NULL; RLX.Audio.WaveDeviceId = 0; } if (SYS_DXTRACE(DirectSoundCreate(ds.lpGUID, &g_lpDSDevice, NULL))) return -1; } return 0; }
BOOL getCurrentChannelConfig() { IDirectSound8* ds; DWORD speakerConfig; LPGUID guid = NULL; DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc, (VOID*)&guid); if (DirectSoundCreate8(guid, &ds, NULL) != S_OK) { return FALSE; } ds->Initialize(NULL); if (ds->GetSpeakerConfig(&speakerConfig) != S_OK) { PrintLastError("GetSpeakerConfig()"); return FALSE; } if (ds) { ds->Release(); } if (guid) { LocalFree(guid); } switch (DSSPEAKER_CONFIG(speakerConfig)) { case DSSPEAKER_STEREO: currentChannelCount = 2; return TRUE; case DSSPEAKER_QUAD: currentChannelCount = 4; return TRUE; case DSSPEAKER_5POINT1: currentChannelCount = 6; return TRUE; case DSSPEAKER_7POINT1: currentChannelCount = 8; return TRUE; } return FALSE; }
static int Enum(void) { DX_Context ds; ds.index = 0; ds.mode = 2; ds.lpGUID = NULL; DirectSoundEnumerate((LPDSENUMCALLBACKA)DSEnumCallback, &ds); if (ds.index) { V3XA.p_driverList = (char**)MM_std.malloc((ds.index+1)*sizeof(char*)); ds.lpGUID = NULL; ds.index = 0; ds.mode = 3; DirectSoundEnumerate((LPDSENUMCALLBACKA)DSEnumCallback, &ds); } return 1; }
int EnumSoundDevice( void ) { SoundDeviceNum=0; if( DS_OK != DirectSoundEnumerate( (LPDSENUMCALLBACK)DSoundEnumCallback, NULL ) ){ return 0; } return SoundDeviceNum; }
std::vector<DSDeviceInfo> CWDSound::GetSoundDevices() { CSingleLock lock (m_critSection); vDSDeviceInfo.clear(); if (FAILED(DirectSoundEnumerate(direct_sound_enumerator_callback, this))) CLog::Log(LOGERROR, "%s - failed to enumerate output devices", __FUNCTION__); return vDSDeviceInfo; }
void alcDSoundInit(BackendFuncs *FuncList) { size_t iter = 1; HRESULT hr; *FuncList = DSoundFuncs; hr = DirectSoundEnumerate(DSoundEnumDevices, &iter); if(FAILED(hr)) AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); }
XAudPlayer::XAudPlayer() { m_stream = NULL; #ifdef DEBUG_NO_SOUND return; #endif if (!bass_init) { int DSidx; const HRESULT hr = GetRegInt("Player", "SoundDeviceBG", &DSidx); if (hr != S_OK) DSidx = -1; // now match the Direct Sound device with the BASS device (by name) int BASSidx = -1; if (DSidx != -1) { DSAudioDevices DSads; if (!FAILED(DirectSoundEnumerate(DSEnumCallBack, &DSads))) { if ((unsigned int)DSidx >= DSads.size() || DSads[DSidx]->guid != NULL) // primary device has guid NULL, so use BASSidx = -1 in that case { BASS_DEVICEINFO info; for (int i = 1; BASS_GetDeviceInfo(i, &info); i++) // 0 = no sound/no device if (info.flags & BASS_DEVICE_ENABLED) // device must be enabled if (strcmp(info.name, DSads[DSidx]->description.c_str()) == 0) { BASSidx = i; break; } } for (size_t i = 0; i < DSads.size(); i++) delete DSads[i]; } } if (!BASS_Init(BASSidx, 44100, 0, g_pvp->m_hwnd, NULL)) // note that sample rate is usually ignored and set depending on the input/file automatically { char bla[128]; sprintf_s(bla, "BASS music/sound library initialization error %d", BASS_ErrorGetCode()); MessageBox(g_pvp->m_hwnd, bla, "Error", MB_ICONERROR); } bass_init = true; } }
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(); }
int iKX::init_directx(int what) { dx_enum_context context; context.kx=this; context.what=what; memset(&context.guid,0,sizeof(GUID)); if(DirectSoundEnumerate(&my_enum,&context)==DS_OK) { memcpy(&guid_,&context.guid,sizeof(GUID)); } else { debug("iKX init_directX: DirectSoundEnumerate failed\n"); } return -1; }
void CDSound::EnumerateDevices() { if (m_iDevices != 0) ClearEnumeration(); DirectSoundEnumerate(DSEnumCallback, NULL); #ifdef _DEBUG // Add an invalid device for debugging reasons GUID g; g.Data1 = 1; g.Data2 = 2; g.Data3 = 3; for (int i = 0; i < 8; ++i) g.Data4[i] = i; EnumerateCallback(&g, _T("Invalid device"), NULL, NULL); #endif }
BOOL setCurrentChannelConfig() { IDirectSound8* ds; DWORD speakerConfig; LPGUID guid = NULL; DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc, (VOID*)&guid); if (DirectSoundCreate8(guid, &ds, NULL) != S_OK) { PrintLastError("DirectSoundCreate8()"); return FALSE; } ds->Initialize(NULL); switch (currentChannelCount) { case 2: speakerConfig = DSSPEAKER_STEREO; break; case 4: speakerConfig = DSSPEAKER_QUAD; break; case 6: speakerConfig = DSSPEAKER_5POINT1; break; case 8: speakerConfig = DSSPEAKER_7POINT1; break; default: speakerConfig = DSSPEAKER_STEREO; break; } if (ds->SetSpeakerConfig(speakerConfig) != S_OK) { PrintLastError("SetSpeakerConfig()"); return FALSE; } if (ds) { ds->Release(); } if (guid) { LocalFree(guid); } return FALSE; }
bool CMpcAudioRendererSettingsWnd::OnActivate() { ASSERT(IPP_FONTSIZE == 13); DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP; CPoint p(10, 10); m_cbWasapiMode.Create(ResStr(IDS_ARS_WASAPI_MODE), dwStyle | BS_AUTOCHECKBOX | BS_LEFTTEXT, CRect(p, CSize(IPP_SCALE(320), m_fontheight)), this, IDC_PP_WASAPI_MODE); p.y += IPP_SCALE(20); m_cbMuteFastForward.Create(ResStr(IDS_ARS_MUTE_FAST_FORWARD), dwStyle | BS_AUTOCHECKBOX | BS_LEFTTEXT, CRect(p, CSize(IPP_SCALE(320), m_fontheight)), this, IDC_PP_MUTE_FAST_FORWARD); p.y += IPP_SCALE(25); m_txtSoundDevice.Create(ResStr(IDS_ARS_SOUND_DEVICE), WS_VISIBLE | WS_CHILD, CRect(p, CSize(IPP_SCALE(115), m_fontheight)), this, (UINT)IDC_STATIC); m_cbSoundDevice.Create(dwStyle | CBS_DROPDOWNLIST | WS_VSCROLL, CRect(p + CPoint(IPP_SCALE(120), -4), CSize(IPP_SCALE(200), 200)), this, IDC_PP_SOUND_DEVICE); SetClassLongPtr(GetDlgItem(IDC_PP_SOUND_DEVICE)->m_hWnd, GCLP_HCURSOR, (LONG_PTR)AfxGetApp()->LoadStandardCursor(IDC_HAND)); DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc, (VOID*)&m_cbSoundDevice); if (m_cbSoundDevice.GetCount() > 0) { int idx = m_cbSoundDevice.FindString(0, m_pMAR->GetSoundDevice()); if (idx < 0) { m_cbSoundDevice.SetCurSel(0); } else { m_cbSoundDevice.SetCurSel(m_cbSoundDevice.FindString(0, m_pMAR->GetSoundDevice())); } } m_cbWasapiMode.SetCheck(m_pMAR->GetWasapiMode()); m_cbMuteFastForward.SetCheck(m_pMAR->GetMuteFastForward()); for (CWnd* pWnd = GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow()) { pWnd->SetFont(&m_font, FALSE); } return true; }
CMpcAudioRenderer::CMpcAudioRenderer(LPUNKNOWN punk, HRESULT *phr) : CBaseRenderer(__uuidof(this), NAME("MPC - Audio Renderer"), punk, phr) , m_pDSBuffer (NULL ) , m_pSoundTouch (NULL ) , m_pDS (NULL ) , m_dwDSWriteOff (0 ) , m_nDSBufSize (0 ) , m_dRate (1.0 ) , m_pReferenceClock (NULL ) , m_pWaveFileFormat (NULL ) , pMMDevice (NULL) , pAudioClient (NULL ) , pRenderClient (NULL ) , m_useWASAPI (true ) , m_bMuteFastForward(false) , m_csSound_Device (_T("")) , nFramesInBuffer (0 ) , hnsPeriod (0 ) , hTask (NULL ) , bufferSize (0) , isAudioClientStarted (false) , lastBufferTime (0) , hnsActualDuration (0) , m_lVolume(DSBVOLUME_MIN) { HMODULE hLib; #ifdef REGISTER_FILTER CRegKey key; TCHAR buff[256]; ULONG len; if (ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, _T("Software\\Gabest\\Filters\\MPC Audio Renderer"), KEY_READ)) { DWORD dw; if (ERROR_SUCCESS == key.QueryDWORDValue(_T("UseWasapi"), dw)) { m_useWASAPI = !!dw; } if (ERROR_SUCCESS == key.QueryDWORDValue(_T("MuteFastForward"), dw)) { m_bMuteFastForward = !!dw; } len = sizeof(buff)/sizeof(buff[0]); memset(buff, 0, sizeof(buff)); if (ERROR_SUCCESS == key.QueryStringValue(_T("SoundDevice"), buff, &len)) { m_csSound_Device = CString(buff); } } #else m_useWASAPI = !!AfxGetApp()->GetProfileInt(_T("Filters\\MPC Audio Renderer"), _T("UseWasapi"), m_useWASAPI); m_bMuteFastForward = !!AfxGetApp()->GetProfileInt(_T("Filters\\MPC Audio Renderer"), _T("MuteFastForward"), m_bMuteFastForward); m_csSound_Device = AfxGetApp()->GetProfileString(_T("Filters\\MPC Audio Renderer"), _T("SoundDevice"), _T("")); #endif m_useWASAPIAfterRestart = m_useWASAPI; // Load Vista specifics DLLs hLib = LoadLibrary (L"AVRT.dll"); if (hLib != NULL) { pfAvSetMmThreadCharacteristicsW = (PTR_AvSetMmThreadCharacteristicsW) GetProcAddress (hLib, "AvSetMmThreadCharacteristicsW"); pfAvRevertMmThreadCharacteristics = (PTR_AvRevertMmThreadCharacteristics) GetProcAddress (hLib, "AvRevertMmThreadCharacteristics"); } else { m_useWASAPI = false; // Wasapi not available below Vista } TRACE(_T("CMpcAudioRenderer constructor\n")); if (!m_useWASAPI) { DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc2, (VOID*)&m_csSound_Device); m_pSoundTouch = new soundtouch::SoundTouch(); *phr = DirectSoundCreate8 (&lpSoundGUID, &m_pDS, NULL); } }
// \brief Create a new device by type (DEFAULT_DEVICE, DIRECTSOUND_DEVICE, AC97_DEVICE) void CAudioContext::SetActiveDevice(int iDevice) { CStdString strAudioDev; if(!m_bAudio2) { strAudioDev = g_guiSettings.GetString("audiooutput.audiodevice"); } else { strAudioDev = g_guiSettings.GetString("audiooutput2.audiodevice"); } /* if device is the same, no need to bother */ #ifdef _WIN32 HRESULT hr; int iPos = strAudioDev.Find(':'); if(iPos != CStdString::npos) strAudioDev.erase(0, iPos+1); if (iDevice == DEFAULT_DEVICE) iDevice = DIRECTSOUND_DEVICE; // default device on win32 is directsound device if(m_iDevice == iDevice && strAudioDev.Equals(m_strDevice)) { if (iDevice != NONE && m_pDirectSoundDevice) { DSCAPS devCaps = {0}; devCaps.dwSize = sizeof(devCaps); HRESULT hr = m_pDirectSoundDevice->GetCaps(&devCaps); if (SUCCEEDED(hr)) // Make sure the DirectSound interface is still valid. return; CLog::Log(LOGDEBUG, "%s - DirectSoundDevice no longer valid and is going to be recreated (0x%08x)", __FUNCTION__, hr); } } #else if(m_iDevice == iDevice) return; #endif CLog::Log(LOGDEBUG, "%s - SetActiveDevice from %i to %i", __FUNCTION__, m_iDevice, iDevice); /* deinit current device */ RemoveActiveDevice(); m_iDevice=iDevice; m_strDevice=strAudioDev; #ifdef HAS_AUDIO memset(&g_digitaldevice, 0, sizeof(GUID)); hr = DirectSoundEnumerate(DSEnumCallback, this); if (FAILED(hr)) CLog::Log(LOGERROR, "%s - failed to enumerate output devices (0x%08X)", __FUNCTION__, hr); if (iDevice==DIRECTSOUND_DEVICE || iDevice==DIRECTSOUND_DEVICE_DIGITAL) { LPGUID guid = NULL; #ifdef _WIN32 CWDSound p_dsound; std::vector<DSDeviceInfo > deviceList = p_dsound.GetSoundDevices(); if (deviceList.size() == 0) CLog::Log(LOGDEBUG, "%s - no output devices found.", __FUNCTION__); std::vector<DSDeviceInfo >::const_iterator iter = deviceList.begin(); for (int i=0; iter != deviceList.end(); i++) { DSDeviceInfo dev = *iter; if (strAudioDev.Equals(dev.strDescription)) { guid = dev.lpGuid; CLog::Log(LOGDEBUG, "%s - selecting %s as output devices", __FUNCTION__, dev.strDescription.c_str()); break; } ++iter; } if (guid == NULL) CLog::Log(LOGDEBUG, "%s - (default playback device).", __FUNCTION__); #else if(iDevice == DIRECTSOUND_DEVICE_DIGITAL && ( g_digitaldevice.Data1 || g_digitaldevice.Data2 || g_digitaldevice.Data3 || g_digitaldevice.Data4 )) guid = &g_digitaldevice; #endif // Create DirectSound hr = DirectSoundCreate( guid, &m_pDirectSoundDevice, NULL ); if (FAILED(hr)) { CLog::Log(LOGERROR, "DirectSoundCreate() Failed (0x%08X)", hr); return; } hr = m_pDirectSoundDevice->SetCooperativeLevel(g_hWnd, DSSCL_PRIORITY); if (FAILED(hr)) { CLog::Log(LOGERROR, "DirectSoundDevice::SetCooperativeLevel() Failed (0x%08X)", hr); return; } } else if (iDevice == DIRECTSOUND_DEVICE_DIGITAL) { } #ifdef HAS_AUDIO_PASS_THROUGH else if (iDevice==AC97_DEVICE) { // Create AC97 Device if (FAILED(Ac97CreateMediaObject(DSAC97_CHANNEL_DIGITAL, NULL, NULL, &m_pAC97Device))) { CLog::Log(LOGERROR, "Failed to create digital Ac97CreateMediaObject()"); return; } } #endif // Don't log an error if the caller specifically asked for no device // externalplayer does this to ensure all audio devices are closed // during external playback else if (iDevice != NONE) { CLog::Log(LOGERROR, "Failed to create audio device"); return; } #endif if (!m_bAudio2) { g_audioManager.Initialize(m_iDevice); } }
bool CAESinkDirectSound::Initialize(AEAudioFormat &format, std::string &device) { if (m_initialized) return false; LPGUID deviceGUID = NULL; RPC_CSTR wszUuid = NULL; HRESULT hr = E_FAIL; std::string strDeviceGUID = device; std::list<DSDevice> DSDeviceList; std::string deviceFriendlyName; DirectSoundEnumerate(DSEnumCallback, &DSDeviceList); if(StringUtils::EndsWithNoCase(device, std::string("default"))) strDeviceGUID = GetDefaultDevice(); for (std::list<DSDevice>::iterator itt = DSDeviceList.begin(); itt != DSDeviceList.end(); ++itt) { if ((*itt).lpGuid) { hr = (UuidToString((*itt).lpGuid, &wszUuid)); std::string sztmp = (char*)wszUuid; std::string szGUID = "{" + std::string(sztmp.begin(), sztmp.end()) + "}"; if (strcasecmp(szGUID.c_str(), strDeviceGUID.c_str()) == 0) { deviceGUID = (*itt).lpGuid; deviceFriendlyName = (*itt).name.c_str(); break; } } if (hr == RPC_S_OK) RpcStringFree(&wszUuid); } hr = DirectSoundCreate(deviceGUID, &m_pDSound, NULL); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Failed to create the DirectSound device %s with error %s, trying the default device.", deviceFriendlyName.c_str(), dserr2str(hr)); hr = DirectSoundCreate(NULL, &m_pDSound, NULL); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Failed to create the default DirectSound device with error %s.", dserr2str(hr)); return false; } } HWND tmp_hWnd; /* Dodge the null handle on first init by using desktop handle */ if (g_hWnd == NULL) tmp_hWnd = GetDesktopWindow(); else tmp_hWnd = g_hWnd; CLog::Log(LOGDEBUG, __FUNCTION__": Using Window handle: %d", tmp_hWnd); hr = m_pDSound->SetCooperativeLevel(tmp_hWnd, DSSCL_PRIORITY); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Failed to create the DirectSound device cooperative level."); CLog::Log(LOGERROR, __FUNCTION__": DSErr: %s", dserr2str(hr)); m_pDSound->Release(); return false; } WAVEFORMATEXTENSIBLE wfxex = {0}; //fill waveformatex ZeroMemory(&wfxex, sizeof(WAVEFORMATEXTENSIBLE)); wfxex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); wfxex.Format.nChannels = format.m_channelLayout.Count(); wfxex.Format.nSamplesPerSec = format.m_sampleRate; if (AE_IS_RAW(format.m_dataFormat)) { wfxex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; wfxex.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF; wfxex.SubFormat = _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF; wfxex.Format.wBitsPerSample = 16; wfxex.Format.nChannels = 2; } else { wfxex.dwChannelMask = SpeakerMaskFromAEChannels(format.m_channelLayout); wfxex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfxex.SubFormat = _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; wfxex.Format.wBitsPerSample = 32; } wfxex.Samples.wValidBitsPerSample = wfxex.Format.wBitsPerSample; wfxex.Format.nBlockAlign = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3); wfxex.Format.nAvgBytesPerSec = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign; m_AvgBytesPerSec = wfxex.Format.nAvgBytesPerSec; unsigned int uiFrameCount = (int)(format.m_sampleRate * 0.01); //default to 10ms chunks m_dwFrameSize = wfxex.Format.nBlockAlign; m_dwChunkSize = m_dwFrameSize * uiFrameCount; m_dwBufferLen = m_dwChunkSize * 12; //120ms total buffer // fill in the secondary sound buffer descriptor DSBUFFERDESC dsbdesc; memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 /** Better position accuracy */ | DSBCAPS_GLOBALFOCUS; /** Allows background playing */ dsbdesc.dwBufferBytes = m_dwBufferLen; dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&wfxex; // now create the stream buffer HRESULT res = IDirectSound_CreateSoundBuffer(m_pDSound, &dsbdesc, &m_pBuffer, NULL); if (res != DS_OK) { if (dsbdesc.dwFlags & DSBCAPS_LOCHARDWARE) { SAFE_RELEASE(m_pBuffer); CLog::Log(LOGDEBUG, __FUNCTION__": Couldn't create secondary buffer (%s). Trying without LOCHARDWARE.", dserr2str(res)); // Try without DSBCAPS_LOCHARDWARE dsbdesc.dwFlags &= ~DSBCAPS_LOCHARDWARE; res = IDirectSound_CreateSoundBuffer(m_pDSound, &dsbdesc, &m_pBuffer, NULL); } if (res != DS_OK) { SAFE_RELEASE(m_pBuffer); CLog::Log(LOGERROR, __FUNCTION__": cannot create secondary buffer (%s)", dserr2str(res)); return false; } } CLog::Log(LOGDEBUG, __FUNCTION__": secondary buffer created"); m_pBuffer->Stop(); AEChannelsFromSpeakerMask(wfxex.dwChannelMask); format.m_channelLayout = m_channelLayout; m_encodedFormat = format.m_dataFormat; format.m_frames = uiFrameCount; format.m_frameSamples = format.m_frames * format.m_channelLayout.Count(); format.m_frameSize = (AE_IS_RAW(format.m_dataFormat) ? wfxex.Format.wBitsPerSample >> 3 : sizeof(float)) * format.m_channelLayout.Count(); format.m_dataFormat = AE_IS_RAW(format.m_dataFormat) ? AE_FMT_S16NE : AE_FMT_FLOAT; m_format = format; m_device = device; m_BufferOffset = 0; m_CacheLen = 0; m_LastCacheCheck = XbmcThreads::SystemClockMillis(); m_initialized = true; m_isDirtyDS = false; CLog::Log(LOGDEBUG, __FUNCTION__": Initializing DirectSound with the following parameters:"); CLog::Log(LOGDEBUG, " Audio Device : %s", ((std::string)deviceFriendlyName).c_str()); CLog::Log(LOGDEBUG, " Sample Rate : %d", wfxex.Format.nSamplesPerSec); CLog::Log(LOGDEBUG, " Sample Format : %s", CAEUtil::DataFormatToStr(format.m_dataFormat)); CLog::Log(LOGDEBUG, " Bits Per Sample : %d", wfxex.Format.wBitsPerSample); CLog::Log(LOGDEBUG, " Valid Bits/Samp : %d", wfxex.Samples.wValidBitsPerSample); CLog::Log(LOGDEBUG, " Channel Count : %d", wfxex.Format.nChannels); CLog::Log(LOGDEBUG, " Block Align : %d", wfxex.Format.nBlockAlign); CLog::Log(LOGDEBUG, " Avg. Bytes Sec : %d", wfxex.Format.nAvgBytesPerSec); CLog::Log(LOGDEBUG, " Samples/Block : %d", wfxex.Samples.wSamplesPerBlock); CLog::Log(LOGDEBUG, " Format cBSize : %d", wfxex.Format.cbSize); CLog::Log(LOGDEBUG, " Channel Layout : %s", ((std::string)format.m_channelLayout).c_str()); CLog::Log(LOGDEBUG, " Channel Mask : %d", wfxex.dwChannelMask); CLog::Log(LOGDEBUG, " Frames : %d", format.m_frames); CLog::Log(LOGDEBUG, " Frame Samples : %d", format.m_frameSamples); CLog::Log(LOGDEBUG, " Frame Size : %d", format.m_frameSize); return true; }
void CAESinkDirectSound::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList) { CAEDeviceInfo deviceInfo; OSVERSIONINFO osvi; IMMDeviceEnumerator* pEnumerator = NULL; IMMDeviceCollection* pEnumDevices = NULL; WAVEFORMATEX* pwfxex = NULL; HRESULT hr; /* See if we are on Windows XP */ ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); if (osvi.dwMajorVersion == 5) { /* We are on XP - WASAPI not supported - enumerate using DS devices */ LPGUID deviceGUID = NULL; RPC_CSTR cszGUID; std::string szGUID; std::list<DSDevice> DSDeviceList; DirectSoundEnumerate(DSEnumCallback, &DSDeviceList); for(std::list<DSDevice>::iterator itt = DSDeviceList.begin(); itt != DSDeviceList.end(); itt++) { if (UuidToString((*itt).lpGuid, &cszGUID) != RPC_S_OK) continue; /* could not convert GUID to string - skip device */ deviceInfo.m_channels.Reset(); deviceInfo.m_dataFormats.clear(); deviceInfo.m_sampleRates.clear(); szGUID = (LPSTR)cszGUID; deviceInfo.m_deviceName = "{" + szGUID + "}"; deviceInfo.m_displayName = (*itt).name; deviceInfo.m_displayNameExtra = std::string("DirectSound: ") + (*itt).name; deviceInfo.m_deviceType = AE_DEVTYPE_PCM; deviceInfo.m_channels = layoutsByChCount[2]; deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_FLOAT)); deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AC3)); deviceInfo.m_sampleRates.push_back((DWORD) 96000); deviceInfoList.push_back(deviceInfo); } RpcStringFree(&cszGUID); return; } /* Windows Vista or later - supporting WASAPI device probing */ hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator); EXIT_ON_FAILURE(hr, __FUNCTION__": Could not allocate WASAPI device enumerator. CoCreateInstance error code: %li", hr) UINT uiCount = 0; hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pEnumDevices); EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint enumeration failed.") hr = pEnumDevices->GetCount(&uiCount); EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint count failed.") for (UINT i = 0; i < uiCount; i++) { IMMDevice *pDevice = NULL; IPropertyStore *pProperty = NULL; PROPVARIANT varName; PropVariantInit(&varName); deviceInfo.m_channels.Reset(); deviceInfo.m_dataFormats.clear(); deviceInfo.m_sampleRates.clear(); hr = pEnumDevices->Item(i, &pDevice); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint failed."); goto failed; } hr = pDevice->OpenPropertyStore(STGM_READ, &pProperty); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint properties failed."); SAFE_RELEASE(pDevice); goto failed; } hr = pProperty->GetValue(PKEY_Device_FriendlyName, &varName); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint device name failed."); SAFE_RELEASE(pDevice); SAFE_RELEASE(pProperty); goto failed; } std::wstring strRawFriendlyName(varName.pwszVal); std::string strFriendlyName = std::string(strRawFriendlyName.begin(), strRawFriendlyName.end()); PropVariantClear(&varName); hr = pProperty->GetValue(PKEY_AudioEndpoint_GUID, &varName); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint GUID failed."); SAFE_RELEASE(pDevice); SAFE_RELEASE(pProperty); goto failed; } std::wstring strRawDevName(varName.pwszVal); std::string strDevName = std::string(strRawDevName.begin(), strRawDevName.end()); PropVariantClear(&varName); hr = pProperty->GetValue(PKEY_AudioEndpoint_FormFactor, &varName); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint form factor failed."); SAFE_RELEASE(pDevice); SAFE_RELEASE(pProperty); goto failed; } std::string strWinDevType = winEndpoints[(EndpointFormFactor)varName.uiVal].winEndpointType; AEDeviceType aeDeviceType = winEndpoints[(EndpointFormFactor)varName.uiVal].aeDeviceType; PropVariantClear(&varName); /* In shared mode Windows tells us what format the audio must be in. */ IAudioClient *pClient; hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pClient); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Activate device failed (%s)", WASAPIErrToStr(hr)); } //hr = pClient->GetMixFormat(&pwfxex); hr = pProperty->GetValue(PKEY_AudioEngine_DeviceFormat, &varName); if (SUCCEEDED(hr)) { WAVEFORMATEX* smpwfxex = (WAVEFORMATEX*)varName.blob.pBlobData; deviceInfo.m_channels = layoutsByChCount[std::min(smpwfxex->nChannels, (WORD) 2)]; deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_FLOAT)); deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AC3)); deviceInfo.m_sampleRates.push_back(std::min(smpwfxex->nSamplesPerSec, (DWORD) 96000)); } else { CLog::Log(LOGERROR, __FUNCTION__": GetMixFormat failed (%s)", WASAPIErrToStr(hr)); } pClient->Release(); SAFE_RELEASE(pDevice); SAFE_RELEASE(pProperty); deviceInfo.m_deviceName = strDevName; deviceInfo.m_displayName = strWinDevType.append(strFriendlyName); deviceInfo.m_displayNameExtra = std::string("DirectSound: ").append(strFriendlyName); deviceInfo.m_deviceType = aeDeviceType; /* Now logged by AESinkFactory on startup */ //CLog::Log(LOGDEBUG,"Audio Device %d: %s", i, ((std::string)deviceInfo).c_str()); deviceInfoList.push_back(deviceInfo); } return; failed: if (FAILED(hr)) CLog::Log(LOGERROR, __FUNCTION__": Failed to enumerate WASAPI endpoint devices (%s).", WASAPIErrToStr(hr)); SAFE_RELEASE(pEnumDevices); SAFE_RELEASE(pEnumerator); }
// \brief Create a new device by type (DEFAULT_DEVICE, DIRECTSOUND_DEVICE, AC97_DEVICE) // Note: DEFAULT_DEVICE is created by the IAudioDeviceChangedCallback void CAudioContext::SetActiveDevice(int iDevice) { /* if device is the same, no need to bother */ #ifdef _WIN32 if (iDevice == DEFAULT_DEVICE) iDevice = DIRECTSOUND_DEVICE; // default device on win32 is directsound device if(m_iDevice == iDevice && g_guiSettings.GetString("audiooutput.audiodevice").Equals(m_strDevice)) { if (iDevice != NONE && m_pDirectSoundDevice) { DSCAPS devCaps = {0}; devCaps.dwSize = sizeof(devCaps); if (SUCCEEDED(m_pDirectSoundDevice->GetCaps(&devCaps))) // Make sure the DirectSound interface is still valid. return; } } #else if(m_iDevice == iDevice) return; #endif if (iDevice==DEFAULT_DEVICE) { /* we just tell callbacks to init, it will setup audio */ g_audioManager.Initialize(iDevice); return; } /* deinit current device */ RemoveActiveDevice(); m_iDevice=iDevice; if (g_guiSettings.HasSetting("audiooutput.audiodevice")) { m_strDevice=g_guiSettings.GetString("audiooutput.audiodevice"); } else { m_strDevice="audiodevice"; } #ifdef HAS_AUDIO memset(&g_digitaldevice, 0, sizeof(GUID)); if (FAILED(DirectSoundEnumerate(DSEnumCallback, this))) CLog::Log(LOGERROR, "%s - failed to enumerate output devices", __FUNCTION__); if (iDevice==DIRECTSOUND_DEVICE || iDevice==DIRECTSOUND_DEVICE_DIGITAL) { LPGUID guid = NULL; #ifdef _WIN32 CWDSound p_dsound; std::vector<DSDeviceInfo > deviceList = p_dsound.GetSoundDevices(); std::vector<DSDeviceInfo >::const_iterator iter = deviceList.begin(); for (int i=0; iter != deviceList.end(); i++) { DSDeviceInfo dev = *iter; if (g_guiSettings.GetString("audiooutput.audiodevice").Equals(dev.strDescription)) { guid = dev.lpGuid; CLog::Log(LOGDEBUG, "%s - selecting %s as output devices", __FUNCTION__, dev.strDescription.c_str()); break; } ++iter; } #else if(iDevice == DIRECTSOUND_DEVICE_DIGITAL && ( g_digitaldevice.Data1 || g_digitaldevice.Data2 || g_digitaldevice.Data3 || g_digitaldevice.Data4 )) guid = &g_digitaldevice; #endif #ifdef _WIN32 //If default device was already created, use it (default device on win32 is directsound device) if (iDevice == DIRECTSOUND_DEVICE && m_pDefaultDirectSoundDevice != NULL) { m_pDirectSoundDevice = m_pDefaultDirectSoundDevice; m_pDirectSoundDevice->AddRef(); } #endif // Create DirectSound if (m_pDirectSoundDevice == NULL && FAILED(DirectSoundCreate( guid, &m_pDirectSoundDevice, NULL ))) { CLog::Log(LOGERROR, "DirectSoundCreate() Failed"); return; } #ifdef _WIN32 //If default device (default device on win32 is directsound device), save it if (iDevice == DIRECTSOUND_DEVICE && m_pDefaultDirectSoundDevice == NULL) { m_pDefaultDirectSoundDevice = m_pDirectSoundDevice; m_pDefaultDirectSoundDevice->AddRef(); } #endif #ifndef _XBOX if (FAILED(m_pDirectSoundDevice->SetCooperativeLevel(g_hWnd, DSSCL_PRIORITY))) { CLog::Log(LOGERROR, "DirectSoundDevice::SetCooperativeLevel() Failed"); return; } #endif } else if (iDevice == DIRECTSOUND_DEVICE_DIGITAL) { } #ifdef HAS_AUDIO_PASS_THROUGH else if (iDevice==AC97_DEVICE) { // Create AC97 Device if (FAILED(Ac97CreateMediaObject(DSAC97_CHANNEL_DIGITAL, NULL, NULL, &m_pAC97Device))) { CLog::Log(LOGERROR, "Failed to create digital Ac97CreateMediaObject()"); return; } } #endif // Don't log an error if the caller specifically asked for no device // externalplayer does this to ensure all audio devices are closed // during external playback else if (iDevice != NONE) { CLog::Log(LOGERROR, "Failed to create audio device"); return; } #endif g_audioManager.Initialize(m_iDevice); }
void CWin32DirectSound::EnumerateAudioSinks(AudioSinkList &vAudioSinks, bool passthrough) { if (FAILED(DirectSoundEnumerate(DSEnumCallback, &vAudioSinks))) CLog::Log(LOGERROR, "%s - failed to enumerate output devices", __FUNCTION__); }
BOOL CALLBACK DSound51::ConfigProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { int wmId,wmEvent; int tSel=0; switch(uMsg) { case WM_INITDIALOG: haveGuid = ! FAILED(GUIDFromString(Config_DSound51.Device,&DevGuid)); SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_RESETCONTENT,0,0); ndevs=0; DirectSoundEnumerate(DSEnumCallback,NULL); tSel=-1; for(int i=0;i<ndevs;i++) { SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_ADDSTRING,0,(LPARAM)devices[i].name); if(haveGuid && IsEqualGUID(devices[i].guid,DevGuid)) { tSel=i; } } if(tSel>=0) { SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_SETCURSEL,tSel,0); } INIT_SLIDER(IDC_LEFT_GAIN_SLIDER,0,512,64,16,8); INIT_SLIDER(IDC_RIGHT_GAIN_SLIDER,0,512,64,16,8); INIT_SLIDER(IDC_RLEFT_GAIN_SLIDER,0,512,64,16,8); INIT_SLIDER(IDC_RRIGHT_GAIN_SLIDER,0,512,64,16,8); INIT_SLIDER(IDC_CENTER_GAIN_SLIDER,0,512,64,16,8); INIT_SLIDER(IDC_LFE_SLIDER,0,512,64,16,8); INIT_SLIDER(IDC_LR_CENTER_SLIDER,0,512,64,16,8); AssignSliderValue( hWnd, IDC_LEFT_GAIN_SLIDER, IDC_LEFT_GAIN_EDIT, Config_DSound51.GainL ); AssignSliderValue( hWnd, IDC_RIGHT_GAIN_SLIDER, IDC_RIGHT_GAIN_EDIT, Config_DSound51.GainR ); AssignSliderValue( hWnd, IDC_RLEFT_GAIN_SLIDER, IDC_RLEFT_GAIN_EDIT, Config_DSound51.GainSL ); AssignSliderValue( hWnd, IDC_RRIGHT_GAIN_SLIDER, IDC_RRIGHT_GAIN_EDIT, Config_DSound51.GainSR ); AssignSliderValue( hWnd, IDC_CENTER_GAIN_SLIDER, IDC_CENTER_GAIN_EDIT, Config_DSound51.GainC); AssignSliderValue( hWnd, IDC_LFE_SLIDER, IDC_LFE_EDIT, Config_DSound51.GainLFE); AssignSliderValue( hWnd, IDC_LR_CENTER_SLIDER, IDC_LR_CENTER_EDIT, Config_DSound51.AddCLR ); char temp[128]; INIT_SLIDER( IDC_BUFFERS_SLIDER, 2, MAX_BUFFER_COUNT, 2, 1, 1 ); SendMessage(GetDlgItem(hWnd,IDC_BUFFERS_SLIDER),TBM_SETPOS,TRUE,Config_DSound51.NumBuffers); sprintf_s(temp, 128, "%d (%d ms latency)",Config_DSound51.NumBuffers, 1000 / (96000 / (Config_DSound51.NumBuffers * BufferSize))); SetWindowText(GetDlgItem(hWnd,IDC_LATENCY_LABEL2),temp); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDOK: { int i = (int)SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_GETCURSEL,0,0); if(!devices[i].hasGuid) { Config_DSound51.Device[0]=0; // clear device name to "" } else { sprintf_s(Config_DSound51.Device,256,"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", devices[i].guid.Data1, devices[i].guid.Data2, devices[i].guid.Data3, devices[i].guid.Data4[0], devices[i].guid.Data4[1], devices[i].guid.Data4[2], devices[i].guid.Data4[3], devices[i].guid.Data4[4], devices[i].guid.Data4[5], devices[i].guid.Data4[6], devices[i].guid.Data4[7] ); Config_DSound51.NumBuffers = GetSliderValue( hWnd, IDC_BUFFERS_SLIDER ); Config_DSound51.GainL = GetSliderValue( hWnd, IDC_LEFT_GAIN_SLIDER ); Config_DSound51.GainR = GetSliderValue( hWnd, IDC_RIGHT_GAIN_SLIDER ); Config_DSound51.GainSL = GetSliderValue( hWnd, IDC_RLEFT_GAIN_SLIDER ); Config_DSound51.GainSR = GetSliderValue( hWnd, IDC_RRIGHT_GAIN_SLIDER ); Config_DSound51.GainLFE = GetSliderValue( hWnd, IDC_LFE_SLIDER ); Config_DSound51.GainC = GetSliderValue( hWnd, IDC_CENTER_GAIN_SLIDER ); Config_DSound51.AddCLR = GetSliderValue( hWnd, IDC_LR_CENTER_SLIDER ); if( Config_DSound51.NumBuffers < 2 ) Config_DSound51.NumBuffers = 2; if( Config_DSound51.NumBuffers > MAX_BUFFER_COUNT ) Config_DSound51.NumBuffers = MAX_BUFFER_COUNT; } } EndDialog(hWnd,0); break; case IDCANCEL: EndDialog(hWnd,0); break; default: return FALSE; } break; case WM_HSCROLL: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch(wmId) { //case TB_ENDTRACK: //case TB_THUMBPOSITION: case TB_LINEUP: case TB_LINEDOWN: case TB_PAGEUP: case TB_PAGEDOWN: wmEvent=(int)SendMessage((HWND)lParam,TBM_GETPOS,0,0); case TB_THUMBTRACK: if( wmEvent < 2 ) wmEvent = 2; if( wmEvent > MAX_BUFFER_COUNT ) wmEvent = MAX_BUFFER_COUNT; SendMessage((HWND)lParam,TBM_SETPOS,TRUE,wmEvent); sprintf_s(temp,128,"%d (%d ms latency)",wmEvent, 1000 / (96000 / (wmEvent * BufferSize))); SetWindowText(GetDlgItem(hWnd,IDC_LATENCY_LABEL2),temp); break; default: return FALSE; } break; case WM_VSCROLL: HANDLE_SCROLL_MESSAGE(IDC_LEFT_GAIN_SLIDER,IDC_LEFT_GAIN_EDIT); HANDLE_SCROLL_MESSAGE(IDC_RIGHT_GAIN_SLIDER,IDC_RIGHT_GAIN_EDIT); HANDLE_SCROLL_MESSAGE(IDC_RLEFT_GAIN_SLIDER,IDC_RLEFT_GAIN_EDIT); HANDLE_SCROLL_MESSAGE(IDC_RRIGHT_GAIN_SLIDER,IDC_RRIGHT_GAIN_EDIT); HANDLE_SCROLL_MESSAGE(IDC_CENTER_GAIN_SLIDER,IDC_CENTER_GAIN_EDIT); HANDLE_SCROLL_MESSAGE(IDC_LFE_SLIDER,IDC_LFE_EDIT); HANDLE_SCROLL_MESSAGE(IDC_LR_CENTER_SLIDER,IDC_LR_CENTER_EDIT); default: return FALSE; } return TRUE; }
void CAESinkDirectSound::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bool force) { CAEDeviceInfo deviceInfo; IMMDeviceEnumerator* pEnumerator = NULL; IMMDeviceCollection* pEnumDevices = NULL; HRESULT hr; /* See if we are on Windows XP */ if (!g_sysinfo.IsWindowsVersionAtLeast(CSysInfo::WindowsVersionVista)) { /* We are on XP - WASAPI not supported - enumerate using DS devices */ LPGUID deviceGUID = NULL; RPC_CSTR cszGUID; std::string szGUID; std::list<DSDevice> DSDeviceList; DirectSoundEnumerate(DSEnumCallback, &DSDeviceList); for(std::list<DSDevice>::iterator itt = DSDeviceList.begin(); itt != DSDeviceList.end(); ++itt) { if (UuidToString((*itt).lpGuid, &cszGUID) != RPC_S_OK) continue; /* could not convert GUID to string - skip device */ deviceInfo.m_channels.Reset(); deviceInfo.m_dataFormats.clear(); deviceInfo.m_sampleRates.clear(); szGUID = (LPSTR)cszGUID; deviceInfo.m_deviceName = "{" + szGUID + "}"; deviceInfo.m_displayName = (*itt).name; deviceInfo.m_displayNameExtra = std::string("DirectSound: ") + (*itt).name; deviceInfo.m_deviceType = AE_DEVTYPE_PCM; deviceInfo.m_channels = layoutsByChCount[2]; deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_FLOAT)); deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AC3)); deviceInfo.m_sampleRates.push_back((DWORD) 96000); deviceInfoList.push_back(deviceInfo); } RpcStringFree(&cszGUID); return; } /* Windows Vista or later - supporting WASAPI device probing */ hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator); EXIT_ON_FAILURE(hr, __FUNCTION__": Could not allocate WASAPI device enumerator. CoCreateInstance error code: %li", hr) UINT uiCount = 0; hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pEnumDevices); EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint enumeration failed.") hr = pEnumDevices->GetCount(&uiCount); EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint count failed.") for (UINT i = 0; i < uiCount; i++) { IMMDevice *pDevice = NULL; IPropertyStore *pProperty = NULL; PROPVARIANT varName; PropVariantInit(&varName); deviceInfo.m_channels.Reset(); deviceInfo.m_dataFormats.clear(); deviceInfo.m_sampleRates.clear(); hr = pEnumDevices->Item(i, &pDevice); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint failed."); goto failed; } hr = pDevice->OpenPropertyStore(STGM_READ, &pProperty); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint properties failed."); SAFE_RELEASE(pDevice); goto failed; } hr = pProperty->GetValue(PKEY_Device_FriendlyName, &varName); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint device name failed."); SAFE_RELEASE(pDevice); SAFE_RELEASE(pProperty); goto failed; } std::string strFriendlyName = localWideToUtf(varName.pwszVal); PropVariantClear(&varName); hr = pProperty->GetValue(PKEY_AudioEndpoint_GUID, &varName); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint GUID failed."); SAFE_RELEASE(pDevice); SAFE_RELEASE(pProperty); goto failed; } std::string strDevName = localWideToUtf(varName.pwszVal); PropVariantClear(&varName); hr = pProperty->GetValue(PKEY_AudioEndpoint_FormFactor, &varName); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Retrieval of DirectSound endpoint form factor failed."); SAFE_RELEASE(pDevice); SAFE_RELEASE(pProperty); goto failed; } std::string strWinDevType = winEndpoints[(EndpointFormFactor)varName.uiVal].winEndpointType; AEDeviceType aeDeviceType = winEndpoints[(EndpointFormFactor)varName.uiVal].aeDeviceType; PropVariantClear(&varName); /* In shared mode Windows tells us what format the audio must be in. */ IAudioClient *pClient; hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pClient); if (FAILED(hr)) { CLog::Log(LOGERROR, __FUNCTION__": Activate device failed (%s)", WASAPIErrToStr(hr)); goto failed; } //hr = pClient->GetMixFormat(&pwfxex); hr = pProperty->GetValue(PKEY_AudioEngine_DeviceFormat, &varName); if (SUCCEEDED(hr) && varName.blob.cbSize > 0) { WAVEFORMATEX* smpwfxex = (WAVEFORMATEX*)varName.blob.pBlobData; deviceInfo.m_channels = layoutsByChCount[std::max(std::min(smpwfxex->nChannels, (WORD) DS_SPEAKER_COUNT), (WORD) 2)]; deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_FLOAT)); deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AC3)); deviceInfo.m_sampleRates.push_back(std::min(smpwfxex->nSamplesPerSec, (DWORD) 192000)); } else { CLog::Log(LOGERROR, __FUNCTION__": Getting DeviceFormat failed (%s)", WASAPIErrToStr(hr)); } pClient->Release(); SAFE_RELEASE(pDevice); SAFE_RELEASE(pProperty); deviceInfo.m_deviceName = strDevName; deviceInfo.m_displayName = strWinDevType.append(strFriendlyName); deviceInfo.m_displayNameExtra = std::string("DirectSound: ").append(strFriendlyName); deviceInfo.m_deviceType = aeDeviceType; deviceInfoList.push_back(deviceInfo); } // since AE takes the first device in deviceInfoList as default audio device we need // to sort it in order to use the real default device if(deviceInfoList.size() > 1) { std::string strDD = GetDefaultDevice(); for (AEDeviceInfoList::iterator itt = deviceInfoList.begin(); itt != deviceInfoList.end(); ++itt) { CAEDeviceInfo devInfo = *itt; if(devInfo.m_deviceName == strDD) { deviceInfoList.erase(itt); deviceInfoList.insert(deviceInfoList.begin(), devInfo); break; } } } return; failed: if (FAILED(hr)) CLog::Log(LOGERROR, __FUNCTION__": Failed to enumerate WASAPI endpoint devices (%s).", WASAPIErrToStr(hr)); SAFE_RELEASE(pEnumDevices); SAFE_RELEASE(pEnumerator); }
void I_InitSound(void) { // proff 07/04/98: Added for CYGWIN32 compatibility #ifdef HAVE_LIBDSOUND HRESULT error; int c; int i; #endif // HAVE_LIBDSOUND // proff 07/01/98: Added I_InitMusic if (!nomusicparm) I_InitMusic(); if (nosfxparm) return; // proff 07/04/98: Added for CYGWIN32 compatibility #ifdef HAVE_LIBDSOUND // proff 11/21/98: Added DirectSound device selection i = M_CheckParm ("-dsounddevice"); if ((i) || (snd_dsounddevice)) { printf("I_InitSound: Sound Devices\n"); DirectSoundEnumerate(&DSEnumCallback,NULL); DSoundDevice=snd_dsounddevice; if (i) DSoundDevice=atoi(myargv[i+1]); DSoundDevice= (DSoundDevice < 0) ? 0 : (DSoundDevice >= DSDeviceCount) ? 0 : DSoundDevice; } printf("I_InitSound: "); error = DirectSoundCreate(DSDeviceGUIDs[DSoundDevice], &lpDS, NULL); // proff 11/21/98: End of additions and changes if (error == DSERR_NODRIVER) { lpDS = NULL; printf("no sounddevice found\n"); noDSound = true; return; } noDSound = false; if (error != DS_OK) { noDSound = true; return; } // open the hidden sound window we use to play sounds through OpenSoundWnd(); printf("created DirectSound. Selected Device: %i\n", DSoundDevice); atexit(I_ShutdownSound); error = IDirectSound_SetCooperativeLevel(lpDS, soundWnd , DSSCL_EXCLUSIVE); if (error != DS_OK) { noDSound = true; return; } printf("I_InitSound: "); printf("CooperativeLevel set\n"); printf("I_InitSound: "); // error is returned but it works ... ?? error = CreatePrimaryBuffer(); // if (error != DS_OK) // { // printf("ERROR: Couldnt create primary buffer\n"); // noDSound = true; // return; // } numChannels = default_numChannels; lpSecondaryDSB = malloc(sizeof(LPDIRECTSOUNDBUFFER)*numChannels); if (lpSecondaryDSB) { memset(lpSecondaryDSB, 0, sizeof(LPDIRECTSOUNDBUFFER) * numChannels); printf ("Channels : %i\n", numChannels); } else { noDSound = true; return; } ChannelInfo = malloc(sizeof(channel_info_t)*numChannels); if (ChannelInfo) { // proff 11/09/98: Added for security memset(ChannelInfo, 0, sizeof(channel_info_t) * numChannels); } else { noDSound = true; return; } for (c=0; c<numChannels; c++) { error = CreateSecondaryBuffer(&lpSecondaryDSB[c], 65535); if (error != DS_OK) { noDSound = true; return; } } printf("DirectSound initialised ok!\n"); #endif // HAVE_LIBDSOUND }
static void *dsound_init(const char *device, unsigned rate, unsigned latency) { WAVEFORMATEX wfx = {0}; DSBUFFERDESC bufdesc = {0}; struct dsound_dev dev = {0}; dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds)); if (!ds) goto error; InitializeCriticalSection(&ds->crit); if (device) dev.device = strtoul(device, NULL, 0); RARCH_LOG("DirectSound devices:\n"); #ifndef _XBOX DirectSoundEnumerate(enumerate_cb, &dev); #endif if (DirectSoundCreate(dev.guid, &ds->ds, NULL) != DS_OK) goto error; #ifndef _XBOX if (IDirectSound_SetCooperativeLevel(ds->ds, GetDesktopWindow(), DSSCL_PRIORITY) != DS_OK) goto error; #endif wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; wfx.nSamplesPerSec = rate; wfx.wBitsPerSample = 16; wfx.nBlockAlign = 2 * sizeof(int16_t); wfx.nAvgBytesPerSec = rate * 2 * sizeof(int16_t); ds->buffer_size = (latency * wfx.nAvgBytesPerSec) / 1000; ds->buffer_size /= CHUNK_SIZE; ds->buffer_size *= CHUNK_SIZE; if (ds->buffer_size < 4 * CHUNK_SIZE) ds->buffer_size = 4 * CHUNK_SIZE; RARCH_LOG("[DirectSound]: Setting buffer size of %u bytes\n", ds->buffer_size); RARCH_LOG("[DirectSound]: Latency = %u ms\n", (unsigned)((1000 * ds->buffer_size) / wfx.nAvgBytesPerSec)); bufdesc.dwSize = sizeof(DSBUFFERDESC); bufdesc.dwFlags = 0; #ifndef _XBOX bufdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; #endif bufdesc.dwBufferBytes = ds->buffer_size; bufdesc.lpwfxFormat = &wfx; ds->event = CreateEvent(NULL, false, false, NULL); if (!ds->event) goto error; ds->buffer = fifo_new(4 * 1024); if (!ds->buffer) goto error; if (IDirectSound_CreateSoundBuffer(ds->ds, &bufdesc, &ds->dsb, 0) != DS_OK) goto error; IDirectSoundBuffer_SetVolume(ds->dsb, DSBVOLUME_MAX); IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0); dsound_clear_buffer(ds); if (IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) != DS_OK) goto error; if (!dsound_start_thread(ds)) goto error; return ds; error: RARCH_ERR("[DirectSound] Error occured in init.\n"); dsound_free(ds); return NULL; }