예제 #1
0
const QHash<QString, QString> WASAPISystem::getDevices(EDataFlow dataflow) {
	QHash<QString, QString> devices;

	HRESULT hr;

	IMMDeviceEnumerator *pEnumerator = NULL;
	IMMDeviceCollection *pCollection = NULL;

	hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), reinterpret_cast<void **>(&pEnumerator));

	if (! pEnumerator || FAILED(hr)) {
		qWarning("WASAPI: Failed to instatiate enumerator");
	} else {
		hr = pEnumerator->EnumAudioEndpoints(dataflow, DEVICE_STATE_ACTIVE, &pCollection);
		if (! pCollection || FAILED(hr)) {
			qWarning("WASAPI: Failed to enumerate");
		} else {
			devices.insert(QString(), tr("Default Device"));

			UINT ndev = 0;
			pCollection->GetCount(&ndev);
			for (unsigned int idx=0;idx<ndev;++idx) {
				IMMDevice *pDevice = NULL;
				IPropertyStore *pStore = NULL;

				pCollection->Item(idx, &pDevice);
				pDevice->OpenPropertyStore(STGM_READ, &pStore);

				LPWSTR strid = NULL;
				pDevice->GetId(&strid);

				PROPVARIANT varName;
				PropVariantInit(&varName);

				pStore->GetValue(PKEY_Device_FriendlyName, &varName);

				devices.insert(QString::fromWCharArray(strid), QString::fromWCharArray(varName.pwszVal));

				PropVariantClear(&varName);
				CoTaskMemFree(strid);

				pStore->Release();
				pDevice->Release();
			}
			pCollection->Release();
		}
		pEnumerator->Release();
	}

	return devices;
}
예제 #2
0
bool ChangeVolume(double nVolume,bool bScalar)
{
 
    HRESULT hr=NULL;
    bool decibels = false;
    bool scalar = false;
    double newVolume=nVolume;
 
    CoInitialize(NULL);

		IMMDeviceEnumerator *deviceEnumerator = NULL;
		hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, 
		                      __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
		IMMDevice *defaultDevice = NULL;
 
		hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
		deviceEnumerator->Release();
		deviceEnumerator = NULL;
 
		IAudioEndpointVolume *endpointVolume = NULL;
		hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), 
		     CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
		defaultDevice->Release();
		defaultDevice = NULL;
 
		// -------------------------
		float currentVolume = 0;
		endpointVolume->GetMasterVolumeLevel(&currentVolume);
		//printf("Current volume in dB is: %f\n", currentVolume);

		hr = endpointVolume->GetMasterVolumeLevelScalar(&currentVolume);
		//CString strCur=L"";
		//strCur.Format(L"%f",currentVolume);
		//AfxMessageBox(strCur);

		// printf("Current volume as a scalar is: %f\n", currentVolume);
		if (bScalar==false)
		{
		    hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL);
		}
		else if (bScalar==true)
		{
		    hr = endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL);
		}
		endpointVolume->Release();
 
    CoUninitialize();
 
    return FALSE;
}
예제 #3
0
IAudioEndpointVolume * GetEndpointVolume() {
  HRESULT hr;
  IMMDeviceEnumerator *deviceEnumerator = NULL;
  hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
  IMMDevice *defaultDevice = NULL;

  hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
  deviceEnumerator->Release();
  deviceEnumerator = NULL;

  IAudioEndpointVolume *endpointVolume = NULL;
  hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
  defaultDevice->Release();
  defaultDevice = NULL;
  return endpointVolume;
}
예제 #4
0
Array AudioDriverWASAPI::audio_device_get_list(bool p_capture) {

	Array list;
	IMMDeviceCollection *devices = NULL;
	IMMDeviceEnumerator *enumerator = NULL;

	list.push_back(String("Default"));

	CoInitialize(NULL);

	HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator);
	ERR_FAIL_COND_V(hr != S_OK, Array());

	hr = enumerator->EnumAudioEndpoints(p_capture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &devices);
	ERR_FAIL_COND_V(hr != S_OK, Array());

	UINT count = 0;
	hr = devices->GetCount(&count);
	ERR_FAIL_COND_V(hr != S_OK, Array());

	for (ULONG i = 0; i < count; i++) {
		IMMDevice *device = NULL;

		hr = devices->Item(i, &device);
		ERR_BREAK(hr != S_OK);

		IPropertyStore *props = NULL;
		hr = device->OpenPropertyStore(STGM_READ, &props);
		ERR_BREAK(hr != S_OK);

		PROPVARIANT propvar;
		PropVariantInit(&propvar);

		hr = props->GetValue(PKEY_Device_FriendlyName, &propvar);
		ERR_BREAK(hr != S_OK);

		list.push_back(String(propvar.pwszVal));

		PropVariantClear(&propvar);
		props->Release();
		device->Release();
	}

	devices->Release();
	enumerator->Release();
	return list;
}
예제 #5
0
bool SexyALI_WASAPISH_Avail(void)
{
 IMMDeviceEnumerator *imd = NULL;
 HRESULT hr;

 hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 if(hr != S_OK && hr != S_FALSE)
  return(false);

 hr = CoCreateInstance(LV_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, LV_IID_IMMDeviceEnumerator, (void**)&imd);
 if(FAILED(hr))
  return(false);

 imd->Release();

 return(true);
}
예제 #6
0
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuidStr(WCHAR deviceOutStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE])
{
	REV_TRACE(ovr_GetAudioDeviceOutGuidStr);

	if (!deviceOutStrBuffer)
		return ovrError_InvalidParameter;

	// Query and cache the result
	static WCHAR cachedBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE] = {};
	if (wcslen(cachedBuffer) == 0)
	{
		HRESULT com = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

		IMMDeviceEnumerator* pEnumerator;
		const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
		const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
		HRESULT hr = CoCreateInstance(
			CLSID_MMDeviceEnumerator, NULL,
			CLSCTX_ALL, IID_IMMDeviceEnumerator,
			(void**)&pEnumerator);
		if (FAILED(hr))
			return ovrError_AudioComError;

		IMMDevice* pDevice;
		hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
		if (FAILED(hr))
			return ovrError_AudioDeviceNotFound;

		LPWSTR pGuid;
		hr = pDevice->GetId(&pGuid);
		if (FAILED(hr))
			return ovrError_AudioComError;

		wcsncpy(cachedBuffer, pGuid, OVR_AUDIO_MAX_DEVICE_STR_SIZE);

		// Cleanup
		pDevice->Release();
		pEnumerator->Release();
		if (SUCCEEDED(com))
			CoUninitialize();
	}

	wcsncpy(deviceOutStrBuffer, cachedBuffer, OVR_AUDIO_MAX_DEVICE_STR_SIZE);
	return ovrSuccess;
}
예제 #7
0
//
//  We can "Chat" if there's more than one capture device.
//
bool CWasapiChat::Initialize(bool UseInputDevice)
{
    IMMDeviceEnumerator *deviceEnumerator;
    HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&deviceEnumerator));
    if (FAILED(hr))
    {
        MessageBox(_AppWindow, L"Unable to instantiate device enumerator", L"WASAPI Transport Initialize Failure", MB_OK);
        return false;
    }

    if (UseInputDevice)
    {
        _Flow = eCapture;
    }
    else
    {
        _Flow = eRender;
    }

    hr = deviceEnumerator->GetDefaultAudioEndpoint(_Flow, eCommunications, &_ChatEndpoint);
    deviceEnumerator->Release();
    if (FAILED(hr))
    {
        MessageBox(_AppWindow, L"Unable to retrieve default endpoint", L"WASAPI Transport Initialize Failure", MB_OK);
        return false;
    }
    //
    //  Create our shutdown event - we want an auto reset event that starts in the not-signaled state.
    //
    _ShutdownEvent = CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
    if (_ShutdownEvent == NULL)
    {
        MessageBox(_AppWindow, L"Unable to create shutdown event.", L"WASAPI Transport Initialize Failure", MB_OK);
        return false;
    }

    _AudioSamplesReadyEvent = CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
    if (_ShutdownEvent == NULL)
    {
        MessageBox(_AppWindow, L"Unable to create samples ready event.", L"WASAPI Transport Initialize Failure", MB_OK);
        return false;
    }

    return true;
}
IAudioSessionEnumerator* GetAudioSessionEnumerator() {
  IMMDeviceEnumerator* deviceEnumerator = nullptr;
  CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);

  IMMDevice* device = nullptr;
  deviceEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &device);

  IAudioSessionManager2* sessionManager = nullptr;
  device->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, nullptr, (void**)&sessionManager);

  IAudioSessionEnumerator* enumerator = nullptr;
  sessionManager->GetSessionEnumerator(&enumerator);

  deviceEnumerator->Release();
  device->Release();
  sessionManager->Release();

  return enumerator;
}
예제 #9
0
	//-------------------------------------------------------------------
	//  Initializes the CAudioSessionEventHandler object.
	long CAudioSessionEventHandler::Initialize()
	{
		_WINQ_FCONTEXT( "CAudioSessionEventHandler::Initialize" );
		long hr = 0;

		IMMDeviceEnumerator* pDeviceEnumerator = 0;
		IMMDevice* pDevice = 0;
		IAudioSessionManager* pAudioSessionManager = 0;

		// Get the enumerator for the audio endpoint devices.
		hr = nsWinQAPI::COLE32::Instance().CoCreateInstance( reinterpret_cast< const ::IID& >( CLASS_MMDEVICEENUMERATOR ), 0, CLSCTX_INPROC_SERVER, reinterpret_cast< const ::IID& >( IMMDeviceEnumerator::_IID ), reinterpret_cast< void** >( &pDeviceEnumerator ) );

		if( hr < 0 ) { goto done; }

		// Get the default audio endpoint that the SAR will use.
		hr = pDeviceEnumerator->GetDefaultAudioEndpoint( eRender, eConsole,   // The SAR uses 'eConsole' by default.
			&pDevice
			);

		if( hr < 0 ) { goto done; }

		// Get the session manager for this device.
		hr = pDevice->Activate(  IAudioSessionManager::_IID,  CLSCTX_INPROC_SERVER, 0, (void**) &pAudioSessionManager );
		if( hr < 0 ) { goto done; }

		// Get the audio session. 
		hr = pAudioSessionManager->GetAudioSessionControl(reinterpret_cast< const nsWin32::GUID* >(&NULL_GUID),     // Get the default audio session. 
			0,          // The session is not cross-process.
			&m_pAudioSession 
			);

		if( hr < 0 ) { goto done; }

		hr = pAudioSessionManager->GetSimpleAudioVolume(reinterpret_cast< const nsWin32::GUID* >(&NULL_GUID), 0, &m_pSimpleAudioVolume);

done:

		pDeviceEnumerator->Release();
		pDevice->Release();
		pAudioSessionManager->Release();
		return hr;
	}
예제 #10
0
//
//  Utility function to retrieve the session manager for the default audio endpoint.
//
HRESULT CMediaPlayer::GetSessionManager2()
{
    HRESULT hr = S_OK;
    if (_SessionManager2 == NULL)
    {
        IMMDeviceEnumerator *deviceEnumerator;
        IMMDevice *endpoint = NULL;

        //
        //  Start with the default endpoint.
        //
        hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&deviceEnumerator));
        if (SUCCEEDED(hr))
        {
            hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &endpoint);

            deviceEnumerator->Release();
            deviceEnumerator = NULL;
        }
        else
        {
            MessageBox(_AppWindow, L"Unable to instantiate MMDeviceEnumerator", L"Get SessionManager Error", MB_OK);
        }

        if (SUCCEEDED(hr))
        {
            hr = endpoint->Activate(__uuidof(IAudioSessionManager2), CLSCTX_INPROC_SERVER,
                    NULL, reinterpret_cast<void **>(&_SessionManager2));
            endpoint->Release();
            if (FAILED(hr))
            {
                MessageBox(_AppWindow, L"Unable to Activate session manager", L"Get SessionManager Error", MB_OK);
            }
        }
        else
        {
            MessageBox(_AppWindow, L"Unable to get default endpoint", L"Get SessionManager Error", MB_OK);
        }
    }
    return hr;
}
예제 #11
0
/**
* Initialize the EndpointVolume (volume controller).
*/
void master_volume::loadVolumeController()
{
    m_endpointVolume = nullptr;

    HRESULT hr;
    IMMDeviceEnumerator *deviceEnumerator = nullptr;
    IMMDevice *defaultDevice = nullptr;

    // Get the list of audio devices
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
    if (hr != S_OK) {
        logger.Error("master_volume::loadVolumeController(), CoCreateInstance failed with error: " + hr);
        return;
    }

    // Get the default audio device
    hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
    if (hr != S_OK) {
        logger.Error("GetDefaultAudioEndpoint failed with error: " + hr);
        return;
    }

    // Free the device list
    if (deviceEnumerator) {
        deviceEnumerator->Release();
        deviceEnumerator = nullptr;
    }

    // Load EndpointVolume (volume controller)
    hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, (LPVOID *)&m_endpointVolume);
    if (hr != S_OK) {
        logger.Error("master_volume::loadVolumeController(), defaultDevice->Activate failed with error: " + hr);
        return;
    }

    // Release the default device
    if (defaultDevice) {
        defaultDevice->Release();
        defaultDevice = nullptr;
    }
}
예제 #12
0
void SetMuteStatus()
{
    HRESULT hr;

    CoInitialize(NULL);
    IMMDeviceEnumerator *deviceEnumerator = NULL;
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
    if (!SUCCEEDED(hr)) 
    {
        CoUninitialize();
    }

    IMMDevice *defaultDevice = NULL;

    hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
    deviceEnumerator->Release();
    deviceEnumerator = NULL;
    if (!SUCCEEDED(hr))
    {
        CoUninitialize();
    }

    IAudioEndpointVolume *endpointVolume = NULL;
    hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
    defaultDevice->Release();
    defaultDevice = NULL; 

    if (!SUCCEEDED(hr)) 
    {
        CoUninitialize();
    }

    // -------------------------
	BOOL b;

	endpointVolume->GetMute(&b);
	b=!b;
	endpointVolume->SetMute(b, NULL);
	endpointVolume->Release();
    CoUninitialize();
}
예제 #13
0
IMMDevice* GetDefaultAudioDevice()
{
    IMMDevice* mmDevice = nullptr;
    IMMDeviceEnumerator* mmDeviceEnumerator;

    // activate a device enumerator
    HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&mmDeviceEnumerator);
    if (FAILED(hr))
    {
        fprintf(stderr, "CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x\n", hr);
        return mmDevice;
    }

    // get the default render endpoint
    hr = mmDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &mmDevice);
    mmDeviceEnumerator->Release();
    if (FAILED(hr))
        fprintf(stderr, "IMMDeviceEnumerator::GetDefaultAudioEndpoint failed: hr = 0x%08x\n", hr);

    return mmDevice;
}
예제 #14
0
void InitializeAudioEndpoint(IAudioEndpointVolume **audioEndpoint) 
{
	HRESULT hr;

	// Initialize the COM library
	CoInitialize(nullptr);

	// Get audio device enumerator
	IMMDeviceEnumerator *deviceEnumerator = nullptr;
	hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
	if (hr != S_OK) {
		printf("Unable to create instance of MMDeviceEnumerator (error code: 0x%08lx)\n", hr);
		CoUninitialize();
		exit(-1);
	}

	// Ask device enumerator for the default audio renderer
	IMMDevice *defaultDevice = nullptr;
	hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
	deviceEnumerator->Release();
	deviceEnumerator = nullptr;
	if (hr != S_OK) {
		printf("Unable to get default audio endpoint (error code: 0x%08lx)\n", hr);
		CoUninitialize();
		exit(-1);
	}
	
	// Ask default audio renderer for volume controller
	//IAudioEndpointVolume *endpointVolume = nullptr;
	hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, (LPVOID *)audioEndpoint);
	defaultDevice->Release();
	defaultDevice = nullptr;
	if (hr != S_OK) {
		printf("Unable to get default audio volume controller (error code: 0x%08lx)\n", hr);
		CoUninitialize();
		exit(-1);
	}
}
예제 #15
0
	void do_unregister( XAudio2_Output * p_instance )
	{
		if ( InterlockedDecrement( &registered ) == 0 )
		{
			if (pEnumerator)
			{
				pEnumerator->UnregisterEndpointNotificationCallback( this );
				pEnumerator->Release();
				pEnumerator = NULL;
			}
		}

		EnterCriticalSection( &lock );
		for ( std::vector<XAudio2_Output*>::iterator it = instances.begin(); it < instances.end(); ++it )
		{
			if ( *it == p_instance )
			{
				instances.erase( it );
				break;
			}
		}
		LeaveCriticalSection( &lock );
	}
HRESULT get_default_device(IMMDevice **ppMMDevice) {
    HRESULT hr = S_OK;
    IMMDeviceEnumerator *pMMDeviceEnumerator;
    // activate a device enumerator
    hr = CoCreateInstance(
        __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, 
        __uuidof(IMMDeviceEnumerator),
        (void**)&pMMDeviceEnumerator
    );
    if (FAILED(hr)) {
        printf("CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x\n", hr);
        return hr;
    }

    // get the default render endpoint
    hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, ppMMDevice);
    pMMDeviceEnumerator->Release();
    if (FAILED(hr)) {
        printf("IMMDeviceEnumerator::GetDefaultAudioEndpoint failed: hr = 0x%08x\n", hr);
        return hr;
    }

    return S_OK;
}
void MFAudioEndpointControl::updateEndpoints()
{
    m_defaultEndpoint = QString::fromLatin1("Default");
    m_devices.insert(m_defaultEndpoint, NULL);

    IMMDeviceEnumerator *pEnum = NULL;
    HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
                          NULL, CLSCTX_ALL,
                          __uuidof(IMMDeviceEnumerator),
                         (void**)&pEnum);
    if (SUCCEEDED(hr)) {
        IMMDeviceCollection *pDevices = NULL;
        hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices);
        if (SUCCEEDED(hr)) {
            UINT count;
            hr = pDevices->GetCount(&count);
            if (SUCCEEDED(hr)) {
                for (UINT i = 0; i < count; ++i) {
                    IMMDevice *pDevice = NULL;
                    hr = pDevices->Item(i, &pDevice);
                    if (SUCCEEDED(hr)) {
                        LPWSTR wstrID = NULL;
                        hr = pDevice->GetId(&wstrID);
                        if (SUCCEEDED(hr)) {
                            QString deviceId = QString::fromWCharArray(wstrID);
                            m_devices.insert(deviceId, wstrID);
                        }
                        pDevice->Release();
                    }
                }
            }
            pDevices->Release();
        }
        pEnum->Release();
    }
}
HRESULT unregister_notification_callback(IMMNotificationClient *pClient) {
    HRESULT hr = S_OK;
    IMMDeviceEnumerator *pMMDeviceEnumerator;

    // activate a device enumerator
    hr = CoCreateInstance(
             __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,
             __uuidof(IMMDeviceEnumerator),
             (void**)&pMMDeviceEnumerator
         );
    if (FAILED(hr)) {
        printf("CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x\n", hr);
        return hr;
    }

    // get the default render endpoint
    hr = pMMDeviceEnumerator->UnregisterEndpointNotificationCallback(pClient);
    pMMDeviceEnumerator->Release();
    if (FAILED(hr)) {
        printf("IMMDeviceEnumerator::UnregisterEndpointNotificationCallback failed: hr = 0x%08x\n", hr);
        return hr;
    }
    return S_OK;
}
/**********************************************************************************

Function Name = LeapDesktopAppFull::volumeManipulation

Descriptive Name = Increase/decrease/mute/unmute the volume

Function =

    This functions is responsible for performing the actions of increasing/
    decreasing/muting/unmuting the volume. Makes use of the available functions on 
    windows to construct and initialize the interface of audio devices for communication.

Dependencies =

    None

Restrictions =

    Must have audio devices connected, running and capable of being accessed through the 
    IMMDeviceEnumerator interface.

Input =
    
    string controlOption - The volume action to be performed, supports the following options:
                                VOLUME_STEP_UP      - This option will increase the volume by 1
                                VOLUME_STEP_DOWN    - This option will decrease the volume by 1
                                VOLUME_MUTE_UNMUTE  - This option will mute or unmute based on 
                                                      what the state of the volume currently is.

Output =
   
   Currently there are no outputs from this functions as it only performs the action. 
   Future TODO is to make sure errors are handled and appropriate response is returned.

Normal Return =
    
    N/A

Error Return =

    N/A

******************************************************************************/
void LeapDesktopAppFull::volumeManipulation ( string controlOption )
{
    // Variable Declaration
    HRESULT              volumeManipulationResults = NULL ;  // Stores detailed information for the volume communication interface
    IMMDeviceEnumerator  *deviceEnumerator         = NULL ;  // Stores the interface pointer of enumerating audio devices
    IMMDevice            *defaultDevice            = NULL ;  // Stores all the default audio devices resources
    IAudioEndpointVolume *endpointVolume           = NULL ;  // Stores the volume controls on the audio streams 
    BOOL                 pbMute                    = FALSE ; //

    // Initialize the COM library on the current thread
    CoInitialize ( NULL ) ;

    // Create an instance of a single uninitialized object of audio devices, a success instance creation will return "S_OK"
    volumeManipulationResults = CoCreateInstance ( __uuidof( MMDeviceEnumerator ),    // The CLSID associated with the data and code that is used to create the object
                                                   NULL,                              // Set to NULL to identify that object is not being created as an aggregate
                                                   CLSCTX_INPROC_SERVER,              // Identifies how the new object will run, in this case it is a DLL that runs in the same process
                                                   __uuidof( IMMDeviceEnumerator ),   // The identifier of the interface that will be used to communicate with the object
                                                   ( LPVOID * ) &deviceEnumerator     // Pointer that will store the interface pointer that was requested
                                                 ) ;

    // Using the device enumerator interface get the default audio endpoint for the provided data-flow direction
    volumeManipulationResults = deviceEnumerator->GetDefaultAudioEndpoint ( eRender,          // Set to eRender to represent an audio rendering stream
                                                                            eConsole,         // Set to eConsole to represent the role that is assigned to the endpoint device
                                                                            &defaultDevice    // Pointer to which the device address is stored of the endpoint object
                                                                          ) ;

    // No longer need the pointer for the device enumerator interface so release it to free up memory
    deviceEnumerator->Release () ;
    deviceEnumerator = NULL ;  // Force un-initialization

    // Activate the device that was retrieved above, a success activation will return "S_OK"
    volumeManipulationResults = defaultDevice->Activate ( __uuidof( IAudioEndpointVolume ), // The interface identifier, in this case this is an audio endpoint device
                                                          CLSCTX_INPROC_SERVER,             // Identifies how the new object will run, in this case it is a DLL that runs in the same process
                                                          NULL,                             // Set to NULL to activate an IAudioEndpointVolume interface on an audio endpoint device
                                                          ( LPVOID * ) &endpointVolume      // Pointer which stores the address of the IAudioEndpointVolume interface
                                                        ) ;

    // No longer need the pointer for the device interface so release it to free up memory
    defaultDevice->Release () ;
    defaultDevice = NULL ; // Force un-initialization

    // From the endpointVolume interface get the mute status
    // GetMute returns TRUE for muted and FALSE for the stream not muted
    endpointVolume->GetMute ( &pbMute ) ;

    // Based on the mute status perform the action of muting or unmuting the stream
    if ( ( pbMute && controlOption == VOLUME_MUTE_UNMUTE ) )
    {
        // Found that the stream is already currently muted so un-mute the stream
        volumeManipulationResults = endpointVolume->SetMute ( 0, NULL ) ;

        // Display user feed back image based on the action performed
        createUserFeedBackWindow ( loadResource ( RES_KEYTAP_IMAGE ), 150, 131 ) ;
    }
    else if ( !pbMute && controlOption == VOLUME_MUTE_UNMUTE )
    {
        // Found that the stream is not mute so mute the stream
        volumeManipulationResults = endpointVolume->SetMute ( 1, NULL ) ;

        // Display user feed back image based on the action performed
        createUserFeedBackWindow ( loadResource ( RES_KEYTAPRELEASE_IMAGE ), 150, 131 ) ;
    }

    // Based on the volume increase/decrease option, perform the appropriate action
    if ( controlOption == VOLUME_STEP_UP )
    {
        // Increase the volume on the stream by one, this also will update any connected system notifications
        volumeManipulationResults = endpointVolume->VolumeStepUp ( NULL );
        volumeManipulationResults = endpointVolume->VolumeStepUp ( NULL );
        volumeManipulationResults = endpointVolume->VolumeStepUp ( NULL );
        volumeManipulationResults = endpointVolume->VolumeStepUp ( NULL );
    }
    else if ( controlOption == VOLUME_STEP_DOWN )
    {
        // Decrease the volume on the stream by one, this also will update any connected system notifications
        volumeManipulationResults = endpointVolume->VolumeStepDown ( NULL );
        volumeManipulationResults = endpointVolume->VolumeStepDown ( NULL );
        volumeManipulationResults = endpointVolume->VolumeStepDown ( NULL );
        volumeManipulationResults = endpointVolume->VolumeStepDown ( NULL );
    }

    // No longer need the endpointVolume interface so release it to free up memory
    endpointVolume->Release ();

    // All the actions that are to be performed on the end point device are done so un-initialize the instance
    CoUninitialize ();
}
예제 #20
0
void VolumeControl::init()
{
	//initialize audio mixer interface
#if defined (__APPLE__)
	#warning TODO: Not implemented for MacOS yet!!!
#elif defined(__linux__)
	//try to open mixer device
	if (mixerHandle == nullptr)
	{
		snd_mixer_selem_id_alloca(&mixerSelemId);
		//sets simple-mixer index and name
		snd_mixer_selem_id_set_index(mixerSelemId, mixerIndex);
		snd_mixer_selem_id_set_name(mixerSelemId, mixerName);
		//open mixer
		if (snd_mixer_open(&mixerHandle, 0) >= 0)
		{
			LOG(LogDebug) << "VolumeControl::init() - Opened ALSA mixer";
			//ok. attach to defualt card
			if (snd_mixer_attach(mixerHandle, mixerCard) >= 0)
			{
				LOG(LogDebug) << "VolumeControl::init() - Attached to default card";
				//ok. register simple element class
				if (snd_mixer_selem_register(mixerHandle, NULL, NULL) >= 0)
				{
					LOG(LogDebug) << "VolumeControl::init() - Registered simple element class";
					//ok. load registered elements
					if (snd_mixer_load(mixerHandle) >= 0)
					{
						LOG(LogDebug) << "VolumeControl::init() - Loaded mixer elements";
						//ok. find elements now
						mixerElem = snd_mixer_find_selem(mixerHandle, mixerSelemId);
						if (mixerElem != nullptr)
						{
							//wohoo. good to go...
							LOG(LogDebug) << "VolumeControl::init() - Mixer initialized";
						}
						else
						{
							LOG(LogError) << "VolumeControl::init() - Failed to find mixer elements!";
							snd_mixer_close(mixerHandle);
							mixerHandle = nullptr;
						}
					}
					else
					{
						LOG(LogError) << "VolumeControl::init() - Failed to load mixer elements!";
						snd_mixer_close(mixerHandle);
						mixerHandle = nullptr;
					}
				}
				else
				{
					LOG(LogError) << "VolumeControl::init() - Failed to register simple element class!";
					snd_mixer_close(mixerHandle);
					mixerHandle = nullptr;
				}
			}
			else
			{
				LOG(LogError) << "VolumeControl::init() - Failed to attach to default card!";
				snd_mixer_close(mixerHandle);
				mixerHandle = nullptr;
			}
		}
		else
		{
			LOG(LogError) << "VolumeControl::init() - Failed to open ALSA mixer!";
		}
	}
#elif defined(WIN32) || defined(_WIN32)
	//get windows version information
	OSVERSIONINFOEXA osVer = {sizeof(OSVERSIONINFO)};
	::GetVersionExA(reinterpret_cast<LPOSVERSIONINFOA>(&osVer));
	//check windows version
	if(osVer.dwMajorVersion < 6)
	{
		//Windows older than Vista. use mixer API. open default mixer
		if (mixerHandle == nullptr)
		{
			if (mixerOpen(&mixerHandle, 0, NULL, 0, 0) == MMSYSERR_NOERROR)
			{
				//retrieve info on the volume slider control for the "Speaker Out" line
				MIXERLINECONTROLS mixerLineControls;
				mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
				mixerLineControls.dwLineID = 0xFFFF0000; //Id of "Speaker Out" line
				mixerLineControls.cControls = 1;
				//mixerLineControls.dwControlID = 0x00000000; //Id of "Speaker Out" line's volume slider
				mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; //Get volume control
				mixerLineControls.pamxctrl = &mixerControl;
				mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
				if (mixerGetLineControls((HMIXEROBJ)mixerHandle, &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR)
				{
					LOG(LogError) << "VolumeControl::getVolume() - Failed to get mixer volume control!";
					mixerClose(mixerHandle);
					mixerHandle = nullptr;
				}
			}
			else
			{
				LOG(LogError) << "VolumeControl::init() - Failed to open mixer!";
			}
		}
	}
	else
	{
		//Windows Vista or above. use EndpointVolume API. get device enumerator
		if (endpointVolume == nullptr)
		{
			CoInitialize(nullptr);
			IMMDeviceEnumerator * deviceEnumerator = nullptr;
			CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
			if (deviceEnumerator != nullptr)
			{
				//get default endpoint
				IMMDevice * defaultDevice = nullptr;
				deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
				if (defaultDevice != nullptr)
				{
					//retrieve endpoint volume
					defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, (LPVOID *)&endpointVolume);
					if (endpointVolume == nullptr)
					{
						LOG(LogError) << "VolumeControl::init() - Failed to get default audio endpoint volume!";
					}
					//release default device. we don't need it anymore
					defaultDevice->Release();
				}
				else
				{
					LOG(LogError) << "VolumeControl::init() - Failed to get default audio endpoint!";
				}
				//release device enumerator. we don't need it anymore
				deviceEnumerator->Release();
			}
			else
			{
				LOG(LogError) << "VolumeControl::init() - Failed to get audio endpoint enumerator!";
				CoUninitialize();
			}
		}
	}
#endif
}
예제 #21
0
void modifyVolume(char ch)
{
	HRESULT hr;
	bool decibels = false;
	bool scalar = true;
	double newVolume = 10;
	// -------------------------
	CoInitialize(NULL);
	IMMDeviceEnumerator *deviceEnumerator = NULL;
	hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
	IMMDevice *defaultDevice = NULL;

	hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &defaultDevice);
	deviceEnumerator->Release();
	deviceEnumerator = NULL;

	IAudioEndpointVolume *endpointVolume = NULL;
	hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
	defaultDevice->Release();
	defaultDevice = NULL;

	// -------------------------
	float currentVolume = 0;
	endpointVolume->GetMasterVolumeLevel(&currentVolume);
	//printf("Current volume in dB is: %f\n", currentVolume);

	hr = endpointVolume->GetMasterVolumeLevelScalar(&currentVolume);

	float min, max, inc;
	endpointVolume->GetVolumeRange(&min, &max, &inc);
	//printf("Current volume as a scalar is: %f\n", currentVolume);

	if (ch == 'u')
		newVolume = currentVolume + 0.1;
	else if (ch == 'd')
		newVolume = currentVolume - 0.1;

	if (ch == 'm')
	{
		endpointVolume->SetMute(TRUE, NULL);
	}
	else if (ch == 'n')
	{
		endpointVolume->SetMute(FALSE, NULL);
	}
	else
	{
		if (decibels)
		{
			hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL);
			//endpointVolume->VolumeStepUp(NULL);
		}
		else if (scalar)
		{
			hr = endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL);
			//endpointVolume->VolumeStepUp(NULL);
		}
	}


	endpointVolume->Release();

	CoUninitialize();
}
예제 #22
0
void changeFGWindowVolume()
{
	if (soundOption == dncItemID) return;

	char titleBuff[128];
	HWND activeHWND = GetForegroundWindow();
	GetWindowText(activeHWND, titleBuff, 128);

	UINT count = sizeof(mediaCommands) / sizeof(mediaCommands[0]);
	for (UINT i = 0; i < count; i++)
	{
		if (strstr(titleBuff, mediaCommands[i].title) > 0) return;
	}

	IMMDevice *mmDevice;
	IMMDeviceEnumerator *mmDeviceEnum;
	IAudioSessionManager2 *sessionManager;
	IAudioSessionEnumerator *sessionEnum;
	IAudioSessionControl *sessionControl;
	IAudioSessionControl2 *sessionControl2;
	ISimpleAudioVolume *audioVolume;

	CoCreateInstance(__uuidof(MMDeviceEnumerator), 0, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&mmDeviceEnum);
	mmDeviceEnum->GetDefaultAudioEndpoint(eRender, eMultimedia, &mmDevice);
	mmDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, 0, (void**)&sessionManager);
	sessionManager->GetSessionEnumerator(&sessionEnum);

	DWORD activePid;
	GetWindowThreadProcessId(activeHWND, &activePid);

	int sessionCount;
	sessionEnum->GetCount(&sessionCount);
	for (int i = 0; i < sessionCount; i++)
	{
		sessionEnum->GetSession(i, &sessionControl);
		sessionControl->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&sessionControl2);

		DWORD pid;
		sessionControl2->GetProcessId(&pid);
		if (activePid == pid)
		{
			sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&audioVolume);

			BOOL muted;
			audioVolume->GetMute(&muted);

			float volumeLevel;
			audioVolume->GetMasterVolume(&volumeLevel);

			if (soundOption == muteItemID)
			{
				audioVolume->SetMute(!muted, 0);

				if (volumeLevel != 1.0f)
				{
					audioVolume->SetMasterVolume(1.0f, 0);
				}
			}
			else
			{
				float newVolumeLevel = (soundOption - sBaseItemID) / 100.0f;
				audioVolume->SetMasterVolume(volumeLevel == 1.0f ? newVolumeLevel : 1.0f, 0);

				if (muted)
				{
					audioVolume->SetMute(false, 0);
				}
			}

			audioVolume->Release();
		}

		sessionControl->Release();
		sessionControl2->Release();
	}

	sessionEnum->Release();
	sessionManager->Release();
	mmDevice->Release();
	mmDeviceEnum->Release();
}
예제 #23
0
/*
========================
idSoundHardware_XAudio2::Init
========================
*/
void idSoundHardware_XAudio2::Init()
{

	cmdSystem->AddCommand( "listDevices", listDevices_f, 0, "Lists the connected sound devices", NULL );
	
	DWORD xAudioCreateFlags = 0;
	
// RB: not available on Windows 8 SDK
#if !defined(USE_WINRT) && defined(_DEBUG) // (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) && defined(_DEBUG)
	xAudioCreateFlags |= XAUDIO2_DEBUG_ENGINE;
#endif
// RB end

	XAUDIO2_PROCESSOR xAudioProcessor = XAUDIO2_DEFAULT_PROCESSOR;
	
// RB: not available on Windows 8 SDK
	if( FAILED( XAudio2Create( &pXAudio2, xAudioCreateFlags, xAudioProcessor ) ) )
	{
#if !defined(USE_WINRT) && defined(_DEBUG) // (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) && defined(_DEBUG)
		if( xAudioCreateFlags & XAUDIO2_DEBUG_ENGINE )
		{
			// in case the debug engine isn't installed
			xAudioCreateFlags &= ~XAUDIO2_DEBUG_ENGINE;
			if( FAILED( XAudio2Create( &pXAudio2, xAudioCreateFlags, xAudioProcessor ) ) )
			{
				idLib::FatalError( "Failed to create XAudio2 engine.  Try installing the latest DirectX." );
				return;
			}
		}
		else
#endif
// RB end
		{
			idLib::FatalError( "Failed to create XAudio2 engine.  Try installing the latest DirectX." );
			return;
		}
	}
#ifdef _DEBUG
	XAUDIO2_DEBUG_CONFIGURATION debugConfiguration = { 0 };
	debugConfiguration.TraceMask = XAUDIO2_LOG_WARNINGS;
	debugConfiguration.BreakMask = XAUDIO2_LOG_ERRORS;
	pXAudio2->SetDebugConfiguration( &debugConfiguration );
#endif
	
	// Register the sound engine callback
	pXAudio2->RegisterForCallbacks( &soundEngineCallback );
	soundEngineCallback.hardware = this;
	UINT32 deviceCount = 0;
	DWORD outputSampleRate = 44100; // Max( (DWORD)XAUDIO2FX_REVERB_MIN_FRAMERATE, Min( (DWORD)XAUDIO2FX_REVERB_MAX_FRAMERATE, deviceDetails.OutputFormat.Format.nSamplesPerSec ) );
	
	// RB: not available on Windows 8 SDK
#if defined(USE_WINRT) //(_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
	
	IMMDeviceEnumerator*     immDevEnum       = nullptr;
	IMMDeviceCollection*     immDevCollection = nullptr;
	IMMDevice*               immDev           = nullptr;
	std::vector<AudioDevice> vAudioDevices;
	
	HRESULT hResult = CoCreateInstance(
						  __uuidof( MMDeviceEnumerator ), NULL,
						  CLSCTX_ALL, __uuidof( IMMDeviceEnumerator ), ( void** ) &immDevEnum );
						  
	if( FAILED( hResult ) )
	{
		idLib::Warning( "Failed to get audio enumerator" );
		pXAudio2->Release();
		pXAudio2 = NULL;
		return;
	}
	
	hResult = immDevEnum->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &immDevCollection );
	if( FAILED( hResult ) )
	{
		idLib::Warning( "Failed to get audio endpoints" );
		pXAudio2->Release();
		pXAudio2 = NULL;
		return;
	}
	
	hResult = immDevCollection->GetCount( &deviceCount );
	if( FAILED( hResult ) )
	{
		idLib::Warning( "No audio devices found" );
		pXAudio2->Release();
		pXAudio2 = NULL;
		return;
	}
	
	for( UINT i = 0; i < deviceCount; i++ )
	{
		IPropertyStore* propStore = nullptr;
		PROPVARIANT     varName;
		PROPVARIANT     varId;
		
		PropVariantInit( &varId );
		PropVariantInit( &varName );
		
		hResult = immDevCollection->Item( i, &immDev );
		if( SUCCEEDED( hResult ) )
		{
			hResult = immDev->OpenPropertyStore( STGM_READ, &propStore );
		}
		if( SUCCEEDED( hResult ) )
		{
			hResult = propStore->GetValue( PKEY_AudioEndpoint_Path, &varId );
		}
		
		if( SUCCEEDED( hResult ) )
		{
			hResult = propStore->GetValue( PKEY_Device_FriendlyName, &varName );
		}
		
		if( SUCCEEDED( hResult ) )
		{
			assert( varId.vt == VT_LPWSTR );
			assert( varName.vt == VT_LPWSTR );
			
			// Now save somewhere the device display name & id
			AudioDevice ad;
			ad.name = varName.pwszVal;
			ad.id   = varId.pwszVal;
			
			vAudioDevices.push_back( ad );
		}
		
		PropVariantClear( &varName );
		PropVariantClear( &varId );
		
		if( propStore != nullptr )
		{
			propStore->Release();
		}
		
		if( immDev != nullptr )
		{
			immDev->Release();
		}
	}
	
	
	immDevCollection->Release();
	immDevEnum->Release();
	
	int preferredDevice = s_device.GetInteger();
	if( !vAudioDevices.empty() )
	{
		if( SUCCEEDED( pXAudio2->CreateMasteringVoice( &pMasterVoice,
					   XAUDIO2_DEFAULT_CHANNELS,
					   outputSampleRate,
					   0,
					   vAudioDevices.at( 0 ).id.c_str(),
					   NULL,
					   AudioCategory_GameEffects ) ) )
		{
			XAUDIO2_VOICE_DETAILS deviceDetails;
			pMasterVoice->GetVoiceDetails( &deviceDetails );
			
			pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ) );
			
			outputChannels = deviceDetails.InputChannels;
			DWORD win8_channelMask;
			pMasterVoice->GetChannelMask( &win8_channelMask );
			
			channelMask = ( unsigned int )win8_channelMask;
			idLib::Printf( "Using device %s\n", vAudioDevices.at( 0 ).name );
		}
		else
		{
			idLib::Warning( "Failed to create master voice" );
			pXAudio2->Release();
			pXAudio2 = NULL;
			return;
		}
	}
	
#else
	if( pXAudio2->GetDeviceCount( &deviceCount ) != S_OK || deviceCount == 0 )
	{
		idLib::Warning( "No audio devices found" );
		pXAudio2->Release();
		pXAudio2 = NULL;
		return;
	}
	
	idCmdArgs args;
	listDevices_f( args );
	
	int preferredDevice = s_device.GetInteger();
	if( preferredDevice < 0 || preferredDevice >= ( int )deviceCount )
	{
		int preferredChannels = 0;
		for( unsigned int i = 0; i < deviceCount; i++ )
		{
			XAUDIO2_DEVICE_DETAILS deviceDetails;
			if( pXAudio2->GetDeviceDetails( i, &deviceDetails ) != S_OK )
			{
				continue;
			}
	
			if( deviceDetails.Role & DefaultGameDevice )
			{
				// if we find a device the user marked as their preferred 'game' device, then always use that
				preferredDevice = i;
				preferredChannels = deviceDetails.OutputFormat.Format.nChannels;
				break;
			}
	
			if( deviceDetails.OutputFormat.Format.nChannels > preferredChannels )
			{
				preferredDevice = i;
				preferredChannels = deviceDetails.OutputFormat.Format.nChannels;
			}
		}
	}
	
	idLib::Printf( "Using device %d\n", preferredDevice );
	
	XAUDIO2_DEVICE_DETAILS deviceDetails;
	if( pXAudio2->GetDeviceDetails( preferredDevice, &deviceDetails ) != S_OK )
	{
		// One way this could happen is if a device is removed between the loop and this line of code
		// Highly unlikely but possible
		idLib::Warning( "Failed to get device details" );
		pXAudio2->Release();
		pXAudio2 = NULL;
		return;
	}
	
	
	if( FAILED( pXAudio2->CreateMasteringVoice( &pMasterVoice, XAUDIO2_DEFAULT_CHANNELS, outputSampleRate, 0, preferredDevice, NULL ) ) )
	{
		idLib::Warning( "Failed to create master voice" );
		pXAudio2->Release();
		pXAudio2 = NULL;
		return;
	}
	pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ) );
	
	outputChannels = deviceDetails.OutputFormat.Format.nChannels;
	channelMask = deviceDetails.OutputFormat.dwChannelMask;
	
#endif // #if (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/)
	
	idSoundVoice::InitSurround( outputChannels, channelMask );
	
	// ---------------------
	// Create VU Meter Effect
	// ---------------------
	IUnknown* vuMeter = NULL;
	XAudio2CreateVolumeMeter( &vuMeter, 0 );
	
	XAUDIO2_EFFECT_DESCRIPTOR descriptor;
	descriptor.InitialState = true;
	descriptor.OutputChannels = outputChannels;
	descriptor.pEffect = vuMeter;
	
	XAUDIO2_EFFECT_CHAIN chain;
	chain.EffectCount = 1;
	chain.pEffectDescriptors = &descriptor;
	
	pMasterVoice->SetEffectChain( &chain );
	
	vuMeter->Release();
	
	// ---------------------
	// Create VU Meter Graph
	// ---------------------
	
	vuMeterRMS = console->CreateGraph( outputChannels );
	vuMeterPeak = console->CreateGraph( outputChannels );
	// DG: make sure they're not NULL (as it's currently the case with the cegui-based console)
	if( vuMeterRMS && vuMeterPeak )
	{
		vuMeterRMS->Enable( false );
		vuMeterPeak->Enable( false );
		
		memset( vuMeterPeakTimes, 0, sizeof( vuMeterPeakTimes ) );
		
		vuMeterPeak->SetFillMode( idDebugGraph::GRAPH_LINE );
		vuMeterPeak->SetBackgroundColor( idVec4( 0.0f, 0.0f, 0.0f, 0.0f ) );
		
		vuMeterRMS->AddGridLine( 0.500f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) );
		vuMeterRMS->AddGridLine( 0.250f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) );
		vuMeterRMS->AddGridLine( 0.125f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) );
		
		const char* channelNames[] = { "L", "R", "C", "S", "Lb", "Rb", "Lf", "Rf", "Cb", "Ls", "Rs" };
		for( int i = 0, ci = 0; ci < sizeof( channelNames ) / sizeof( channelNames[0] ); ci++ )
		{
			if( ( channelMask & BIT( ci ) ) == 0 )
			{
				continue;
			}
			vuMeterRMS->SetLabel( i, channelNames[ci] );
			i++;
		}
	}
	
	// ---------------------
	// Create submix buffer
	// ---------------------
	if( FAILED( pXAudio2->CreateSubmixVoice( &pSubmixVoice, 1, outputSampleRate, 0, 0, NULL, NULL ) ) )
	{
		idLib::FatalError( "Failed to create submix voice" );
	}
	
	// XAudio doesn't really impose a maximum number of voices
	voices.SetNum( voices.Max() );
	freeVoices.SetNum( voices.Max() );
	zombieVoices.SetNum( 0 );
	for( int i = 0; i < voices.Num(); i++ )
	{
		freeVoices[i] = &voices[i];
	}
// RB end
}
예제 #24
0
HRESULT get_specific_device(LPCWSTR szLongName, IMMDevice **ppMMDevice) {
    HRESULT hr = S_OK;

    *ppMMDevice = NULL;
    
    // get an enumerator
    IMMDeviceEnumerator *pMMDeviceEnumerator;

    hr = CoCreateInstance(
        __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, 
        __uuidof(IMMDeviceEnumerator),
        (void**)&pMMDeviceEnumerator
    );
    if (FAILED(hr)) {
        printf("CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x\n", hr);
        return hr;
    }

    IMMDeviceCollection *pMMDeviceCollection;

    // get all the active render endpoints
    hr = pMMDeviceEnumerator->EnumAudioEndpoints(
        eRender, DEVICE_STATE_ACTIVE, &pMMDeviceCollection
    );
    pMMDeviceEnumerator->Release();
    if (FAILED(hr)) {
        printf("IMMDeviceEnumerator::EnumAudioEndpoints failed: hr = 0x%08x\n", hr);
        return hr;
    }

    UINT count;
    hr = pMMDeviceCollection->GetCount(&count);
    if (FAILED(hr)) {
        pMMDeviceCollection->Release();
        printf("IMMDeviceCollection::GetCount failed: hr = 0x%08x\n", hr);
        return hr;
    }

    for (UINT i = 0; i < count; i++) {
        IMMDevice *pMMDevice;

        // get the "n"th device
        hr = pMMDeviceCollection->Item(i, &pMMDevice);
        if (FAILED(hr)) {
            pMMDeviceCollection->Release();
            printf("IMMDeviceCollection::Item failed: hr = 0x%08x\n", hr);
            return hr;
        }

        // open the property store on that device
        IPropertyStore *pPropertyStore;
        hr = pMMDevice->OpenPropertyStore(STGM_READ, &pPropertyStore);
        if (FAILED(hr)) {
            pMMDevice->Release();
            pMMDeviceCollection->Release();
            printf("IMMDevice::OpenPropertyStore failed: hr = 0x%08x\n", hr);
            return hr;
        }

        // get the long name property
        PROPVARIANT pv; PropVariantInit(&pv);
        hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &pv);
        pPropertyStore->Release();
        if (FAILED(hr)) {
            pMMDevice->Release();
            pMMDeviceCollection->Release();
            printf("IPropertyStore::GetValue failed: hr = 0x%08x\n", hr);
            return hr;
        }

        if (VT_LPWSTR != pv.vt) {
            printf("PKEY_Device_FriendlyName variant type is %u - expected VT_LPWSTR", pv.vt);

            PropVariantClear(&pv);
            pMMDevice->Release();
            pMMDeviceCollection->Release();
            return E_UNEXPECTED;
        }

        // is it a match?
        if (0 == _wcsicmp(pv.pwszVal, szLongName)) {
            // did we already find it?
            if (NULL == *ppMMDevice) {
                *ppMMDevice = pMMDevice;
                pMMDevice->AddRef();
            } else {
                printf("Found (at least) two devices named %ls\n", szLongName);
                PropVariantClear(&pv);
                pMMDevice->Release();
                pMMDeviceCollection->Release();
                return E_UNEXPECTED;
            }
        }
        
        pMMDevice->Release();
        PropVariantClear(&pv);
    }
    pMMDeviceCollection->Release();
    
    if (NULL == *ppMMDevice) {
        printf("Could not find a device named %ls\n", szLongName);
        return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
    }

    return S_OK;
}
예제 #25
0
HRESULT list_devices() {
    HRESULT hr = S_OK;

    // get an enumerator
    IMMDeviceEnumerator *pMMDeviceEnumerator;

    hr = CoCreateInstance(
        __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, 
        __uuidof(IMMDeviceEnumerator),
        (void**)&pMMDeviceEnumerator
    );
    if (FAILED(hr)) {
        printf("CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x\n", hr);
        return hr;
    }

    IMMDeviceCollection *pMMDeviceCollection;

    // get all the active render endpoints
    hr = pMMDeviceEnumerator->EnumAudioEndpoints(
        eRender, DEVICE_STATE_ACTIVE, &pMMDeviceCollection
    );
    pMMDeviceEnumerator->Release();
    if (FAILED(hr)) {
        printf("IMMDeviceEnumerator::EnumAudioEndpoints failed: hr = 0x%08x\n", hr);
        return hr;
    }

    UINT count;
    hr = pMMDeviceCollection->GetCount(&count);
    if (FAILED(hr)) {
        pMMDeviceCollection->Release();
        printf("IMMDeviceCollection::GetCount failed: hr = 0x%08x\n", hr);
        return hr;
    }
    printf("Active render endpoints found: %u\n", count);

    for (UINT i = 0; i < count; i++) {
        IMMDevice *pMMDevice;

        // get the "n"th device
        hr = pMMDeviceCollection->Item(i, &pMMDevice);
        if (FAILED(hr)) {
            pMMDeviceCollection->Release();
            printf("IMMDeviceCollection::Item failed: hr = 0x%08x\n", hr);
            return hr;
        }

        // open the property store on that device
        IPropertyStore *pPropertyStore;
        hr = pMMDevice->OpenPropertyStore(STGM_READ, &pPropertyStore);
        pMMDevice->Release();
        if (FAILED(hr)) {
            pMMDeviceCollection->Release();
            printf("IMMDevice::OpenPropertyStore failed: hr = 0x%08x\n", hr);
            return hr;
        }

        // get the long name property
        PROPVARIANT pv; PropVariantInit(&pv);
        hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &pv);
        pPropertyStore->Release();
        if (FAILED(hr)) {
            pMMDeviceCollection->Release();
            printf("IPropertyStore::GetValue failed: hr = 0x%08x\n", hr);
            return hr;
        }

        if (VT_LPWSTR != pv.vt) {
            printf("PKEY_Device_FriendlyName variant type is %u - expected VT_LPWSTR", pv.vt);

            PropVariantClear(&pv);
            pMMDeviceCollection->Release();
            return E_UNEXPECTED;
        }

        printf("    %ls\n", pv.pwszVal);
        
        PropVariantClear(&pv);
    }    
    pMMDeviceCollection->Release();
    
    return S_OK;
}
예제 #26
0
long WasapiEngine::doInit(long rate, int const latency) {
	{
		IMMDevice *pDevice = 0;
		IMMDeviceEnumerator *pEnumerator = 0;
		HRESULT hr;

		if (FAILED(CoCreateInstance(CLSID_MMDeviceEnumerator, 0, CLSCTX_ALL,
		                            IID_IMMDeviceEnumerator,
		                            reinterpret_cast<void **>(&pEnumerator)))) {
			std::cerr << "CoCreateInstance failed" << std::endl;
			return -1;
		}

		if (deviceSelector->count() > 1) {
			hr = pEnumerator->GetDevice(
				deviceSelector->itemData(deviceIndex).value<std::wstring>().c_str(),
				&pDevice);
		} else
			hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);

		pEnumerator->Release();
		if (FAILED(hr)) {
			std::cerr << "pEnumerator->GetDefaultAudioEndpoint failed" << std::endl;
			return -1;
		}

		hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, 0,
		                       reinterpret_cast<void **>(&pAudioClient));
		pDevice->Release();
		if (FAILED(hr)) {
			std::cerr << "pDevice->Activate failed" << std::endl;
			return -1;
		}
	}

	{
		static GUID const ksdataformat_subtype_pcm = {
			WAVE_FORMAT_PCM, 0x0000, 0x0010,
			{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
		};

		WAVEFORMATEXTENSIBLE wfext;
		std::memset(&wfext, 0, sizeof wfext);
		wfext.Format.cbSize = sizeof wfext - sizeof wfext.Format;
		wfext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
		wfext.Format.nChannels = 2;
		wfext.Format.nSamplesPerSec = rate;
		wfext.Format.wBitsPerSample = 16;
		wfext.Samples.wValidBitsPerSample = 16;
		wfext.SubFormat = ksdataformat_subtype_pcm;
		wfext.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;

		if (!exclusive_.value()) {
			WAVEFORMATEX *mwfe = 0;
			if (SUCCEEDED(pAudioClient->GetMixFormat(&mwfe)) && mwfe) {
				wfext.Format.nChannels = std::max<int>(mwfe->nChannels, 2);
				wfext.Format.nSamplesPerSec = mwfe->nSamplesPerSec;
				if (mwfe->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
					wfext.dwChannelMask =
						reinterpret_cast<WAVEFORMATEXTENSIBLE *>(mwfe)->dwChannelMask;
				}

				CoTaskMemFree(mwfe);
			} else
				std::cerr << "pAudioClient->GetMixFormat failed\r\n";

			if (!(eventHandle_ = CreateEventA(0, false, false, 0)))
				std::cerr << "CreateEvent failed\r\n";
		}

		wfext.Format.nBlockAlign = wfext.Format.nChannels * wfext.Format.wBitsPerSample >> 3;
		wfext.Format.nAvgBytesPerSec = wfext.Format.nSamplesPerSec * wfext.Format.nBlockAlign;
		nchannels_ = wfext.Format.nChannels;
		rate = wfext.Format.nSamplesPerSec;

		HRESULT hr = pAudioClient->Initialize(
			exclusive_.value() ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED,
			eventHandle_ ? AUDCLNT_STREAMFLAGS_EVENTCALLBACK : 0,
			latency * 10000,
			0,
			&wfext.Format,
			0);
		if (FAILED(hr)) {
			std::cerr << "pAudioClient->Initialize failed: " << hr << "\r\n";
			return -1;
		}
	}

	if (eventHandle_ && FAILED(pAudioClient->SetEventHandle(eventHandle_))) {
		std::cerr << "pAudioClient->SetEventHandle failed\r\n";
		return -1;
	}
	if (FAILED(pAudioClient->GetBufferSize(&bufferFrameCount))) {
		std::cerr << "pAudioClient->GetBufferSize failed" << std::endl;
		return -1;
	}
	if (FAILED(pAudioClient->GetService(IID_IAudioRenderClient,
	                                    reinterpret_cast<void **>(&pRenderClient)))) {
		std::cerr << "pAudioClient->GetService failed" << std::endl;
		return -1;
	}
	if (FAILED(pAudioClient->GetService(IID_IAudioClock,
	                                    reinterpret_cast<void **>(&pAudioClock)))) {
		std::cerr << "pAudioClient->GetService failed" << std::endl;
		return -1;
	}

	{
		UINT64 freq = 0;
		pAudioClock->GetFrequency(&freq);
		posFrames = freq / (rate ? rate : 1);
	}

	pos_ = 0;
	est = RateEst(rate, bufferFrameCount);

	return rate;
}
	static bool UpdateAudioDucking(bool bDuckingOptOutChecked)
	{
		HRESULT hr = S_OK;

		//  Start with the default endpoint.
		IMMDeviceEnumerator* pDeviceEnumerator = NULL;
		hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_PPV_ARGS(&pDeviceEnumerator));

		if (SUCCEEDED(hr))
		{
			{
				IMMDevice* pEndpoint = NULL;
				hr = pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pEndpoint);
				if (SUCCEEDED(hr))
				{
					LPWSTR Desc;
					pEndpoint->GetId(&Desc);
					UE_LOG(LogVoiceCapture, Display, TEXT("%s ducking on audio device. Desc: %s"), bDuckingOptOutChecked ? TEXT("Disabling") : TEXT("Enabling"), Desc);
					CoTaskMemFree(Desc);

					FAudioDuckingWindows::EnableDuckingOptOut(pEndpoint, bDuckingOptOutChecked);
					pEndpoint->Release();
					pEndpoint = NULL;
				}
			}

			if (0) // reference for enumerating all endpoints in case its necessary
			{
				IMMDeviceCollection* pDeviceCollection = NULL;
				IMMDevice* pCollEndpoint = NULL;
				hr = pDeviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDeviceCollection);
				if (SUCCEEDED(hr))
				{
					IPropertyStore *pProps = NULL;

					::UINT DeviceCount = 0;
					pDeviceCollection->GetCount(&DeviceCount);
					for (::UINT i = 0; i < DeviceCount; ++i)
					{
						hr = pDeviceCollection->Item(i, &pCollEndpoint);
						if (SUCCEEDED(hr) && pCollEndpoint)
						{
							LPWSTR Desc;
							pCollEndpoint->GetId(&Desc);

							hr = pCollEndpoint->OpenPropertyStore(STGM_READ, &pProps);
							if (SUCCEEDED(hr))
							{
								PROPVARIANT varName;
								// Initialize container for property value.
								PropVariantInit(&varName);

								// Get the endpoint's friendly-name property.
								hr = pProps->GetValue(
									PKEY_Device_FriendlyName, &varName);
								if (SUCCEEDED(hr))
								{
									// Print endpoint friendly name and endpoint ID.
									UE_LOG(LogVoiceCapture, Display, TEXT("%s ducking on audio device [%d]: \"%s\" (%s)"),
										bDuckingOptOutChecked ? TEXT("Disabling") : TEXT("Enabling"),
										i, varName.pwszVal, Desc);

									CoTaskMemFree(Desc);

									Desc = NULL;
									PropVariantClear(&varName);

									pProps->Release();
									pProps = NULL;
								}
							}

							FAudioDuckingWindows::EnableDuckingOptOut(pCollEndpoint, bDuckingOptOutChecked);

							pCollEndpoint->Release();
							pCollEndpoint = NULL;
						}
					}

					pDeviceCollection->Release();
					pDeviceCollection = NULL;
				}
			}

			pDeviceEnumerator->Release();
			pDeviceEnumerator = NULL;
		}

		if (FAILED(hr))
		{
			UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to duck audio endpoint. Error: %0x08x"), hr);
		}

		return SUCCEEDED(hr);
	}
예제 #28
0
//-------------------------------------------------------------------------------------------------
void FMain()
{
    if (const HWND hWnd = FindWindowW(g_wGuidClass, nullptr))
        PostMessageW(hWnd, WM_CLOSE, 0, 0);

    if (SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)))
    {
        IMMDeviceEnumerator *immDeviceEnumerator;
        if (CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), reinterpret_cast<LPVOID*>(&immDeviceEnumerator)) == S_OK)
        {
            IMMDevice *immDeviceDefault;
            if (immDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &immDeviceDefault) == S_OK)
            {
                wchar_t *wIdDefaultOld;
                HRESULT hr = immDeviceDefault->GetId(&wIdDefaultOld);
                immDeviceDefault->Release();
                if (hr == S_OK)
                {
                    IMMDeviceCollection *immDeviceCollection;
                    hr = immDeviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &immDeviceCollection);
                    immDeviceEnumerator->Release();
                    if (hr == S_OK)
                    {
                        UINT iCount;
                        if (immDeviceCollection->GetCount(&iCount) == S_OK)
                        {
                            bool bFail = true;
                            for (UINT i = 0; i < iCount; ++i)
                            {
                                IMMDevice *immDevice;
                                if (immDeviceCollection->Item(i, &immDevice) == S_OK)
                                {
                                    wchar_t *wIdEnum;
                                    hr = immDevice->GetId(&wIdEnum);
                                    immDevice->Release();
                                    if (hr == S_OK)
                                    {
                                        if (FCompareMemoryW(wIdDefaultOld, wIdEnum))
                                        {
                                            bFail = false;
                                            if (++i >= iCount)
                                                i = 0;
                                            hr = immDeviceCollection->Item(i, &immDevice);
                                            immDeviceCollection->Release();
                                            if (hr == S_OK)
                                            {
                                                wchar_t *wIdDefaultNew;
                                                if (immDevice->GetId(&wIdDefaultNew) == S_OK)
                                                {
                                                    IPropertyStore *ipStore;
                                                    hr = immDevice->OpenPropertyStore(STGM_READ, &ipStore);
                                                    immDevice->Release();
                                                    if (hr == S_OK)
                                                    {
                                                        PROPVARIANT propFriendlyName;
                                                        PropVariantInitFix(&propFriendlyName);
                                                        PROPERTYKEY propKeyFriendlyName;
                                                        propKeyFriendlyName.fmtid.Data1 = 0xA45C254E;
                                                        propKeyFriendlyName.fmtid.Data2 = 0xDF1C;
                                                        propKeyFriendlyName.fmtid.Data3 = 0x4EFD;
                                                        FCopyMemory(propKeyFriendlyName.fmtid.Data4);
                                                        propKeyFriendlyName.pid = 14;
                                                        hr = ipStore->GetValue(propKeyFriendlyName, &propFriendlyName);
                                                        ipStore->Release();
                                                        if (SUCCEEDED(hr))
                                                        {
                                                            IPolicyConfig *pPolicyConfig;
                                                            if (CoCreateInstance(__uuidof(CPolicyConfigClient), nullptr, CLSCTX_ALL, (GetVersion() & 0xFF) >= 10 ? __uuidof(IPolicyConfigWin10) : __uuidof(IPolicyConfig), reinterpret_cast<LPVOID*>(&pPolicyConfig)) == S_OK)
                                                            {
                                                                hr = pPolicyConfig->SetDefaultEndpoint(wIdDefaultNew, eConsole);
                                                                if (hr == S_OK)
                                                                {
                                                                    pPolicyConfig->SetDefaultEndpoint(wIdDefaultNew, eMultimedia);
                                                                    pPolicyConfig->SetDefaultEndpoint(wIdDefaultNew, eCommunications);
                                                                }
                                                                pPolicyConfig->Release();
                                                                if (hr == S_OK)
                                                                {
                                                                    WNDCLASSEX wndCl;
                                                                    wndCl.cbSize = sizeof(WNDCLASSEX);
                                                                    wndCl.style = 0;
                                                                    wndCl.lpfnWndProc = WindowProc;
                                                                    wndCl.cbClsExtra = 0;
                                                                    wndCl.cbWndExtra = 0;
                                                                    wndCl.hInstance = GetModuleHandleW(nullptr);
                                                                    wndCl.hIcon = nullptr;
                                                                    wndCl.hCursor = nullptr;
                                                                    wndCl.hbrBackground = nullptr;
                                                                    wndCl.lpszMenuName = nullptr;
                                                                    wndCl.lpszClassName = g_wGuidClass;
                                                                    wndCl.hIconSm = nullptr;

                                                                    if (RegisterClassExW(&wndCl))
                                                                    {
                                                                        if (CreateWindowExW(WS_EX_NOACTIVATE | WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST, g_wGuidClass, nullptr, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, nullptr, nullptr, wndCl.hInstance, propFriendlyName.pwszVal))
                                                                        {
                                                                            MSG msg;
                                                                            while (GetMessageW(&msg, nullptr, 0, 0) > 0)
                                                                                DispatchMessageW(&msg);
                                                                        }
                                                                        UnregisterClassW(g_wGuidClass, wndCl.hInstance);
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        PropVariantClear(&propFriendlyName);
                                                    }
                                                    CoTaskMemFree(wIdDefaultNew);
                                                }
                                                else
                                                    immDevice->Release();
                                            }
                                            break;
                                        }
                                        CoTaskMemFree(wIdEnum);
                                    }
                                }
                            }
                            if (bFail)
                                immDeviceCollection->Release();
                        }
                        else
                            immDeviceCollection->Release();
                    }
                    CoTaskMemFree(wIdDefaultOld);
                }
                else
                    immDeviceEnumerator->Release();
            }
            else
                immDeviceEnumerator->Release();
        }
        CoUninitialize();
    }
}
예제 #29
0
std::vector<AudioDevice> EnumerateAudioDevices(_Out_opt_ AudioDevice* defaultDevice = nullptr)
{
    UINT32                   deviceCount      = 0;
    IMMDeviceEnumerator     *immDevEnum       = nullptr;
    IMMDeviceCollection     *immDevCollection = nullptr;
    IMMDevice               *immDev           = nullptr;
    std::vector<AudioDevice> vAudioDevices;

    HRESULT hResult = CoCreateInstance(
    __uuidof(MMDeviceEnumerator), NULL,
    CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**) &immDevEnum);

    if (FAILED(hResult)) {
        idLib::Warning( "Failed to get audio enumerator" );
        return std::move(vAudioDevices);
    }

    if (defaultDevice != nullptr)
    {
        ZeroMemory(defaultDevice, sizeof(AudioDevice));

        IMMDevice *defaultImmDev = nullptr;

        // @pjb: get the default audio endpoint and make it the first one in the list
        if (SUCCEEDED(immDevEnum->GetDefaultAudioEndpoint(eRender, eConsole, &defaultImmDev)))
        {
            GetAudioDeviceDetails(defaultImmDev, defaultDevice);
            defaultImmDev->Release();
        }
    }

    hResult = immDevEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &immDevCollection);
    if (FAILED(hResult)) {
        idLib::Warning( "Failed to get audio endpoints" );
        return std::move(vAudioDevices);
    }

    hResult = immDevCollection->GetCount(&deviceCount);
    if (FAILED(hResult)) {
        idLib::Warning( "No audio devices found" );
        return std::move(vAudioDevices);
    }

    for (UINT i = 0; i < deviceCount; i++) {
        AudioDevice ad;

        hResult = immDevCollection->Item(i, &immDev);
        if (SUCCEEDED(hResult)) {
            hResult = GetAudioDeviceDetails(immDev, &ad);
        }

        if (SUCCEEDED(hResult)) {
            vAudioDevices.push_back(ad);
        }

        if (immDev != nullptr) {
            immDev->Release();
        }
    }

    immDevCollection->Release();
    immDevEnum->Release();

    return std::move(vAudioDevices);
}
예제 #30
0
RVolumeControl::RVolumeControl(QWidget *parent)
	: QWidget(parent), _value(0), _min(0), _max(100), _isEnableSound(true), _isOn(true), _isDark(true), _isWinXP(false)
{
	endpointVolume = NULL;
	volumeNotification = NULL;

	// ХАК ОТ ВАЛЕНТИНА
	setProperty("ignoreFilter", true);
	setToolTip(tr("Volume control"));

	BOOL mute = false;
	float currVolume = 0.;

	// Определяем версию ОС (xp или старше?)
	OSVERSIONINFO m_osinfo;
	ZeroMemory(&m_osinfo, sizeof(m_osinfo));
	m_osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

	if (GetVersionEx((LPOSVERSIONINFO) &m_osinfo))
	{
		if(m_osinfo.dwMajorVersion < 6)
		{
			_isWinXP = true;
		}
	}

	if(!_isWinXP)
	{
		CoInitialize(NULL);

		HRESULT hr;

		IMMDeviceEnumerator *deviceEnumerator = NULL;
		hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);

		if(hr == S_OK)
		{
			IMMDevice *defaultDevice = NULL;

			hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
			if(hr == S_OK)
			{
				deviceEnumerator->Release();
				deviceEnumerator = NULL;

				//endpointVolume = NULL;
				hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
				if(hr == S_OK)
				{
					defaultDevice->Release();
					defaultDevice = NULL;

					volumeNotification = new CVolumeNotification();
					//connect(volumeNotification, SIGNAL(volumeChanged(double)), this, SLOT(onVolumeChange(double)));
					connect(volumeNotification, SIGNAL(volumeChanged(int)), this, SLOT(onVolumeChange(int)));
					connect(volumeNotification, SIGNAL(volumeMuted(bool)), this, SLOT(onVolumeMuted(bool)));
					hr = endpointVolume->RegisterControlChangeNotify(volumeNotification);

					endpointVolume->GetMute(&mute);
					endpointVolume->GetMasterVolumeLevelScalar(&currVolume);
				}