Index: webrtc/modules/audio_device/win/audio_mixer_manager_win.cc |
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 ae2d00faeb89ecb899e8dddd7dd63e5fbb5bde53..0000000000000000000000000000000000000000 |
--- 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.h> // assert() |
-#include <strsafe.h> // 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<uint16_t> (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<uint16_t> (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<HMIXEROBJ>(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<HMIXEROBJ>(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<HMIXEROBJ>(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<HMIXEROBJ>(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<HMIXEROBJ>(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<HMIXEROBJ>(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<HMIXEROBJ>(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<HMIXEROBJ>(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<HMIXEROBJ>(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<HMIXEROBJ>(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<char*>(src); |
-#endif |
-} |
- |
-} // namespace webrtc |