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; }
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(¤tVolume); //printf("Current volume in dB is: %f\n", currentVolume); hr = endpointVolume->GetMasterVolumeLevelScalar(¤tVolume); //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; }
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; }
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; }
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); }
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; }
// // 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; }
//------------------------------------------------------------------- // 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; }
// // 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; }
/** * 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; } }
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(); }
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; }
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); } }
void do_unregister( XAudio2_Output * p_instance ) { if ( InterlockedDecrement( ®istered ) == 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 (); }
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 }
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(¤tVolume); //printf("Current volume in dB is: %f\n", currentVolume); hr = endpointVolume->GetMasterVolumeLevelScalar(¤tVolume); 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(); }
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(); }
/* ======================== 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 }
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; }
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; }
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); }
//------------------------------------------------------------------------------------------------- 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(); } }
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); }
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); }