Beispiel #1
0
/****************************************** 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;
}
Beispiel #2
0
//============================================================
//	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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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.");
}
Beispiel #6
0
///// 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;
}
Beispiel #7
0
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 "";
}
Beispiel #8
0
/*
 * 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;
}
Beispiel #9
0
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;
}
Beispiel #10
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
int EnumSoundDevice( void )
{
	SoundDeviceNum=0;
	if( DS_OK != DirectSoundEnumerate( (LPDSENUMCALLBACK)DSoundEnumCallback, NULL ) ){
		return 0;
	}
	return SoundDeviceNum;
}
Beispiel #13
0
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;
}
Beispiel #14
0
Datei: dsound.c Projekt: m64/PEG
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);
}
Beispiel #15
0
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;
}
Beispiel #18
0
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
}
Beispiel #19
0
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;
}
Beispiel #21
0
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);
    }
}
Beispiel #22
0
// \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;
}
Beispiel #24
0
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);

}
Beispiel #25
0
// \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);
}
Beispiel #26
0
void CWin32DirectSound::EnumerateAudioSinks(AudioSinkList &vAudioSinks, bool passthrough)
{
  if (FAILED(DirectSoundEnumerate(DSEnumCallback, &vAudioSinks)))
    CLog::Log(LOGERROR, "%s - failed to enumerate output devices", __FUNCTION__);
}
Beispiel #27
0
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;
}
Beispiel #28
0
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);

}
Beispiel #29
0
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
}
Beispiel #30
0
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;
}