From e654b6387929d0b2cef5f8b2d1c9fa14b23f9cba Mon Sep 17 00:00:00 2001 From: solenberg Date: Sat, 18 Feb 2017 04:05:35 -0800 Subject: [PATCH] Remove audio_mixer_manager_win.cc/.h. Not used after Wave support dropped in https://codereview.webrtc.org/2700983002/. BUG=webrtc:7183 Review-Url: https://codereview.webrtc.org/2699333002 Cr-Commit-Position: refs/heads/master@{#16690} --- webrtc/modules/audio_device/BUILD.gn | 2 - .../win/audio_mixer_manager_win.cc | 2725 ----------------- .../win/audio_mixer_manager_win.h | 139 - 3 files changed, 2866 deletions(-) delete mode 100644 webrtc/modules/audio_device/win/audio_mixer_manager_win.cc delete mode 100644 webrtc/modules/audio_device/win/audio_mixer_manager_win.h diff --git a/webrtc/modules/audio_device/BUILD.gn b/webrtc/modules/audio_device/BUILD.gn index 216ae0fb52..ddf74c6e9a 100644 --- a/webrtc/modules/audio_device/BUILD.gn +++ b/webrtc/modules/audio_device/BUILD.gn @@ -211,8 +211,6 @@ rtc_static_library("audio_device") { sources += [ "win/audio_device_core_win.cc", "win/audio_device_core_win.h", - "win/audio_mixer_manager_win.cc", - "win/audio_mixer_manager_win.h", ] libs = [ # Required for the built-in WASAPI AEC. diff --git a/webrtc/modules/audio_device/win/audio_mixer_manager_win.cc b/webrtc/modules/audio_device/win/audio_mixer_manager_win.cc deleted file mode 100644 index ae2d00faeb..0000000000 --- a/webrtc/modules/audio_device/win/audio_mixer_manager_win.cc +++ /dev/null @@ -1,2725 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_device/win/audio_mixer_manager_win.h" -#include "webrtc/system_wrappers/include/trace.h" - -#include // assert() -#include // StringCchCopy(), StringCchCat(), StringCchPrintf() - -#ifdef _WIN32 -// removes warning: "reinterpret_cast: conversion from 'UINT' to 'HMIXEROBJ' -// of greater size" -#pragma warning(disable:4312) -#endif - -// Avoids the need of Windows 7 SDK -#ifndef WAVE_MAPPED_kDefaultCommunicationDevice -#define WAVE_MAPPED_kDefaultCommunicationDevice 0x0010 -#endif - -namespace webrtc { - -// ============================================================================ -// CONSTRUCTION/DESTRUCTION -// ============================================================================ - -AudioMixerManager::AudioMixerManager(const int32_t id) : - _critSect(*CriticalSectionWrapper::CreateCriticalSection()), - _id(id), - _inputMixerHandle(NULL), - _outputMixerHandle(NULL) -{ - WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s constructed", __FUNCTION__); - ClearSpeakerState(); - ClearMicrophoneState(); -} - -AudioMixerManager::~AudioMixerManager() -{ - WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destructed", __FUNCTION__); - - Close(); - - delete &_critSect; -} - -// ============================================================================ -// PUBLIC METHODS -// ============================================================================ - -// ---------------------------------------------------------------------------- -// Close -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::Close() -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - CriticalSectionScoped lock(&_critSect); - - if (_outputMixerHandle != NULL) - { - mixerClose(_outputMixerHandle); - _outputMixerHandle = NULL; - } - if (_inputMixerHandle != NULL) - { - mixerClose(_inputMixerHandle); - _inputMixerHandle = NULL; - } - return 0; - -} - -// ---------------------------------------------------------------------------- -// CloseSpeaker -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::CloseSpeaker() -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - CriticalSectionScoped lock(&_critSect); - - if (_outputMixerHandle == NULL) - { - return -1; - } - - ClearSpeakerState(_outputMixerID); - - mixerClose(_outputMixerHandle); - _outputMixerHandle = NULL; - - return 0; -} - -// ---------------------------------------------------------------------------- -// CloseMicrophone -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::CloseMicrophone() -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - CriticalSectionScoped lock(&_critSect); - - if (_inputMixerHandle == NULL) - { - return -1; - } - - ClearMicrophoneState(_inputMixerID); - - mixerClose(_inputMixerHandle); - _inputMixerHandle = NULL; - - return 0; -} - -// ---------------------------------------------------------------------------- -// EnumerateAll -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::EnumerateAll() -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - UINT nDevices = mixerGetNumDevs(); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "#mixer devices: %u", nDevices); - - MIXERCAPS caps; - MIXERLINE destLine; - MIXERLINE sourceLine; - MIXERCONTROL controlArray[MAX_NUMBER_OF_LINE_CONTROLS]; - - UINT mixId(0); - UINT destId(0); - UINT sourceId(0); - - for (mixId = 0; mixId < nDevices; mixId++) - { - if (!GetCapabilities(mixId, caps, true)) - continue; - - for (destId = 0; destId < caps.cDestinations; destId++) - { - GetDestinationLineInfo(mixId, destId, destLine, true); - GetAllLineControls(mixId, destLine, controlArray, true); - - for (sourceId = 0; sourceId < destLine.cConnections; sourceId++) - { - GetSourceLineInfo(mixId, destId, sourceId, sourceLine, true); - GetAllLineControls(mixId, sourceLine, controlArray, true); - } - } - } - - return 0; -} - -// ---------------------------------------------------------------------------- -// EnumerateSpeakers -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::EnumerateSpeakers() -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - UINT nDevices = mixerGetNumDevs(); - if (nDevices > MAX_NUMBER_MIXER_DEVICES) - { - assert(false); - return -1; - } - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "#mixer devices: %u", nDevices); - - MIXERCAPS caps; - MIXERLINE destLine; - MIXERCONTROL controlArray[MAX_NUMBER_OF_LINE_CONTROLS]; - - UINT mixId(0); - UINT destId(0); - - ClearSpeakerState(); - - // scan all avaliable mixer devices - for (mixId = 0; mixId < nDevices; mixId++) - { - // get capabilities for the specified mixer ID - if (!GetCapabilities(mixId, caps)) - continue; - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "[mixerID=%d] %s: ", mixId, WideToUTF8(caps.szPname)); - // scan all avaliable destinations for this mixer - for (destId = 0; destId < caps.cDestinations; destId++) - { - GetDestinationLineInfo(mixId, destId, destLine); - if ((destLine.cControls == 0) || // no controls or - (destLine.cConnections == 0) || // no source lines or - (destLine.fdwLine & MIXERLINE_LINEF_DISCONNECTED) || // disconnected or - !(destLine.fdwLine & MIXERLINE_LINEF_ACTIVE)) // inactive - { - // don't store this line ID since it will not be possible to control - continue; - } - if ((destLine.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS) || - (destLine.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_HEADPHONES)) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found valid speaker/headphone (name: %s, ID: %u)", WideToUTF8(destLine.szName), destLine.dwLineID); - _speakerState[mixId].dwLineID = destLine.dwLineID; - _speakerState[mixId].speakerIsValid = true; - // retrieve all controls for the speaker component - GetAllLineControls(mixId, destLine, controlArray); - for (UINT c = 0; c < destLine.cControls; c++) - { - if (controlArray[c].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) - { - _speakerState[mixId].dwVolumeControlID = controlArray[c].dwControlID; - _speakerState[mixId].volumeControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found volume control (name: %s, ID: %u)", WideToUTF8(controlArray[c].szName), controlArray[c].dwControlID); - } - else if (controlArray[c].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) - { - _speakerState[mixId].dwMuteControlID = controlArray[c].dwControlID; - _speakerState[mixId].muteControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found mute control (name: %s, ID: %u)", WideToUTF8(controlArray[c].szName), controlArray[c].dwControlID); - } - } - break; - } - } - if (!SpeakerIsValid(mixId)) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "unable to find a valid speaker destination line", mixId); - } - } - - if (ValidSpeakers() == 0) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "failed to locate any valid speaker line"); - return -1; - } - - return 0; -} - -// ---------------------------------------------------------------------------- -// EnumerateMicrophones -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::EnumerateMicrophones() -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - UINT nDevices = mixerGetNumDevs(); - if (nDevices > MAX_NUMBER_MIXER_DEVICES) - { - assert(false); - return -1; - } - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "#mixer devices: %u", nDevices); - - MIXERCAPS caps; - MIXERLINE destLine; - MIXERLINE sourceLine; - MIXERCONTROL controlArray[MAX_NUMBER_OF_LINE_CONTROLS]; - - UINT mixId(0); - UINT destId(0); - - ClearMicrophoneState(); - - // scan all avaliable mixer devices - for (mixId = 0; mixId < nDevices; mixId++) - { - // get capabilities for the specified mixer ID - if (!GetCapabilities(mixId, caps)) - continue; - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "[mixerID=%d] %s: ", mixId, WideToUTF8(caps.szPname)); - // scan all avaliable destinations for this mixer - for (destId = 0; destId < caps.cDestinations; destId++) - { - GetDestinationLineInfo(mixId, destId, destLine); - - if ((destLine.cConnections == 0) || // no source lines or - (destLine.fdwLine & MIXERLINE_LINEF_DISCONNECTED) || // disconnected or - !(destLine.fdwLine & MIXERLINE_LINEF_ACTIVE)) // inactive - { - // Don't store this line ID since there are no sources connected to this destination. - // Compare with the speaker side where we also exclude lines with no controls. - continue; - } - - if (destLine.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_WAVEIN) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found valid Wave In destination (name: %s, ID: %u)", WideToUTF8(destLine.szName), destLine.dwLineID); - _microphoneState[mixId].dwLineID = destLine.dwLineID; - _microphoneState[mixId].microphoneIsValid = true; - - // retrieve all controls for the identified wave-in destination - if (!GetAllLineControls(mixId, destLine, controlArray)) - { - // This destination has no controls. We must try to control - // one of its sources instead. - // This is a rare state but has been found for some - // Logitech USB headsets. - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "this destination has no controls => must control source"); - for (DWORD sourceId = 0; sourceId < destLine.cConnections; sourceId++) - { - GetSourceLineInfo(mixId, destId, sourceId, sourceLine, false); - if (sourceLine.dwComponentType == - MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "found microphone source ( name: %s, ID: %u)", - WideToUTF8(sourceLine.szName), sourceId); - GetAllLineControls(mixId, sourceLine, controlArray, false); - // scan the controls for this source and search for volume, - // mute and on/off (<=> boost) controls - for (UINT sc = 0; sc < sourceLine.cControls; sc++) - { - if (controlArray[sc].dwControlType == - MIXERCONTROL_CONTROLTYPE_VOLUME) - { - // store this volume control - _microphoneState[mixId].dwVolumeControlID = - controlArray[sc].dwControlID; - _microphoneState[mixId].volumeControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "found volume control (name: %s, ID: %u)", - WideToUTF8(controlArray[sc].szName), - controlArray[sc].dwControlID); - } - else if (controlArray[sc].dwControlType == - MIXERCONTROL_CONTROLTYPE_MUTE) - { - // store this mute control - _microphoneState[mixId].dwMuteControlID = - controlArray[sc].dwControlID; - _microphoneState[mixId].muteControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "found mute control (name: %s, ID: %u)", - WideToUTF8(controlArray[sc].szName), - controlArray[sc].dwControlID); - } - else if (controlArray[sc].dwControlType == - MIXERCONTROL_CONTROLTYPE_ONOFF || - controlArray[sc].dwControlType == - MIXERCONTROL_CONTROLTYPE_LOUDNESS) - { - // store this on/off control (most likely a Boost control) - _microphoneState[mixId].dwOnOffControlID = - controlArray[sc].dwControlID; - _microphoneState[mixId].onOffControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "found on/off control (name: %s, ID: %u)", - WideToUTF8(controlArray[sc].szName), - controlArray[sc].dwControlID); - } - } - } - } - - break; - } - - // It seems like there are three different configurations we can find in this state: - // - // (1) The Wave-in destination contains one MUX control only - // (2) The Wave-in destination contains one or more controls where one is a volume control - // (3) On Vista and Win 7, it seems like case 2 above is extended. - // It is common that a Wave-in destination has two master controls (volume and mute), - // AND a microphone source as well with its own volume and mute controls with unique - // identifiers. Initial tests have shown that it is sufficient to modify the master - // controls only. The source controls will "follow" the master settings, hence the - // source controls seem to be redundant. - // - // For case 1, we should locate the selected source and its controls. The MUX setting will - // give us the selected source. NOTE - the selecion might not be a microphone. - // - // For case 2, the volume control works as a master level control and we should use that one. - // - // For case 3, we use the master controls only and assume that the source control will "follow". - // - // Examples of case 1: - SigmaTel Audio (built-in) - // - add more.. - // - // Examples of case 2: - Plantronics USB Headset - // - Eutectics IPP 200 USB phone - // - add more... - // - // Examples of case 3: - Realtek High Definition on Vista (TL) - // - add more... - - if ((destLine.cControls == 1) && - (controlArray[0].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)) - { - // Case 1: MUX control detected => locate the selected source and its volume control - // Note that, the selecion might not be a microphone. A warning is given for - // this case only, i.e., it is OK to control a selected Line In source as long - // as it is connected to the wave-in destination. - - UINT selection(0); - const DWORD nItemsInMux(controlArray[0].cMultipleItems); - - // decide which source line that is selected in the mux - if (GetSelectedMuxSource(mixId, controlArray[0].dwControlID, nItemsInMux, selection)) - { - // selection now contains the index of the selected source => - // read the line information for this source - // if conditions listed below - // condition 1: invalid source - // condition 2: no controls - // condition 3: disconnected - // condition 4: inactive - if (!GetSourceLineInfo(mixId, destId, selection, sourceLine) || - (sourceLine.cControls == 0) || - (sourceLine.fdwLine & MIXERLINE_LINEF_DISCONNECTED) || - !(sourceLine.fdwLine & MIXERLINE_LINEF_ACTIVE)) - { - continue; - } - - if (sourceLine.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) - { - // add more details about the selected source (not a microphone) - TraceComponentType(sourceLine.dwComponentType); - // send a warning just to inform about the fact that a non-microphone source will be controlled - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "the selected (to be controlled) source is not a microphone type"); - } - - // retrieve all controls for the selected source - GetAllLineControls(mixId, sourceLine, controlArray); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "MUX selection is %u [0,%u]", selection, nItemsInMux-1); - - // scan the controls for this source and search for volume, mute and on/off (<=> boost) controls - for (UINT sc = 0; sc < sourceLine.cControls; sc++) - { - if (controlArray[sc].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) - { - // store this volume control - _microphoneState[mixId].dwVolumeControlID = controlArray[sc].dwControlID; - _microphoneState[mixId].volumeControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found volume control (name: %s, ID: %u)", WideToUTF8(controlArray[sc].szName), controlArray[sc].dwControlID); - } - else if (controlArray[sc].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) - { - // store this mute control - _microphoneState[mixId].dwMuteControlID = controlArray[sc].dwControlID; - _microphoneState[mixId].muteControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found mute control (name: %s, ID: %u)", WideToUTF8(controlArray[sc].szName), controlArray[sc].dwControlID); - } - else if (controlArray[sc].dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF || - controlArray[sc].dwControlType == MIXERCONTROL_CONTROLTYPE_LOUDNESS) - { - // store this on/off control (most likely a Boost control) - _microphoneState[mixId].dwOnOffControlID = controlArray[sc].dwControlID; - _microphoneState[mixId].onOffControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found on/off control (name: %s, ID: %u)", WideToUTF8(controlArray[sc].szName), controlArray[sc].dwControlID); - } - } - } - else - { - WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, "failed to detect which source to control"); - } - - } - else if (destLine.cConnections == 1) - { - // Case 2 or Case 3: - - GetSourceLineInfo(mixId, destId, 0, sourceLine); - if ((sourceLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) && - (sourceLine.cControls > 0)) - { - // Case 3: same as Case 2 below but we have also detected a Microphone source - // with its own controls. So far, I have not been able to find any device - // where it is required to modify these controls. Until I have found such - // a device, this case will be handled as a Case 2 (see below). - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "microphone source controls will not be controlled"); - } - else if ((sourceLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) && - (sourceLine.cControls == 0)) - { - // default state on non Vista/Win 7 machines - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "microphone source has no controls => use master controls instead"); - } - else - { - // add more details about the selected source (not a microphone) - TraceComponentType(sourceLine.dwComponentType); - // send a warning just to inform about the fact that a non-microphone source will be controlled - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "the connected (to be controlled) source is not a microphone type"); - } - - // Case 2 : one source only and no MUX control detected => - // locate the master volume control (and mute + boost controls if possible) - - // scan the controls for this wave-in destination and search for volume, mute and on/off (<=> boost) controls - for (UINT dc = 0; dc < destLine.cControls; dc++) - { - if (controlArray[dc].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) - { - // store this volume control - _microphoneState[mixId].dwVolumeControlID = controlArray[dc].dwControlID; - _microphoneState[mixId].volumeControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found volume control (name: %s, ID: %u)", WideToUTF8(controlArray[dc].szName), controlArray[dc].dwControlID); - } - else if (controlArray[dc].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) - { - // store this mute control - _microphoneState[mixId].dwMuteControlID = controlArray[dc].dwControlID; - _microphoneState[mixId].muteControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found mute control (name: %s, ID: %u)", WideToUTF8(controlArray[dc].szName), controlArray[dc].dwControlID); - } - else if (controlArray[dc].dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF || - controlArray[dc].dwControlType == MIXERCONTROL_CONTROLTYPE_LOUDNESS || - controlArray[dc].dwControlType == MIXERCONTROL_CONTROLTYPE_BOOLEAN) - { - // store this on/off control - _microphoneState[mixId].dwOnOffControlID = controlArray[dc].dwControlID; - _microphoneState[mixId].onOffControlIsValid = true; - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "found on/off control (name: %s, ID: %u)", WideToUTF8(controlArray[dc].szName), controlArray[dc].dwControlID); - } - } - } - else - { - // We are in a state where more than one source is connected to the wave-in destination. - // I am bailing out here for now until I understand this case better. - WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, "failed to locate valid microphone controls for this mixer"); - } - break; - } - } // for (destId = 0; destId < caps.cDestinations; destId++) - - if (!MicrophoneIsValid(mixId)) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "unable to find a valid microphone destination line", mixId); - } - } // for (mixId = 0; mixId < nDevices; mixId++) - - if (ValidMicrophones() == 0) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "failed to locate any valid microphone line"); - return -1; - } - - return 0; -} - -// ---------------------------------------------------------------------------- -// OpenSpeaker I(II) -// -// Verifies that the mixer contains a valid speaker destination line. -// Avoids opening the mixer if valid control has not been found. -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::OpenSpeaker(AudioDeviceModule::WindowsDeviceType device) -{ - if (device == AudioDeviceModule::kDefaultDevice) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::OpenSpeaker(kDefaultDevice)"); - } - else if (device == AudioDeviceModule::kDefaultCommunicationDevice) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::OpenSpeaker(kDefaultCommunicationDevice)"); - } - - CriticalSectionScoped lock(&_critSect); - - // Close any existing output mixer handle - // - if (_outputMixerHandle != NULL) - { - mixerClose(_outputMixerHandle); - _outputMixerHandle = NULL; - } - - MMRESULT res = MMSYSERR_NOERROR; - WAVEFORMATEX waveFormat; - HWAVEOUT hWaveOut(NULL); - - waveFormat.wFormatTag = WAVE_FORMAT_PCM ; - waveFormat.nChannels = 2; - waveFormat.nSamplesPerSec = 48000; - waveFormat.wBitsPerSample = 16; - waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; - waveFormat.cbSize = 0; - - // We need a waveform-audio output handle for the currently selected output device. - // This handle will then give us the corresponding mixer identifier. Once the mixer - // ID is known, it is possible to open the output mixer. - // - if (device == AudioDeviceModule::kDefaultCommunicationDevice) - { - // check if it is possible to open the default communication device (supported on Windows 7) - res = waveOutOpen(NULL, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL | - WAVE_MAPPED_kDefaultCommunicationDevice | WAVE_FORMAT_QUERY); - if (MMSYSERR_NOERROR == res) - { - // if so, open the default communication device for real - res = waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL | WAVE_MAPPED_kDefaultCommunicationDevice); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "opening default communication device"); - } - else - { - // use default device since default communication device was not avaliable - res = waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "unable to open default communication device => using default instead"); - } - } - else if (device == AudioDeviceModule::kDefaultDevice) - { - // open default device since it has been requested - res = waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "opening default output device"); - } - - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "waveOutOpen() failed (err=%d)", res); - TraceWaveOutError(res); - } - - UINT mixerId(0); - HMIXER hMixer(NULL); - - // Retrieve the device identifier for a mixer device associated with the - // aquired waveform-audio output handle. - // - res = mixerGetID((HMIXEROBJ)hWaveOut, &mixerId, MIXER_OBJECTF_HWAVEOUT); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetID(MIXER_OBJECTF_HWAVEOUT) failed (err=%d)", res); - // identification failed => use default mixer identifier (=0) - mixerId = 0; - } - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "specified output device <=> mixer ID %u", mixerId); - - // The waveform-audio output handle is no longer needed. - // - waveOutClose(hWaveOut); - - // Verify that the mixer contains a valid speaker destination line. - // Avoid opening the mixer if valid control has not been found. - // - if (!SpeakerIsValid(mixerId)) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "it is not possible to control the speaker volume for this mixer device"); - return -1; - } - - // Open the specified mixer device and ensure that the device will not - // be removed until the application closes the handle. - // - res = mixerOpen(&hMixer, mixerId, 0, 0, MIXER_OBJECTF_MIXER); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerOpen() failed (err=%d)", res); - } - - // Store the output mixer handle and active mixer identifier - // - _outputMixerHandle = hMixer; - _outputMixerID = mixerId; - - if (_outputMixerHandle != NULL) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "the output mixer device is now open (0x%x)", _outputMixerHandle); - } - - return 0; -} - -// ---------------------------------------------------------------------------- -// OpenSpeaker II(II) -// -// Verifies that the mixer contains a valid speaker destination line. -// Avoids opening the mixer if valid control has not been found. -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::OpenSpeaker(uint16_t index) -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::OpenSpeaker(index=%d)", index); - - CriticalSectionScoped lock(&_critSect); - - // Close any existing output mixer handle - // - if (_outputMixerHandle != NULL) - { - mixerClose(_outputMixerHandle); - _outputMixerHandle = NULL; - } - - MMRESULT res; - WAVEFORMATEX waveFormat; - HWAVEOUT hWaveOut(NULL); - - const UINT deviceID(index); // use index parameter as device identifier - - waveFormat.wFormatTag = WAVE_FORMAT_PCM ; - waveFormat.nChannels = 2; - waveFormat.nSamplesPerSec = 48000; - waveFormat.wBitsPerSample = 16; - waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; - waveFormat.cbSize = 0; - - // We need a waveform-audio output handle for the currently selected output device. - // This handle will then give us the corresponding mixer identifier. Once the mixer - // ID is known, it is possible to open the output mixer. - // - res = waveOutOpen(&hWaveOut, deviceID, &waveFormat, 0, 0, CALLBACK_NULL); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "waveOutOpen(deviceID=%u) failed (err=%d)", index, res); - TraceWaveOutError(res); - } - - UINT mixerId(0); - HMIXER hMixer(NULL); - - // Retrieve the device identifier for a mixer device associated with the - // aquired waveform-audio output handle. - // - res = mixerGetID((HMIXEROBJ)hWaveOut, &mixerId, MIXER_OBJECTF_HWAVEOUT); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetID(MIXER_OBJECTF_HWAVEOUT) failed (err=%d)", res); - // identification failed => use default mixer identifier (=0) - mixerId = 0; - } - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "specified output device <=> mixer ID %u", mixerId); - - // The waveform-audio output handle is no longer needed. - // - waveOutClose(hWaveOut); - - // Verify that the mixer contains a valid speaker destination line. - // Avoid opening the mixer if valid control has not been found. - // - if (!SpeakerIsValid(mixerId)) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "it is not possible to control the speaker volume for this mixer device"); - return -1; - } - - // Open the specified mixer device and ensure that the device will not - // be removed until the application closes the handle. - // - res = mixerOpen(&hMixer, mixerId, 0, 0, MIXER_OBJECTF_MIXER); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerOpen() failed (err=%d)", res); - } - - // Store the output mixer handle and active mixer identifier - // - _outputMixerHandle = hMixer; - _outputMixerID = mixerId; - - if (_outputMixerHandle != NULL) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "the output mixer device is now open (0x%x)", _outputMixerHandle); - } - - return 0; -} - -// ---------------------------------------------------------------------------- -// OpenMicrophone I(II) -// -// Verifies that the mixer contains a valid wave-in destination line. -// Avoids opening the mixer if valid control has not been found. -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::OpenMicrophone(AudioDeviceModule::WindowsDeviceType device) -{ - if (device == AudioDeviceModule::kDefaultDevice) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::OpenMicrophone(kDefaultDevice)"); - } - else if (device == AudioDeviceModule::kDefaultCommunicationDevice) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::OpenMicrophone(kDefaultCommunicationDevice)"); - } - - CriticalSectionScoped lock(&_critSect); - - // Close any existing output mixer handle - // - if (_inputMixerHandle != NULL) - { - mixerClose(_inputMixerHandle); - _inputMixerHandle = NULL; - } - - MMRESULT res = MMSYSERR_NOERROR; - WAVEFORMATEX waveFormat; - HWAVEIN hWaveIn(NULL); - - waveFormat.wFormatTag = WAVE_FORMAT_PCM ; - waveFormat.nChannels = 1; - waveFormat.nSamplesPerSec = 48000; - waveFormat.wBitsPerSample = 16; - waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; - waveFormat.cbSize = 0 ; - - // We need a waveform-audio input handle for the currently selected input device. - // This handle will then give us the corresponding mixer identifier. Once the mixer - // ID is known, it is possible to open the input mixer. - // - if (device == AudioDeviceModule::kDefaultCommunicationDevice) - { - // check if it is possible to open the default communication device (supported on Windows 7) - res = waveInOpen(NULL, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL | - WAVE_MAPPED_kDefaultCommunicationDevice | WAVE_FORMAT_QUERY); - if (MMSYSERR_NOERROR == res) - { - // if so, open the default communication device for real - res = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL | WAVE_MAPPED_kDefaultCommunicationDevice); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "opening default communication device"); - } - else - { - // use default device since default communication device was not avaliable - res = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "unable to open default communication device => using default instead"); - } - } - else if (device == AudioDeviceModule::kDefaultDevice) - { - // open default device since it has been requested - res = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "opening default input device"); - } - - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "waveInOpen() failed (err=%d)", res); - TraceWaveInError(res); - } - - UINT mixerId(0); - HMIXER hMixer(NULL); - - // Retrieve the device identifier for a mixer device associated with the - // aquired waveform-audio input handle. - // - res = mixerGetID((HMIXEROBJ)hWaveIn, &mixerId, MIXER_OBJECTF_HWAVEIN); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetID(MIXER_OBJECTF_HWAVEIN) failed (err=%d)", res); - // identification failed => use default mixer identifier (=0) - mixerId = 0; - } - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "specified input device <=> mixer ID %u", mixerId); - - // The waveform-audio input handle is no longer needed. - // - waveInClose(hWaveIn); - - // Verify that the mixer contains a valid wave-in destination line and a volume control. - // Avoid opening the mixer if valid control has not been found. - // - if (!MicrophoneIsValid(mixerId)) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "it is not possible to control the microphone volume for this mixer device"); - return -1; - } - - // Open the specified mixer device and ensure that the device will not - // be removed until the application closes the handle. - // - res = mixerOpen(&hMixer, mixerId, 0, 0, MIXER_OBJECTF_MIXER); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerOpen() failed (err=%d)", res); - } - - // Store the input mixer handle and active mixer identifier - // - _inputMixerHandle = hMixer; - _inputMixerID = mixerId; - - if (_inputMixerHandle != NULL) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "the input mixer device is now open (0x%x)", _inputMixerHandle); - } - - return 0; -} - -// ---------------------------------------------------------------------------- -// OpenMicrophone II(II) -// -// Verifies that the mixer contains a valid wave-in destination line. -// Avoids opening the mixer if valid control has not been found. -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::OpenMicrophone(uint16_t index) -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::OpenMicrophone(index=%d)", index); - - CriticalSectionScoped lock(&_critSect); - - // Close any existing input mixer handle - // - if (_inputMixerHandle != NULL) - { - mixerClose(_inputMixerHandle); - _inputMixerHandle = NULL; - } - - MMRESULT res; - WAVEFORMATEX waveFormat; - HWAVEIN hWaveIn(NULL); - - const UINT deviceID(index); // use index parameter as device identifier - - waveFormat.wFormatTag = WAVE_FORMAT_PCM ; - waveFormat.nChannels = 1; - waveFormat.nSamplesPerSec = 48000; - waveFormat.wBitsPerSample = 16; - waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; - waveFormat.cbSize = 0; - - // We need a waveform-audio input handle for the currently selected input device. - // This handle will then give us the corresponding mixer identifier. Once the mixer - // ID is known, it is possible to open the input mixer. - // - res = waveInOpen(&hWaveIn, deviceID, &waveFormat, 0, 0, CALLBACK_NULL); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "waveInOpen(deviceID=%u) failed (err=%d)", index, res); - TraceWaveInError(res); - } - - UINT mixerId(0); - HMIXER hMixer(NULL); - - // Retrieve the device identifier for a mixer device associated with the - // aquired waveform-audio input handle. - // - res = mixerGetID((HMIXEROBJ)hWaveIn, &mixerId, MIXER_OBJECTF_HWAVEIN); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetID(MIXER_OBJECTF_HWAVEIN) failed (err=%d)", res); - // identification failed => use default mixer identifier (=0) - mixerId = 0; - } - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "specified input device <=> mixer ID %u", mixerId); - - // The waveform-audio input handle is no longer needed. - // - waveInClose(hWaveIn); - - // Verify that the mixer contains a valid wave-in destination line. - // Avoid opening the mixer if valid control has not been found. - // - if (!MicrophoneIsValid(mixerId)) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "it is not possible to control the microphone volume for this mixer device"); - return -1; - } - - // Open the specified mixer device and ensure that the device will not - // be removed until the application closes the handle. - // - res = mixerOpen(&hMixer, mixerId, 0, 0, MIXER_OBJECTF_MIXER); - if (MMSYSERR_NOERROR != res) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerOpen() failed (err=%d)", res); - } - - // Store the input mixer handle and active mixer identifier - // - _inputMixerHandle = hMixer; - _inputMixerID = mixerId; - - if (_inputMixerHandle != NULL) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "the input mixer device is now open (0x%x)", _inputMixerHandle); - } - - return 0; -} - -// ---------------------------------------------------------------------------- -// SpeakerIsInitialized -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::SpeakerIsInitialized() const -{ - WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - return (_outputMixerHandle != NULL); -} - -// ---------------------------------------------------------------------------- -// MicrophoneIsInitialized -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::MicrophoneIsInitialized() const -{ - WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - return (_inputMixerHandle != NULL); -} - -// ---------------------------------------------------------------------------- -// SetSpeakerVolume -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SetSpeakerVolume(uint32_t volume) -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::SetSpeakerVolume(volume=%u)", volume); - - CriticalSectionScoped lock(&_critSect); - - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - const UINT mixerID(_outputMixerID); - const DWORD dwControlID(_speakerState[_outputMixerID].dwVolumeControlID); - DWORD dwValue(volume); - - // Set one unsigned control value for a specified volume-control identifier - // - if (!SetUnsignedControlValue(mixerID, dwControlID, dwValue)) - { - return -1; - } - - return (0); -} - -// ---------------------------------------------------------------------------- -// SpeakerVolume -// -// Note that (MIXERCONTROL_CONTROLTYPE_VOLUME & MIXERCONTROL_CT_UNITS_MASK) -// always equals MIXERCONTROL_CT_UNITS_UNSIGNED; -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SpeakerVolume(uint32_t& volume) const -{ - - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - const UINT mixerID(_outputMixerID); - const DWORD dwControlID(_speakerState[_outputMixerID].dwVolumeControlID); - DWORD dwValue(0); - - // Retrieve one unsigned control value for a specified volume-control identifier - // - if (!GetUnsignedControlValue(mixerID, dwControlID, dwValue)) - { - return -1; - } - - volume = dwValue; - - return 0; -} - -// ---------------------------------------------------------------------------- -// MaxSpeakerVolume -// -// Note that (MIXERCONTROL_CONTROLTYPE_VOLUME & MIXERCONTROL_CT_UNITS_MASK) -// always equals MIXERCONTROL_CT_UNITS_UNSIGNED -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MaxSpeakerVolume(uint32_t& maxVolume) const -{ - - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - const UINT mixerID(_outputMixerID); - const DWORD dwControlID(_speakerState[_outputMixerID].dwVolumeControlID); - MIXERCONTROL mixerControl; - - // Retrieve one control line for a specified volume-control identifier - // - if (!GetLineControl(mixerID, dwControlID, mixerControl)) - { - return -1; - } - - maxVolume = mixerControl.Bounds.dwMaximum; - - return 0; -} - -// ---------------------------------------------------------------------------- -// MinSpeakerVolume -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MinSpeakerVolume(uint32_t& minVolume) const -{ - - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - const UINT mixerID(_outputMixerID); - const DWORD dwControlID(_speakerState[_outputMixerID].dwVolumeControlID); - MIXERCONTROL mixerControl; - - // Retrieve one control line for a specified volume-control identifier - // - if (!GetLineControl(mixerID, dwControlID, mixerControl)) - { - return -1; - } - - minVolume = mixerControl.Bounds.dwMinimum; - - return 0; -} - -// ---------------------------------------------------------------------------- -// SpeakerVolumeStepSize -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SpeakerVolumeStepSize(uint16_t& stepSize) const -{ - - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - const UINT mixerID(_outputMixerID); - MIXERCONTROL mixerControl; - - // Retrieve one control line for a specified volume-control identifier - // - if (!GetLineControl(mixerID, _speakerState[mixerID].dwVolumeControlID, mixerControl)) - { - return -1; - } - - stepSize = static_cast (mixerControl.Metrics.cSteps); - - return 0; -} - -// ---------------------------------------------------------------------------- -// SpeakerVolumeIsAvailable -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SpeakerVolumeIsAvailable(bool& available) -{ - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - available = _speakerState[_outputMixerID].volumeControlIsValid; - - return 0; -} - -// ---------------------------------------------------------------------------- -// SpeakerMuteIsAvailable -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SpeakerMuteIsAvailable(bool& available) -{ - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - available = _speakerState[_outputMixerID].muteControlIsValid; - - return 0; -} - -// ---------------------------------------------------------------------------- -// SetSpeakerMute -// -// This mute function works a master mute for the output speaker. -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SetSpeakerMute(bool enable) -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::SetSpeakerMute(enable=%u)", enable); - - CriticalSectionScoped lock(&_critSect); - - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - // Ensure that the selected speaker destination has a valid mute control. - // If so, its identifier was stored during the enumeration phase which must - // have taken place since the output mixer handle exists. - // - if (!_speakerState[_outputMixerID].muteControlIsValid) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "it is not possible to mute this speaker line"); - return -1; - } - - const DWORD dwControlID(_speakerState[_outputMixerID].dwMuteControlID); - - // Set one boolean control value for the specified mute-control - // - if (!SetBooleanControlValue(_outputMixerID, dwControlID, enable)) - { - return -1; - } - - return (0); -} - -// ---------------------------------------------------------------------------- -// SpeakerMute -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SpeakerMute(bool& enabled) const -{ - - if (_outputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable output mixer exists"); - return -1; - } - - // Ensure that the selected speaker destination has a valid mute control. - // If so, its identifier was stored during the enumeration phase which must - // have taken place since the output mixer handle exists. - // - if (!_speakerState[_outputMixerID].muteControlIsValid) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "it is not possible to mute this speaker line"); - return -1; - } - - const DWORD dwControlID(_speakerState[_outputMixerID].dwMuteControlID); - bool value(false); - - // Retrieve one boolean control value for a specified mute-control identifier - // - if (!GetBooleanControlValue(_outputMixerID, dwControlID, value)) - { - return -1; - } - - enabled = value; - - return 0; -} - -// ---------------------------------------------------------------------------- -// MicrophoneMuteIsAvailable -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MicrophoneMuteIsAvailable(bool& available) -{ - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - available = _microphoneState[_inputMixerID].muteControlIsValid; - - return 0; -} - -// ---------------------------------------------------------------------------- -// SetMicrophoneMute -// -// This mute function works a master mute for the input microphone. -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SetMicrophoneMute(bool enable) -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::SetMicrophoneMute(enable=%u)", enable); - - CriticalSectionScoped lock(&_critSect); - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - // Ensure that the selected wave-in destinationhas a valid mute control. - // If so, its identifier was stored during the enumeration phase which must - // have taken place since the input mixer handle exists. - // - if (!_microphoneState[_inputMixerID].muteControlIsValid) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "it is not possible to mute this microphone line"); - return -1; - } - - const DWORD dwControlID(_microphoneState[_inputMixerID].dwMuteControlID); - - // Set one boolean control value for the specified mute-control - // - if (!SetBooleanControlValue(_inputMixerID, dwControlID, enable)) - { - return -1; - } - - return (0); -} - -// ---------------------------------------------------------------------------- -// MicrophoneMute -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MicrophoneMute(bool& enabled) const -{ - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - // Ensure that the selected wave-in destinationhas a valid mute control. - // If so, its identifier was stored during the enumeration phase which must - // have taken place since the input mixer handle exists. - // - if (!_microphoneState[_inputMixerID].muteControlIsValid) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "it is not possible to mute this microphone line"); - return -1; - } - - const DWORD dwControlID(_microphoneState[_inputMixerID].dwMuteControlID); - bool value(false); - - // Retrieve one boolean control value for a specified mute-control identifier - // - if (!GetBooleanControlValue(_inputMixerID, dwControlID, value)) - { - return -1; - } - - enabled = value; - - return 0; -} - -// ---------------------------------------------------------------------------- -// MicrophoneBoostIsAvailable -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MicrophoneBoostIsAvailable(bool& available) -{ - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - available = _microphoneState[_inputMixerID].onOffControlIsValid; - - return 0; -} - -// ---------------------------------------------------------------------------- -// SetMicrophoneBoost -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SetMicrophoneBoost(bool enable) -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::SetMicrophoneBoost(enable=%u)", enable); - - CriticalSectionScoped lock(&_critSect); - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - // Ensure that the selected wave-in destination has a valid boost (on/off) control. - // If so, its identifier was stored during the enumeration phase which must - // have taken place since the input mixer handle exists. - // - if (!_microphoneState[_inputMixerID].onOffControlIsValid) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no boost control exists for this wave-in line"); - return -1; - } - - const DWORD dwControlID(_microphoneState[_inputMixerID].dwOnOffControlID); - - // Set one boolean control value for the specified boost (on/off) control - // - if (!SetBooleanControlValue(_inputMixerID, dwControlID, enable)) - { - return -1; - } - - return (0); -} - -// ---------------------------------------------------------------------------- -// MicrophoneBoost -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MicrophoneBoost(bool& enabled) const -{ - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - // Ensure that the selected wave-in destination has a valid boost (on/off) control. - // If so, its identifier was stored during the enumeration phase which must - // have taken place since the input mixer handle exists. - // - if (!_microphoneState[_inputMixerID].onOffControlIsValid) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no boost control exists for this wave-in line"); - return -1; - } - - const DWORD dwControlID(_microphoneState[_inputMixerID].dwOnOffControlID); - bool value(false); - - // Retrieve one boolean control value for a specified boost-control identifier - // - if (!GetBooleanControlValue(_inputMixerID, dwControlID, value)) - { - return -1; - } - - enabled = value; - - return 0; -} - -// ---------------------------------------------------------------------------- -// MicrophoneVolumeIsAvailable -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MicrophoneVolumeIsAvailable(bool& available) -{ - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - available = _microphoneState[_inputMixerID].volumeControlIsValid; - - return 0; -} - -// ---------------------------------------------------------------------------- -// SetMicrophoneVolume -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::SetMicrophoneVolume(uint32_t volume) -{ - CriticalSectionScoped lock(&_critSect); - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - const UINT mixerID(_inputMixerID); - const DWORD dwControlID(_microphoneState[_inputMixerID].dwVolumeControlID); - DWORD dwValue(volume); - - // Set one unsigned control value for a specified volume-control identifier - // - if (!SetUnsignedControlValue(mixerID, dwControlID, dwValue)) - { - return -1; - } - - return (0); -} - -// ---------------------------------------------------------------------------- -// MicrophoneVolume -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MicrophoneVolume(uint32_t& volume) const -{ - CriticalSectionScoped lock(&_critSect); - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - const UINT mixerID(_inputMixerID); - const DWORD dwControlID(_microphoneState[_inputMixerID].dwVolumeControlID); - DWORD dwValue(0); - - // Retrieve one unsigned control value for a specified volume-control identifier - // - if (!GetUnsignedControlValue(mixerID, dwControlID, dwValue)) - { - return -1; - } - - volume = dwValue; - - return 0; -} - -// ---------------------------------------------------------------------------- -// MaxMicrophoneVolume -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MaxMicrophoneVolume(uint32_t& maxVolume) const -{ - WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id, "%s", __FUNCTION__); - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - const UINT mixerID(_inputMixerID); - const DWORD dwControlID(_microphoneState[_inputMixerID].dwVolumeControlID); - MIXERCONTROL mixerControl; - - // Retrieve one control line for a specified volume-control identifier - // - if (!GetLineControl(mixerID, dwControlID, mixerControl)) - { - return -1; - } - - maxVolume = mixerControl.Bounds.dwMaximum; - - return 0; -} - -// ---------------------------------------------------------------------------- -// MinMicrophoneVolume -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MinMicrophoneVolume(uint32_t& minVolume) const -{ - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - const UINT mixerID(_inputMixerID); - const DWORD dwControlID(_microphoneState[_inputMixerID].dwVolumeControlID); - MIXERCONTROL mixerControl; - - // Retrieve one control line for a specified volume-control identifier - // - if (!GetLineControl(mixerID, dwControlID, mixerControl)) - { - return -1; - } - - minVolume = mixerControl.Bounds.dwMinimum; - - return 0; -} - -// ---------------------------------------------------------------------------- -// MicrophoneVolumeStepSize -// ---------------------------------------------------------------------------- - -int32_t AudioMixerManager::MicrophoneVolumeStepSize(uint16_t& stepSize) const -{ - - if (_inputMixerHandle == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "no avaliable input mixer exists"); - return -1; - } - - const UINT mixerID(_inputMixerID); - const DWORD dwControlID(_microphoneState[_inputMixerID].dwVolumeControlID); - MIXERCONTROL mixerControl; - - // Retrieve one control line for a specified volume-control identifier - // - if (!GetLineControl(mixerID, dwControlID, mixerControl)) - { - return -1; - } - - stepSize = static_cast (mixerControl.Metrics.cSteps); - - return 0; -} - -// ============================================================================ -// PRIVATE METHODS -// ============================================================================ - -// ---------------------------------------------------------------------------- -// Devices -// -// A given audio card has one Mixer device associated with it. All of the -// various components on that card are controlled through that card's one -// Mixer device. -// ---------------------------------------------------------------------------- - -UINT AudioMixerManager::Devices() const -{ - UINT nDevs = mixerGetNumDevs(); - return nDevs; -} - -// ---------------------------------------------------------------------------- -// DestinationLines -// -// # destination lines given mixer ID. -// ---------------------------------------------------------------------------- - -UINT AudioMixerManager::DestinationLines(UINT mixId) const -{ - MIXERCAPS caps; - if (!GetCapabilities(mixId, caps)) - { - return 0; - } - return (caps.cDestinations); -} -// ---------------------------------------------------------------------------- -// DestinationLines -// -// # source lines given mixer ID and destination ID. -// ---------------------------------------------------------------------------- - -UINT AudioMixerManager::SourceLines(UINT mixId, DWORD destId) const -{ - MIXERLINE dline; - if (!GetDestinationLineInfo(mixId, destId, dline)) - { - return 0; - } - return (dline.cConnections); -} - -// ---------------------------------------------------------------------------- -// GetCapabilities -// -// Queries a specified mixer device to determine its capabilities. -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetCapabilities(UINT mixId, MIXERCAPS& caps, bool trace) const -{ - MMRESULT res; - MIXERCAPS mcaps; - - res = mixerGetDevCaps(mixId, &mcaps, sizeof(MIXERCAPS)); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetDevCaps() failed (err=%d)", res); - return false; - } - - memcpy(&caps, &mcaps, sizeof(MIXERCAPS)); - - if (trace) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "==============================================================="); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "Mixer ID %u:", mixId); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "manufacturer ID : %u", caps.wMid); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "product ID : %u", caps.wPid); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "version of driver : %u", caps.vDriverVersion); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "product name : %s", WideToUTF8(caps.szPname)); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "misc. support bits : %u", caps.fdwSupport); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "count of destinations: %u (+)", caps.cDestinations); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "==============================================================="); - } - - if (caps.cDestinations == 0) - { - WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, "invalid number of mixer destinations"); - return false; - } - - return true; -} - -// ---------------------------------------------------------------------------- -// GetDestinationLineInfo -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetDestinationLineInfo(UINT mixId, DWORD destId, MIXERLINE& line, bool trace) const -{ - MMRESULT res; - MIXERLINE mline; - - mline.cbStruct = sizeof(MIXERLINE); - mline.dwDestination = destId; // max destination index is cDestinations-1 - mline.dwSource = 0; // not set for MIXER_GETLINEINFOF_DESTINATION - - // Retrieve information about the specified destination line of a mixer device. - // Note that we use the mixer ID here and not a handle to an opened mixer. - // It is not required to open the mixer for enumeration purposes only. - // - res = mixerGetLineInfo(reinterpret_cast(mixId), &mline, MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_DESTINATION); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetLineInfo(MIXER_GETLINEINFOF_DESTINATION) failed (err=%d)", res); - return false; - } - - memcpy(&line, &mline, sizeof(MIXERLINE)); - - if (trace) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "> Destination Line ID %u:", destId); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "destination line index : %u", mline.dwDestination); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "dwLineID : %lu (unique)", mline.dwLineID); - TraceStatusAndSupportFlags(mline.fdwLine); - TraceComponentType(mline.dwComponentType); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "count of channels : %u", mline.cChannels); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "# audio source lines : %u (+)", mline.cConnections); // valid only for destinations - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "# controls : %u (*)", mline.cControls); // can be zero - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "short name : %s", WideToUTF8(mline.szShortName)); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "full name : %s", WideToUTF8(mline.szName)); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); - TraceTargetType(mline.Target.dwType); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "target device ID : %lu", mline.Target.dwDeviceID); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "manufacturer ID : %u", mline.Target.wMid); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "product ID : %u", mline.Target.wPid); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "driver version : %u", mline.Target.vDriverVersion); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "product name : %s", WideToUTF8(mline.Target.szPname)); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "---------------------------------------------------------------"); - } - - return true; -} - -// ---------------------------------------------------------------------------- -// GetSourceLineInfo -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetSourceLineInfo(UINT mixId, DWORD destId, DWORD srcId, MIXERLINE& line, bool trace) const -{ - MMRESULT res; - MIXERLINE mline; - - mline.cbStruct = sizeof(MIXERLINE); - mline.dwDestination = destId; // we want the source info for this destination - mline.dwSource = srcId; // source index (enumerate over these) - - // Retrieve information about the specified source line of a mixer device. - // Note that we use the mixer ID here and not a handle to an opened mixer. - // It is not required to open the mixer for enumeration purposes only. - // - res = mixerGetLineInfo(reinterpret_cast(mixId), &mline, MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetLineInfo(MIXER_GETLINEINFOF_SOURCE) failed (err=%d)", res); - return false; - } - - memcpy(&line, &mline, sizeof(MIXERLINE)); - - if (trace) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " >> Source Line ID %u:", srcId); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "destination line index : %u", mline.dwDestination); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "dwSource : %u", mline.dwSource); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "dwLineID : %lu (unique)", mline.dwLineID); - TraceStatusAndSupportFlags(mline.fdwLine); - TraceComponentType(mline.dwComponentType); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "# controls : %u (*)", mline.cControls); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "full name : %s", WideToUTF8(mline.szName)); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); - TraceTargetType(mline.Target.dwType); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "---------------------------------------------------------------"); - } - - return true; -} - -// ---------------------------------------------------------------------------- -// GetAllLineControls -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetAllLineControls(UINT mixId, const MIXERLINE& line, MIXERCONTROL* controlArray, bool trace) const -{ - // Ensure that we don't try to aquire information if there are no controls for this line - // - if (line.cControls == 0) - return false; - - MMRESULT res; - MIXERLINECONTROLS mlineControls; // contains information about the controls of an audio line - - mlineControls.dwLineID = line.dwLineID; // unique audio line identifier - mlineControls.cControls = line.cControls; // number of controls associated with the line - mlineControls.pamxctrl = controlArray; // points to the first MIXERCONTROL structure to be filled - mlineControls.cbStruct = sizeof(MIXERLINECONTROLS); - mlineControls.cbmxctrl = sizeof(MIXERCONTROL); - - // Get information on ALL controls associated with the specified audio line - // - res = mixerGetLineControls(reinterpret_cast(mixId), &mlineControls, MIXER_OBJECTF_MIXER | MIXER_GETLINECONTROLSF_ALL); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetLineControls(MIXER_GETLINECONTROLSF_ALL) failed (err=%d)", res); - return false; - } - - if (trace) - { - for (UINT c = 0; c < line.cControls; c++) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " >> Control ID %u:", c); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "dwControlID : %u (unique)", controlArray[c].dwControlID); - TraceControlType(controlArray[c].dwControlType); - TraceControlStatusAndSupportFlags(controlArray[c].fdwControl); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "cMultipleItems : %u", controlArray[c].cMultipleItems); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "short name : %s", WideToUTF8(controlArray[c].szShortName)); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "full name : %s", WideToUTF8(controlArray[c].szName)); - if ((controlArray[c].dwControlType & MIXERCONTROL_CT_UNITS_MASK) == MIXERCONTROL_CT_UNITS_SIGNED) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "min signed value : %d", controlArray[c].Bounds.lMinimum); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "max signed value : %d", controlArray[c].Bounds.lMaximum); - } - else if ((controlArray[c].dwControlType & MIXERCONTROL_CT_UNITS_MASK) == MIXERCONTROL_CT_UNITS_UNSIGNED || - (controlArray[c].dwControlType & MIXERCONTROL_CT_UNITS_MASK) == MIXERCONTROL_CT_UNITS_BOOLEAN) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "min unsigned value : %u", controlArray[c].Bounds.dwMinimum); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "max unsigned value : %u", controlArray[c].Bounds.dwMaximum); - } - if (controlArray[c].dwControlType != MIXERCONTROL_CONTROLTYPE_CUSTOM) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "cSteps : %u", controlArray[c].Metrics.cSteps); - } - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "..............................................................."); - GetControlDetails(mixId, controlArray[c], true); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "..............................................................."); - - } - } - - return true; -} - -// ---------------------------------------------------------------------------- -// GetLineControls -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetLineControl(UINT mixId, DWORD dwControlID, MIXERCONTROL& control) const -{ - MMRESULT res; - MIXERLINECONTROLS mlineControl; - - mlineControl.dwControlID = dwControlID; - mlineControl.cControls = 1; - mlineControl.pamxctrl = &control; - mlineControl.cbStruct = sizeof(MIXERLINECONTROLS); - mlineControl.cbmxctrl = sizeof(MIXERCONTROL); - - // Get information on one controls associated with the specified conrol identifier - // - res = mixerGetLineControls(reinterpret_cast(mixId), &mlineControl, MIXER_OBJECTF_MIXER | MIXER_GETLINECONTROLSF_ONEBYID); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetLineControls(MIXER_GETLINECONTROLSF_ONEBYID) failed (err=%d)", res); - return false; - } - - return true; -} - -// ---------------------------------------------------------------------------- -// GetControlDetails -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetControlDetails(UINT mixId, MIXERCONTROL& controlArray, bool trace) const -{ - assert(controlArray.cMultipleItems <= MAX_NUMBER_OF_MULTIPLE_ITEMS); - - MMRESULT res; - MIXERCONTROLDETAILS controlDetails; - - MIXERCONTROLDETAILS_UNSIGNED valueUnsigned[MAX_NUMBER_OF_MULTIPLE_ITEMS]; - MIXERCONTROLDETAILS_SIGNED valueSigned[MAX_NUMBER_OF_MULTIPLE_ITEMS]; - MIXERCONTROLDETAILS_BOOLEAN valueBoolean[MAX_NUMBER_OF_MULTIPLE_ITEMS]; - - enum ControlType - { - CT_UNITS_UNSIGNED, - CT_UNITS_SIGNED, - CT_UNITS_BOOLEAN - }; - - ControlType ctype(CT_UNITS_UNSIGNED); - - controlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); - controlDetails.dwControlID = controlArray.dwControlID; // control identifier - controlDetails.cChannels = 1; // we need to set values as if they were uniform - controlDetails.cMultipleItems = controlArray.cMultipleItems; // only nonzero for CONTROLF_MULTIPLE controls - // can e.g. happen for CONTROLTYPE_MUX - if (controlDetails.cMultipleItems > MAX_NUMBER_OF_MULTIPLE_ITEMS) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "cMultipleItems > %d", MAX_NUMBER_OF_MULTIPLE_ITEMS); - controlDetails.cMultipleItems = MAX_NUMBER_OF_MULTIPLE_ITEMS; - } - - if ((controlArray.dwControlType & MIXERCONTROL_CT_UNITS_MASK) == MIXERCONTROL_CT_UNITS_SIGNED) - { - ctype = CT_UNITS_SIGNED; - controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_SIGNED); - controlDetails.paDetails = &valueSigned[0]; - } - else if ((controlArray.dwControlType & MIXERCONTROL_CT_UNITS_MASK) == MIXERCONTROL_CT_UNITS_UNSIGNED) - { - ctype = CT_UNITS_UNSIGNED; - controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - controlDetails.paDetails = &valueUnsigned[0]; - } - else if ((controlArray.dwControlType & MIXERCONTROL_CT_UNITS_MASK) == MIXERCONTROL_CT_UNITS_BOOLEAN) - { - ctype = CT_UNITS_BOOLEAN; - controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); - controlDetails.paDetails = &valueBoolean[0]; - } - - // Retrieve a control's value - // - res = mixerGetControlDetails(reinterpret_cast(mixId), &controlDetails, MIXER_OBJECTF_MIXER | MIXER_GETCONTROLDETAILSF_VALUE); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE) failed (err=%d)", res); - return false; - } - - if (trace) - { - UINT nItems(1); - nItems = (controlDetails.cMultipleItems > 0 ? controlDetails.cMultipleItems : 1); - for (UINT i = 0; i < nItems; i++) - { - if (ctype == CT_UNITS_SIGNED) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "signed value : %d", valueSigned[i].lValue); - } - else if (ctype == CT_UNITS_UNSIGNED) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "unsigned value : %u", valueUnsigned[i].dwValue); - } - else if (ctype == CT_UNITS_BOOLEAN) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "boolean value : %u", valueBoolean[i].fValue); - } - } - } - - return true; -} - -// ---------------------------------------------------------------------------- -// GetUnsignedControlValue -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetUnsignedControlValue(UINT mixId, DWORD dwControlID, DWORD& dwValue) const -{ - MMRESULT res; - MIXERCONTROLDETAILS controlDetails; - MIXERCONTROLDETAILS_UNSIGNED valueUnsigned; - - controlDetails.dwControlID = dwControlID; - controlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); - controlDetails.cChannels = 1; - controlDetails.cMultipleItems = 0; - controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - controlDetails.paDetails = &valueUnsigned; - - // Retrieve the unsigned value - // - res = mixerGetControlDetails(reinterpret_cast(mixId), &controlDetails, MIXER_OBJECTF_MIXER | MIXER_GETCONTROLDETAILSF_VALUE); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE) failed (err=%d)", res); - return false; - } - - // Deliver the retrieved value - // - dwValue = valueUnsigned.dwValue; - - return true; -} - -// ---------------------------------------------------------------------------- -// SetUnsignedControlValue -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::SetUnsignedControlValue(UINT mixId, DWORD dwControlID, DWORD dwValue) const -{ - WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id, "AudioMixerManager::SetUnsignedControlValue(mixId=%u, dwControlID=%d, dwValue=%d)", mixId, dwControlID, dwValue); - - MMRESULT res; - MIXERCONTROLDETAILS controlDetails; - MIXERCONTROLDETAILS_UNSIGNED valueUnsigned; - - controlDetails.dwControlID = dwControlID; - controlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); - controlDetails.cChannels = 1; - controlDetails.cMultipleItems = 0; - controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - controlDetails.paDetails = &valueUnsigned; - - valueUnsigned.dwValue = dwValue; - - // Set the unsigned value - // - res = mixerSetControlDetails(reinterpret_cast(mixId), &controlDetails, MIXER_OBJECTF_MIXER | MIXER_GETCONTROLDETAILSF_VALUE); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerSetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE) failed (err=%d)", res); - return false; - } - - return true; -} - -// ---------------------------------------------------------------------------- -// SetBooleanControlValue -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::SetBooleanControlValue(UINT mixId, DWORD dwControlID, bool value) const -{ - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "AudioMixerManager::SetBooleanControlValue(mixId=%u, dwControlID=%d, value=%d)", mixId, dwControlID, value); - - MMRESULT res; - MIXERCONTROLDETAILS controlDetails; - MIXERCONTROLDETAILS_BOOLEAN valueBoolean; - - controlDetails.dwControlID = dwControlID; - controlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); - controlDetails.cChannels = 1; - controlDetails.cMultipleItems = 0; - controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); - controlDetails.paDetails = &valueBoolean; - - if (value == true) - valueBoolean.fValue = TRUE; - else - valueBoolean.fValue = FALSE; - - // Set the boolean value - // - res = mixerSetControlDetails(reinterpret_cast(mixId), &controlDetails, MIXER_OBJECTF_MIXER | MIXER_GETCONTROLDETAILSF_VALUE); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerSetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE) failed (err=%d)", res); - return false; - } - - return true; -} - -// ---------------------------------------------------------------------------- -// GetBooleanControlValue -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetBooleanControlValue(UINT mixId, DWORD dwControlID, bool& value) const -{ - MMRESULT res; - MIXERCONTROLDETAILS controlDetails; - MIXERCONTROLDETAILS_BOOLEAN valueBoolean; - - controlDetails.dwControlID = dwControlID; - controlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); - controlDetails.cChannels = 1; - controlDetails.cMultipleItems = 0; - controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); - controlDetails.paDetails = &valueBoolean; - - // Retrieve the boolean value - // - res = mixerGetControlDetails(reinterpret_cast(mixId), &controlDetails, MIXER_OBJECTF_MIXER | MIXER_GETCONTROLDETAILSF_VALUE); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE) failed (err=%d)", res); - return false; - } - - // Deliver the retrieved value - // - if (valueBoolean.fValue == 0) - value = false; - else - value = true; - - return true; -} - -// ---------------------------------------------------------------------------- -// GetSelectedMuxSource -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::GetSelectedMuxSource(UINT mixId, DWORD dwControlID, DWORD cMultipleItems, UINT& index) const -{ - assert(cMultipleItems <= MAX_NUMBER_OF_MULTIPLE_ITEMS); - - MMRESULT res; - MIXERCONTROLDETAILS controlDetails; - MIXERCONTROLDETAILS_BOOLEAN valueBoolean[MAX_NUMBER_OF_MULTIPLE_ITEMS]; - memset(&valueBoolean, 0, sizeof(valueBoolean)); - - controlDetails.dwControlID = dwControlID; - controlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); - controlDetails.cChannels = 1; - controlDetails.cMultipleItems = cMultipleItems; - controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); - controlDetails.paDetails = &valueBoolean; - - // Retrieve the boolean values - // - res = mixerGetControlDetails(reinterpret_cast(mixId), &controlDetails, MIXER_OBJECTF_MIXER | MIXER_GETCONTROLDETAILSF_VALUE); - if (res != MMSYSERR_NOERROR) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE) failed (err=%d)", res); - return false; - } - - // Map the current MUX setting to an index corresponding to a source index. - // e.g. with cMultipleItems = 3, - // valueBoolean[] = {1,0,0} => index = 2 - // valueBoolean[] = {0,1,0} => index = 1 - // valueBoolean[] = {0,0,1} => index = 0 - // - // If there is no "1" in the array, we assume index should be 0. - index = 0; - for (DWORD i = 0; i < cMultipleItems; i++) - { - if (valueBoolean[i].fValue > 0) - { - index = (cMultipleItems - 1) - i; - break; - } - } - - return true; -} - -// ---------------------------------------------------------------------------- -// TraceStatusAndSupportFlags -// ---------------------------------------------------------------------------- - -void AudioMixerManager::TraceStatusAndSupportFlags(DWORD fdwLine) const -{ - TCHAR buf[128]; - - StringCchPrintf(buf, 128, TEXT("status & support flags : 0x%x "), fdwLine); - - switch (fdwLine) - { - case MIXERLINE_LINEF_ACTIVE: - StringCchCat(buf, 128, TEXT("(ACTIVE DESTINATION)")); - break; - case MIXERLINE_LINEF_DISCONNECTED: - StringCchCat(buf, 128, TEXT("(DISCONNECTED)")); - break; - case MIXERLINE_LINEF_SOURCE: - StringCchCat(buf, 128, TEXT("(INACTIVE SOURCE)")); - break; - case MIXERLINE_LINEF_SOURCE | MIXERLINE_LINEF_ACTIVE: - StringCchCat(buf, 128, TEXT("(ACTIVE SOURCE)")); - break; - default: - StringCchCat(buf, 128, TEXT("(INVALID)")); - break; - } - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); -} - -// ---------------------------------------------------------------------------- -// TraceComponentType -// ---------------------------------------------------------------------------- - -void AudioMixerManager::TraceComponentType(DWORD dwComponentType) const -{ - TCHAR buf[128]; - - StringCchPrintf(buf, 128, TEXT("component type : 0x%x "), dwComponentType); - - switch (dwComponentType) - { - // Destination - case MIXERLINE_COMPONENTTYPE_DST_UNDEFINED: - StringCchCat(buf, 128, TEXT("(DST_UNDEFINED)")); - break; - case MIXERLINE_COMPONENTTYPE_DST_DIGITAL: - StringCchCat(buf, 128, TEXT("(DST_DIGITAL)")); - break; - case MIXERLINE_COMPONENTTYPE_DST_LINE: - StringCchCat(buf, 128, TEXT("(DST_LINE)")); - break; - case MIXERLINE_COMPONENTTYPE_DST_MONITOR: - StringCchCat(buf, 128, TEXT("(DST_MONITOR)")); - break; - case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS: - StringCchCat(buf, 128, TEXT("(DST_SPEAKERS)")); - break; - case MIXERLINE_COMPONENTTYPE_DST_HEADPHONES: - StringCchCat(buf, 128, TEXT("(DST_HEADPHONES)")); - break; - case MIXERLINE_COMPONENTTYPE_DST_TELEPHONE: - StringCchCat(buf, 128, TEXT("(DST_TELEPHONE)")); - break; - case MIXERLINE_COMPONENTTYPE_DST_WAVEIN: - StringCchCat(buf, 128, TEXT("(DST_WAVEIN)")); - break; - case MIXERLINE_COMPONENTTYPE_DST_VOICEIN: - StringCchCat(buf, 128, TEXT("(DST_VOICEIN)")); - break; - // Source - case MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED: - StringCchCat(buf, 128, TEXT("(SRC_UNDEFINED)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_DIGITAL: - StringCchCat(buf, 128, TEXT("(SRC_DIGITAL)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_LINE: - StringCchCat(buf, 128, TEXT("(SRC_LINE)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE: - StringCchCat(buf, 128, TEXT("(SRC_MICROPHONE)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER: - StringCchCat(buf, 128, TEXT("(SRC_SYNTHESIZER)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC: - StringCchCat(buf, 128, TEXT("(SRC_COMPACTDISC)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE: - StringCchCat(buf, 128, TEXT("(SRC_TELEPHONE)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER: - StringCchCat(buf, 128, TEXT("(SRC_PCSPEAKER)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT: - StringCchCat(buf, 128, TEXT("(SRC_WAVEOUT)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY: - StringCchCat(buf, 128, TEXT("(SRC_AUXILIARY)")); - break; - case MIXERLINE_COMPONENTTYPE_SRC_ANALOG: - StringCchCat(buf, 128, TEXT("(SRC_ANALOG)")); - break; - default: - StringCchCat(buf, 128, TEXT("(INVALID)")); - break; - } - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); -} - -// ---------------------------------------------------------------------------- -// TraceTargetType -// ---------------------------------------------------------------------------- - -void AudioMixerManager::TraceTargetType(DWORD dwType) const -{ - TCHAR buf[128]; - - StringCchPrintf(buf, 128, TEXT("media device type : 0x%x "), dwType); - - switch (dwType) - { - case MIXERLINE_TARGETTYPE_UNDEFINED: - StringCchCat(buf, 128, TEXT("(UNDEFINED)")); - break; - case MIXERLINE_TARGETTYPE_WAVEOUT: - StringCchCat(buf, 128, TEXT("(WAVEOUT)")); - break; - case MIXERLINE_TARGETTYPE_WAVEIN: - StringCchCat(buf, 128, TEXT("(WAVEIN)")); - break; - case MIXERLINE_TARGETTYPE_MIDIOUT: - StringCchCat(buf, 128, TEXT("(MIDIOUT)")); - break; - case MIXERLINE_TARGETTYPE_MIDIIN: - StringCchCat(buf, 128, TEXT("(MIDIIN)")); - break; - default: - StringCchCat(buf, 128, TEXT("(INVALID)")); - break; - } - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); -} - -// ---------------------------------------------------------------------------- -// TraceControlType -// ---------------------------------------------------------------------------- - -void AudioMixerManager::TraceControlType(DWORD dwControlType) const -{ - TCHAR buf[128]; - - // Class type classification - // - StringCchPrintf(buf, 128, TEXT("class type : 0x%x "), dwControlType); - - switch (dwControlType & MIXERCONTROL_CT_CLASS_MASK) - { - case MIXERCONTROL_CT_CLASS_CUSTOM: - StringCchCat(buf, 128, TEXT("(CT_CLASS_CUSTOM)")); - break; - case MIXERCONTROL_CT_CLASS_METER: - StringCchCat(buf, 128, TEXT("(CT_CLASS_METER)")); - break; - case MIXERCONTROL_CT_CLASS_SWITCH: - StringCchCat(buf, 128, TEXT("(CT_CLASS_SWITCH)")); - break; - case MIXERCONTROL_CT_CLASS_NUMBER: - StringCchCat(buf, 128, TEXT("(CT_CLASS_NUMBER)")); - break; - case MIXERCONTROL_CT_CLASS_SLIDER: - StringCchCat(buf, 128, TEXT("(CT_CLASS_SLIDER)")); - break; - case MIXERCONTROL_CT_CLASS_FADER: - StringCchCat(buf, 128, TEXT("(CT_CLASS_FADER)")); - break; - case MIXERCONTROL_CT_CLASS_TIME: - StringCchCat(buf, 128, TEXT("(CT_CLASS_TIME)")); - break; - case MIXERCONTROL_CT_CLASS_LIST: - StringCchCat(buf, 128, TEXT("(CT_CLASS_LIST)")); - break; - default: - StringCchCat(buf, 128, TEXT("(INVALID)")); - break; - } - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); - - // Control type (for each class) - // - StringCchPrintf(buf, 128, TEXT("control type : 0x%x "), dwControlType); - - switch (dwControlType) - { - case MIXERCONTROL_CONTROLTYPE_CUSTOM: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_CUSTOM)")); - break; - case MIXERCONTROL_CONTROLTYPE_BOOLEANMETER: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_BOOLEANMETER)")); - break; - case MIXERCONTROL_CONTROLTYPE_SIGNEDMETER: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_SIGNEDMETER)")); - break; - case MIXERCONTROL_CONTROLTYPE_PEAKMETER: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_PEAKMETER)")); - break; - case MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_UNSIGNEDMETER)")); - break; - case MIXERCONTROL_CONTROLTYPE_BOOLEAN: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_BOOLEAN)")); - break; - case MIXERCONTROL_CONTROLTYPE_ONOFF: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_ONOFF)")); - break; - case MIXERCONTROL_CONTROLTYPE_MUTE: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_MUTE)")); - break; - case MIXERCONTROL_CONTROLTYPE_MONO: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_MONO)")); - break; - case MIXERCONTROL_CONTROLTYPE_LOUDNESS: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_LOUDNESS)")); - break; - case MIXERCONTROL_CONTROLTYPE_STEREOENH: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_STEREOENH)")); - break; - case MIXERCONTROL_CONTROLTYPE_BASS_BOOST: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_BASS_BOOST)")); - break; - case MIXERCONTROL_CONTROLTYPE_BUTTON: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_BUTTON)")); - break; - case MIXERCONTROL_CONTROLTYPE_DECIBELS: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_DECIBELS)")); - break; - case MIXERCONTROL_CONTROLTYPE_SIGNED: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_SIGNED)")); - break; - case MIXERCONTROL_CONTROLTYPE_UNSIGNED: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_UNSIGNED)")); - break; - case MIXERCONTROL_CONTROLTYPE_PERCENT: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_PERCENT)")); - break; - case MIXERCONTROL_CONTROLTYPE_SLIDER: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_SLIDER)")); - break; - case MIXERCONTROL_CONTROLTYPE_PAN: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_PAN)")); - break; - case MIXERCONTROL_CONTROLTYPE_QSOUNDPAN: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_QSOUNDPAN)")); - break; - case MIXERCONTROL_CONTROLTYPE_FADER: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_FADER)")); - break; - case MIXERCONTROL_CONTROLTYPE_VOLUME: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_VOLUME)")); - break; - case MIXERCONTROL_CONTROLTYPE_BASS: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_BASS)")); - break; - case MIXERCONTROL_CONTROLTYPE_TREBLE: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_TREBLE)")); - break; - case MIXERCONTROL_CONTROLTYPE_EQUALIZER: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_EQUALIZER)")); - break; - case MIXERCONTROL_CONTROLTYPE_SINGLESELECT: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_SINGLESELECT)")); - break; - case MIXERCONTROL_CONTROLTYPE_MUX: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_MUX)")); - break; - case MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_MULTIPLESELECT)")); - break; - case MIXERCONTROL_CONTROLTYPE_MIXER: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_MIXER)")); - break; - case MIXERCONTROL_CONTROLTYPE_MICROTIME: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_MICROTIME)")); - break; - case MIXERCONTROL_CONTROLTYPE_MILLITIME: - StringCchCat(buf, 128, TEXT("(CONTROLTYPE_MILLITIME)")); - break; - default: - StringCchCat(buf, 128, TEXT("(INVALID)")); - break; - } - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); -} - -// ---------------------------------------------------------------------------- -// TraceControlStatusAndSupportFlags -// -// fdwControl -// -// Status and support flags for the audio line control. The following values -// are defined: -// -// MIXERCONTROL_CONTROLF_DISABLED -// -// The control is disabled, perhaps due to other settings for the mixer hardware, -// and cannot be used. An application can read current settings from a -// disabled control, but it cannot apply settings. -// -// MIXERCONTROL_CONTROLF_MULTIPLE -// -// The control has two or more settings per channel. An equalizer, for example, -// requires this flag because each frequency band can be set to a different value. -// An equalizer that affects both channels of a stereo line in a uniform fashion -// will also specify the MIXERCONTROL_CONTROLF_UNIFORM flag. -// -// MIXERCONTROL_CONTROLF_UNIFORM -// -// The control acts on all channels of a multichannel line in a uniform fashion. -// For example, a control that mutes both channels of a stereo line would set -// this flag. Most MIXERCONTROL_CONTROLTYPE_MUX and -// MIXERCONTROL_CONTROLTYPE_MIXER controls also specify the -// MIXERCONTROL_CONTROLF_UNIFORM flag. -// ---------------------------------------------------------------------------- - -void AudioMixerManager::TraceControlStatusAndSupportFlags(DWORD fdwControl) const -{ - TCHAR buf[128]; - - StringCchPrintf(buf, 128, TEXT("control support flags : 0x%x "), fdwControl); - - if (fdwControl & MIXERCONTROL_CONTROLF_DISABLED) - { - // The control is disabled, perhaps due to other settings for the mixer hardware, - // and cannot be used. An application can read current settings from a disabled - // control, but it cannot apply settings. - StringCchCat(buf, 128, TEXT("(CONTROLF_DISABLED)")); - } - - if (fdwControl & MIXERCONTROL_CONTROLF_MULTIPLE) - { - // The control has two or more settings per channel. An equalizer, for example, - // requires this flag because each frequency band can be set to a different - // value. An equalizer that affects both channels of a stereo line in a - // uniform fashion will also specify the MIXERCONTROL_CONTROLF_UNIFORM flag. - StringCchCat(buf, 128, TEXT("(CONTROLF_MULTIPLE)")); - } - - if (fdwControl & MIXERCONTROL_CONTROLF_UNIFORM) - { - // The control acts on all channels of a multichannel line in a uniform - // fashion. For example, a control that mutes both channels of a stereo - // line would set this flag. Most MIXERCONTROL_CONTROLTYPE_MUX and - // MIXERCONTROL_CONTROLTYPE_MIXER controls also specify the - // MIXERCONTROL_CONTROLF_UNIFORM flag. - StringCchCat(buf, 128, TEXT("(CONTROLF_UNIFORM)")); - } - - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); -} - -// ---------------------------------------------------------------------------- -// ClearSpeakerState I (II) -// ---------------------------------------------------------------------------- - -void AudioMixerManager::ClearSpeakerState(UINT idx) -{ - _speakerState[idx].dwLineID = 0L; - _speakerState[idx].dwVolumeControlID = 0L; - _speakerState[idx].dwMuteControlID = 0L; - _speakerState[idx].speakerIsValid = false; - _speakerState[idx].muteControlIsValid = false; - _speakerState[idx].volumeControlIsValid = false; -} - -// ---------------------------------------------------------------------------- -// ClearSpeakerState II (II) -// ---------------------------------------------------------------------------- - -void AudioMixerManager::ClearSpeakerState() -{ - for (int i = 0; i < MAX_NUMBER_MIXER_DEVICES; i++) - { - ClearSpeakerState(i); - } -} - -// ---------------------------------------------------------------------------- -// SpeakerIsValid -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::SpeakerIsValid(UINT idx) const -{ - return (_speakerState[idx].speakerIsValid); -} - -// ---------------------------------------------------------------------------- -// ValidSpeakers -// -// Counts number of valid speaker destinations for all mixer devices. -// ---------------------------------------------------------------------------- - -UINT AudioMixerManager::ValidSpeakers() const -{ - UINT nSpeakers(0); - for (int i = 0; i < MAX_NUMBER_MIXER_DEVICES; i++) - { - if (SpeakerIsValid(i)) - nSpeakers++; - } - return nSpeakers; -} - -// ---------------------------------------------------------------------------- -// ClearMicrophoneState I (II) -// ---------------------------------------------------------------------------- - -void AudioMixerManager::ClearMicrophoneState(UINT idx) -{ - _microphoneState[idx].dwLineID = 0L; - _microphoneState[idx].dwVolumeControlID = 0L; - _microphoneState[idx].dwMuteControlID = 0L; - _microphoneState[idx].dwOnOffControlID = 0L; - _microphoneState[idx].microphoneIsValid = false; - _microphoneState[idx].muteControlIsValid = false; - _microphoneState[idx].volumeControlIsValid = false; - _microphoneState[idx].onOffControlIsValid = false; -} - -// ---------------------------------------------------------------------------- -// ClearMicrophoneState II (II) -// ---------------------------------------------------------------------------- - -void AudioMixerManager::ClearMicrophoneState() -{ - for (int i = 0; i < MAX_NUMBER_MIXER_DEVICES; i++) - { - ClearMicrophoneState(i); - } -} - -// ---------------------------------------------------------------------------- -// MicrophoneIsValid -// ---------------------------------------------------------------------------- - -bool AudioMixerManager::MicrophoneIsValid(UINT idx) const -{ - return (_microphoneState[idx].microphoneIsValid); - -} - -// ---------------------------------------------------------------------------- -// ValidMicrophones -// -// Counts number of valid speaker destinations for all mixer devices. -// To be valid, a speaker destination line must exist. -// ---------------------------------------------------------------------------- - -UINT AudioMixerManager::ValidMicrophones() const -{ - UINT nMicrophones(0); - for (int i = 0; i < MAX_NUMBER_MIXER_DEVICES; i++) - { - if (MicrophoneIsValid(i)) - nMicrophones++; - } - return nMicrophones; -} - -// ---------------------------------------------------------------------------- -// TraceWaveInError -// ---------------------------------------------------------------------------- - -void AudioMixerManager::TraceWaveInError(MMRESULT error) const -{ - TCHAR buf[MAXERRORLENGTH]; - TCHAR msg[MAXERRORLENGTH]; - - StringCchPrintf(buf, MAXERRORLENGTH, TEXT("Error details: ")); - waveInGetErrorText(error, msg, MAXERRORLENGTH); - StringCchCat(buf, MAXERRORLENGTH, msg); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); -} - -// ---------------------------------------------------------------------------- -// TraceWaveOutError -// ---------------------------------------------------------------------------- - -void AudioMixerManager::TraceWaveOutError(MMRESULT error) const -{ - TCHAR buf[MAXERRORLENGTH]; - TCHAR msg[MAXERRORLENGTH]; - - StringCchPrintf(buf, MAXERRORLENGTH, TEXT("Error details: ")); - waveOutGetErrorText(error, msg, MAXERRORLENGTH); - StringCchCat(buf, MAXERRORLENGTH, msg); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); -} - -// ---------------------------------------------------------------------------- -// WideToUTF8 -// ---------------------------------------------------------------------------- - -char* AudioMixerManager::WideToUTF8(const TCHAR* src) const { -#ifdef UNICODE - const size_t kStrLen = sizeof(_str); - memset(_str, 0, kStrLen); - // Get required size (in bytes) to be able to complete the conversion. - unsigned int required_size = (unsigned int)WideCharToMultiByte(CP_UTF8, 0, src, -1, _str, 0, 0, 0); - if (required_size <= kStrLen) - { - // Process the entire input string, including the terminating null char. - if (WideCharToMultiByte(CP_UTF8, 0, src, -1, _str, kStrLen, 0, 0) == 0) - memset(_str, 0, kStrLen); - } - return _str; -#else - return const_cast(src); -#endif -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_device/win/audio_mixer_manager_win.h b/webrtc/modules/audio_device/win/audio_mixer_manager_win.h deleted file mode 100644 index 1e0ab47ad4..0000000000 --- a/webrtc/modules/audio_device/win/audio_mixer_manager_win.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_AUDIO_DEVICE_AUDIO_MIXER_MANAGER_WIN_H -#define WEBRTC_AUDIO_DEVICE_AUDIO_MIXER_MANAGER_WIN_H - -#include "webrtc/typedefs.h" -#include "webrtc/modules/audio_device/include/audio_device.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include -#include - -namespace webrtc { - -class AudioMixerManager -{ -public: - enum { MAX_NUMBER_MIXER_DEVICES = 40 }; - enum { MAX_NUMBER_OF_LINE_CONTROLS = 20 }; - enum { MAX_NUMBER_OF_MULTIPLE_ITEMS = 20 }; - struct SpeakerLineInfo - { - DWORD dwLineID; - bool speakerIsValid; - DWORD dwVolumeControlID; - bool volumeControlIsValid; - DWORD dwMuteControlID; - bool muteControlIsValid; - }; - struct MicrophoneLineInfo - { - DWORD dwLineID; - bool microphoneIsValid; - DWORD dwVolumeControlID; - bool volumeControlIsValid; - DWORD dwMuteControlID; - bool muteControlIsValid; - DWORD dwOnOffControlID; - bool onOffControlIsValid; - }; -public: - int32_t EnumerateAll(); - int32_t EnumerateSpeakers(); - int32_t EnumerateMicrophones(); - int32_t OpenSpeaker(AudioDeviceModule::WindowsDeviceType device); - int32_t OpenSpeaker(uint16_t index); - int32_t OpenMicrophone(AudioDeviceModule::WindowsDeviceType device); - int32_t OpenMicrophone(uint16_t index); - int32_t SetSpeakerVolume(uint32_t volume); - int32_t SpeakerVolume(uint32_t& volume) const; - int32_t MaxSpeakerVolume(uint32_t& maxVolume) const; - int32_t MinSpeakerVolume(uint32_t& minVolume) const; - int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const; - int32_t SpeakerVolumeIsAvailable(bool& available); - int32_t SpeakerMuteIsAvailable(bool& available); - int32_t SetSpeakerMute(bool enable); - int32_t SpeakerMute(bool& enabled) const; - int32_t MicrophoneMuteIsAvailable(bool& available); - int32_t SetMicrophoneMute(bool enable); - int32_t MicrophoneMute(bool& enabled) const; - int32_t MicrophoneBoostIsAvailable(bool& available); - int32_t SetMicrophoneBoost(bool enable); - int32_t MicrophoneBoost(bool& enabled) const; - int32_t MicrophoneVolumeIsAvailable(bool& available); - int32_t SetMicrophoneVolume(uint32_t volume); - int32_t MicrophoneVolume(uint32_t& volume) const; - int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const; - int32_t MinMicrophoneVolume(uint32_t& minVolume) const; - int32_t MicrophoneVolumeStepSize(uint16_t& stepSize) const; - int32_t Close(); - int32_t CloseSpeaker(); - int32_t CloseMicrophone(); - bool SpeakerIsInitialized() const; - bool MicrophoneIsInitialized() const; - UINT Devices() const; - -private: - UINT DestinationLines(UINT mixId) const; - UINT SourceLines(UINT mixId, DWORD destId) const; - bool GetCapabilities(UINT mixId, MIXERCAPS& caps, bool trace = false) const; - bool GetDestinationLineInfo(UINT mixId, DWORD destId, MIXERLINE& line, bool trace = false) const; - bool GetSourceLineInfo(UINT mixId, DWORD destId, DWORD srcId, MIXERLINE& line, bool trace = false) const; - - bool GetAllLineControls(UINT mixId, const MIXERLINE& line, MIXERCONTROL* controlArray, bool trace = false) const; - bool GetLineControl(UINT mixId, DWORD dwControlID, MIXERCONTROL& control) const; - bool GetControlDetails(UINT mixId, MIXERCONTROL& controlArray, bool trace = false) const; - bool GetUnsignedControlValue(UINT mixId, DWORD dwControlID, DWORD& dwValue) const; - bool SetUnsignedControlValue(UINT mixId, DWORD dwControlID, DWORD dwValue) const; - bool SetBooleanControlValue(UINT mixId, DWORD dwControlID, bool value) const; - bool GetBooleanControlValue(UINT mixId, DWORD dwControlID, bool& value) const; - bool GetSelectedMuxSource(UINT mixId, DWORD dwControlID, DWORD cMultipleItems, UINT& index) const; - -private: - void ClearSpeakerState(); - void ClearSpeakerState(UINT idx); - void ClearMicrophoneState(); - void ClearMicrophoneState(UINT idx); - bool SpeakerIsValid(UINT idx) const; - UINT ValidSpeakers() const; - bool MicrophoneIsValid(UINT idx) const; - UINT ValidMicrophones() const; - - void TraceStatusAndSupportFlags(DWORD fdwLine) const; - void TraceTargetType(DWORD dwType) const; - void TraceComponentType(DWORD dwComponentType) const; - void TraceControlType(DWORD dwControlType) const; - void TraceControlStatusAndSupportFlags(DWORD fdwControl) const; - void TraceWaveInError(MMRESULT error) const; - void TraceWaveOutError(MMRESULT error) const; - // Converts from wide-char to UTF-8 if UNICODE is defined. - // Does nothing if UNICODE is undefined. - char* WideToUTF8(const TCHAR* src) const; - -public: - AudioMixerManager(const int32_t id); - ~AudioMixerManager(); - -private: - CriticalSectionWrapper& _critSect; - int32_t _id; - HMIXER _outputMixerHandle; - UINT _outputMixerID; - HMIXER _inputMixerHandle; - UINT _inputMixerID; - SpeakerLineInfo _speakerState[MAX_NUMBER_MIXER_DEVICES]; - MicrophoneLineInfo _microphoneState[MAX_NUMBER_MIXER_DEVICES]; - mutable char _str[MAXERRORLENGTH]; -}; - -} // namespace webrtc - -#endif // WEBRTC_AUDIO_DEVICE_AUDIO_MIXER_MANAGER_H