| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <assert.h> | 11 #include <assert.h> |
| 12 | 12 |
| 13 #include "webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h" | 13 #include "webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h" |
| 14 #include "webrtc/system_wrappers/include/trace.h" | 14 #include "webrtc/rtc_base/logging.h" |
| 15 | 15 |
| 16 extern webrtc::adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable; | 16 extern webrtc::adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable; |
| 17 | 17 |
| 18 // Accesses ALSA functions through our late-binding symbol table instead of | 18 // Accesses ALSA functions through our late-binding symbol table instead of |
| 19 // directly. This way we don't have to link to libalsa, which means our binary | 19 // directly. This way we don't have to link to libalsa, which means our binary |
| 20 // will work on systems that don't have it. | 20 // will work on systems that don't have it. |
| 21 #define LATE(sym) \ | 21 #define LATE(sym) \ |
| 22 LATESYM_GET(webrtc::adm_linux_alsa::AlsaSymbolTable, &AlsaSymbolTable, sym) | 22 LATESYM_GET(webrtc::adm_linux_alsa::AlsaSymbolTable, &AlsaSymbolTable, sym) |
| 23 | 23 |
| 24 namespace webrtc | 24 namespace webrtc |
| 25 { | 25 { |
| 26 | 26 |
| 27 AudioMixerManagerLinuxALSA::AudioMixerManagerLinuxALSA(const int32_t id) : | 27 AudioMixerManagerLinuxALSA::AudioMixerManagerLinuxALSA() : |
| 28 _id(id), | |
| 29 _outputMixerHandle(NULL), | 28 _outputMixerHandle(NULL), |
| 30 _inputMixerHandle(NULL), | 29 _inputMixerHandle(NULL), |
| 31 _outputMixerElement(NULL), | 30 _outputMixerElement(NULL), |
| 32 _inputMixerElement(NULL) | 31 _inputMixerElement(NULL) |
| 33 { | 32 { |
| 34 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, | 33 LOG(LS_INFO) << __FUNCTION__ << " created"; |
| 35 "%s constructed", __FUNCTION__); | |
| 36 | 34 |
| 37 memset(_outputMixerStr, 0, kAdmMaxDeviceNameSize); | 35 memset(_outputMixerStr, 0, kAdmMaxDeviceNameSize); |
| 38 memset(_inputMixerStr, 0, kAdmMaxDeviceNameSize); | 36 memset(_inputMixerStr, 0, kAdmMaxDeviceNameSize); |
| 39 } | 37 } |
| 40 | 38 |
| 41 AudioMixerManagerLinuxALSA::~AudioMixerManagerLinuxALSA() | 39 AudioMixerManagerLinuxALSA::~AudioMixerManagerLinuxALSA() |
| 42 { | 40 { |
| 43 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, | 41 LOG(LS_INFO) << __FUNCTION__ << " destroyed"; |
| 44 "%s destructed", __FUNCTION__); | |
| 45 Close(); | 42 Close(); |
| 46 } | 43 } |
| 47 | 44 |
| 48 // ============================================================================ | 45 // ============================================================================ |
| 49 // PUBLIC METHODS | 46 // PUBLIC METHODS |
| 50 // ============================================================================ | 47 // ============================================================================ |
| 51 | 48 |
| 52 int32_t AudioMixerManagerLinuxALSA::Close() | 49 int32_t AudioMixerManagerLinuxALSA::Close() |
| 53 { | 50 { |
| 54 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", | 51 LOG(LS_VERBOSE) << __FUNCTION__; |
| 55 __FUNCTION__); | |
| 56 | 52 |
| 57 rtc::CritScope lock(&_critSect); | 53 rtc::CritScope lock(&_critSect); |
| 58 | 54 |
| 59 CloseSpeaker(); | 55 CloseSpeaker(); |
| 60 CloseMicrophone(); | 56 CloseMicrophone(); |
| 61 | 57 |
| 62 return 0; | 58 return 0; |
| 63 | 59 |
| 64 } | 60 } |
| 65 | 61 |
| 66 int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() | 62 int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() |
| 67 { | 63 { |
| 68 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", | 64 LOG(LS_VERBOSE) << __FUNCTION__; |
| 69 __FUNCTION__); | |
| 70 | 65 |
| 71 rtc::CritScope lock(&_critSect); | 66 rtc::CritScope lock(&_critSect); |
| 72 | 67 |
| 73 int errVal = 0; | 68 int errVal = 0; |
| 74 | 69 |
| 75 if (_outputMixerHandle != NULL) | 70 if (_outputMixerHandle != NULL) |
| 76 { | 71 { |
| 77 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 72 LOG(LS_VERBOSE) << "Closing playout mixer"; |
| 78 "Closing playout mixer"); | |
| 79 LATE(snd_mixer_free)(_outputMixerHandle); | 73 LATE(snd_mixer_free)(_outputMixerHandle); |
| 80 if (errVal < 0) | 74 if (errVal < 0) |
| 81 { | 75 { |
| 82 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 76 LOG(LS_ERROR) << "Error freeing playout mixer: " |
| 83 " Error freeing playout mixer: %s", | 77 << LATE(snd_strerror)(errVal); |
| 84 LATE(snd_strerror)(errVal)); | |
| 85 } | 78 } |
| 86 errVal = LATE(snd_mixer_detach)(_outputMixerHandle, _outputMixerStr); | 79 errVal = LATE(snd_mixer_detach)(_outputMixerHandle, _outputMixerStr); |
| 87 if (errVal < 0) | 80 if (errVal < 0) |
| 88 { | 81 { |
| 89 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 82 LOG(LS_ERROR) << "Error detaching playout mixer: " |
| 90 " Error detachinging playout mixer: %s", | 83 << LATE(snd_strerror)(errVal); |
| 91 LATE(snd_strerror)(errVal)); | |
| 92 } | 84 } |
| 93 errVal = LATE(snd_mixer_close)(_outputMixerHandle); | 85 errVal = LATE(snd_mixer_close)(_outputMixerHandle); |
| 94 if (errVal < 0) | 86 if (errVal < 0) |
| 95 { | 87 { |
| 96 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 88 LOG(LS_ERROR) << "Error snd_mixer_close(handleMixer) errVal=" |
| 97 " Error snd_mixer_close(handleMixer) errVal=%d", | 89 << errVal; |
| 98 errVal); | |
| 99 } | 90 } |
| 100 _outputMixerHandle = NULL; | 91 _outputMixerHandle = NULL; |
| 101 _outputMixerElement = NULL; | 92 _outputMixerElement = NULL; |
| 102 } | 93 } |
| 103 memset(_outputMixerStr, 0, kAdmMaxDeviceNameSize); | 94 memset(_outputMixerStr, 0, kAdmMaxDeviceNameSize); |
| 104 | 95 |
| 105 return 0; | 96 return 0; |
| 106 } | 97 } |
| 107 | 98 |
| 108 int32_t AudioMixerManagerLinuxALSA::CloseMicrophone() | 99 int32_t AudioMixerManagerLinuxALSA::CloseMicrophone() |
| 109 { | 100 { |
| 110 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); | 101 LOG(LS_VERBOSE) << __FUNCTION__; |
| 111 | 102 |
| 112 rtc::CritScope lock(&_critSect); | 103 rtc::CritScope lock(&_critSect); |
| 113 | 104 |
| 114 int errVal = 0; | 105 int errVal = 0; |
| 115 | 106 |
| 116 if (_inputMixerHandle != NULL) | 107 if (_inputMixerHandle != NULL) |
| 117 { | 108 { |
| 118 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 109 LOG(LS_VERBOSE) << "Closing record mixer"; |
| 119 "Closing record mixer"); | |
| 120 | 110 |
| 121 LATE(snd_mixer_free)(_inputMixerHandle); | 111 LATE(snd_mixer_free)(_inputMixerHandle); |
| 122 if (errVal < 0) | 112 if (errVal < 0) |
| 123 { | 113 { |
| 124 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 114 LOG(LS_ERROR) << "Error freeing record mixer: " |
| 125 " Error freeing record mixer: %s", | 115 << LATE(snd_strerror)(errVal); |
| 126 LATE(snd_strerror)(errVal)); | |
| 127 } | 116 } |
| 128 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 117 LOG(LS_VERBOSE) << "Closing record mixer 2"; |
| 129 "Closing record mixer 2"); | |
| 130 | 118 |
| 131 errVal = LATE(snd_mixer_detach)(_inputMixerHandle, _inputMixerStr); | 119 errVal = LATE(snd_mixer_detach)(_inputMixerHandle, _inputMixerStr); |
| 132 if (errVal < 0) | 120 if (errVal < 0) |
| 133 { | 121 { |
| 134 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 122 LOG(LS_ERROR) << "Error detaching record mixer: " |
| 135 " Error detachinging record mixer: %s", | 123 << LATE(snd_strerror)(errVal); |
| 136 LATE(snd_strerror)(errVal)); | |
| 137 } | 124 } |
| 138 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 125 LOG(LS_VERBOSE) << "Closing record mixer 3"; |
| 139 "Closing record mixer 3"); | |
| 140 | 126 |
| 141 errVal = LATE(snd_mixer_close)(_inputMixerHandle); | 127 errVal = LATE(snd_mixer_close)(_inputMixerHandle); |
| 142 if (errVal < 0) | 128 if (errVal < 0) |
| 143 { | 129 { |
| 144 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 130 LOG(LS_ERROR) << "Error snd_mixer_close(handleMixer) errVal=" |
| 145 " Error snd_mixer_close(handleMixer) errVal=%d", | 131 << errVal; |
| 146 errVal); | |
| 147 } | 132 } |
| 148 | 133 |
| 149 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 134 LOG(LS_VERBOSE) << "Closing record mixer 4"; |
| 150 "Closing record mixer 4"); | |
| 151 _inputMixerHandle = NULL; | 135 _inputMixerHandle = NULL; |
| 152 _inputMixerElement = NULL; | 136 _inputMixerElement = NULL; |
| 153 } | 137 } |
| 154 memset(_inputMixerStr, 0, kAdmMaxDeviceNameSize); | 138 memset(_inputMixerStr, 0, kAdmMaxDeviceNameSize); |
| 155 | 139 |
| 156 return 0; | 140 return 0; |
| 157 } | 141 } |
| 158 | 142 |
| 159 int32_t AudioMixerManagerLinuxALSA::OpenSpeaker(char* deviceName) | 143 int32_t AudioMixerManagerLinuxALSA::OpenSpeaker(char* deviceName) |
| 160 { | 144 { |
| 161 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 145 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::OpenSpeaker(name=" |
| 162 "AudioMixerManagerLinuxALSA::OpenSpeaker(name=%s)", deviceName)
; | 146 << deviceName << ")"; |
| 163 | 147 |
| 164 rtc::CritScope lock(&_critSect); | 148 rtc::CritScope lock(&_critSect); |
| 165 | 149 |
| 166 int errVal = 0; | 150 int errVal = 0; |
| 167 | 151 |
| 168 // Close any existing output mixer handle | 152 // Close any existing output mixer handle |
| 169 // | 153 // |
| 170 if (_outputMixerHandle != NULL) | 154 if (_outputMixerHandle != NULL) |
| 171 { | 155 { |
| 172 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 156 LOG(LS_VERBOSE) << "Closing playout mixer"; |
| 173 "Closing playout mixer"); | |
| 174 | 157 |
| 175 LATE(snd_mixer_free)(_outputMixerHandle); | 158 LATE(snd_mixer_free)(_outputMixerHandle); |
| 176 if (errVal < 0) | 159 if (errVal < 0) |
| 177 { | 160 { |
| 178 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 161 LOG(LS_ERROR) << "Error freeing playout mixer: " |
| 179 " Error freeing playout mixer: %s", | 162 << LATE(snd_strerror)(errVal); |
| 180 LATE(snd_strerror)(errVal)); | |
| 181 } | 163 } |
| 182 errVal = LATE(snd_mixer_detach)(_outputMixerHandle, _outputMixerStr); | 164 errVal = LATE(snd_mixer_detach)(_outputMixerHandle, _outputMixerStr); |
| 183 if (errVal < 0) | 165 if (errVal < 0) |
| 184 { | 166 { |
| 185 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 167 LOG(LS_ERROR) << "Error detaching playout mixer: " |
| 186 " Error detachinging playout mixer: %s", | 168 << LATE(snd_strerror)(errVal); |
| 187 LATE(snd_strerror)(errVal)); | |
| 188 } | 169 } |
| 189 errVal = LATE(snd_mixer_close)(_outputMixerHandle); | 170 errVal = LATE(snd_mixer_close)(_outputMixerHandle); |
| 190 if (errVal < 0) | 171 if (errVal < 0) |
| 191 { | 172 { |
| 192 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 173 LOG(LS_ERROR) << "Error snd_mixer_close(handleMixer) errVal=" |
| 193 " Error snd_mixer_close(handleMixer) errVal=%d", | 174 << errVal; |
| 194 errVal); | |
| 195 } | 175 } |
| 196 } | 176 } |
| 197 _outputMixerHandle = NULL; | 177 _outputMixerHandle = NULL; |
| 198 _outputMixerElement = NULL; | 178 _outputMixerElement = NULL; |
| 199 | 179 |
| 200 errVal = LATE(snd_mixer_open)(&_outputMixerHandle, 0); | 180 errVal = LATE(snd_mixer_open)(&_outputMixerHandle, 0); |
| 201 if (errVal < 0) | 181 if (errVal < 0) |
| 202 { | 182 { |
| 203 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 183 LOG(LS_ERROR) << "snd_mixer_open(&_outputMixerHandle, 0) - error"; |
| 204 "snd_mixer_open(&_outputMixerHandle, 0) - error"); | |
| 205 return -1; | 184 return -1; |
| 206 } | 185 } |
| 207 | 186 |
| 208 char controlName[kAdmMaxDeviceNameSize] = { 0 }; | 187 char controlName[kAdmMaxDeviceNameSize] = { 0 }; |
| 209 GetControlName(controlName, deviceName); | 188 GetControlName(controlName, deviceName); |
| 210 | 189 |
| 211 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 190 LOG(LS_VERBOSE) << "snd_mixer_attach(_outputMixerHandle, " << controlName |
| 212 " snd_mixer_attach(_outputMixerHandle, %s)", controlName); | 191 << ")"; |
| 213 | 192 |
| 214 errVal = LATE(snd_mixer_attach)(_outputMixerHandle, controlName); | 193 errVal = LATE(snd_mixer_attach)(_outputMixerHandle, controlName); |
| 215 if (errVal < 0) | 194 if (errVal < 0) |
| 216 { | 195 { |
| 217 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 196 LOG(LS_ERROR) << "snd_mixer_attach(_outputMixerHandle, " << controlName |
| 218 " snd_mixer_attach(_outputMixerHandle, %s) error: %s", | 197 << ") error: " << LATE(snd_strerror)(errVal); |
| 219 controlName, LATE(snd_strerror)(errVal)); | |
| 220 _outputMixerHandle = NULL; | 198 _outputMixerHandle = NULL; |
| 221 return -1; | 199 return -1; |
| 222 } | 200 } |
| 223 strcpy(_outputMixerStr, controlName); | 201 strcpy(_outputMixerStr, controlName); |
| 224 | 202 |
| 225 errVal = LATE(snd_mixer_selem_register)(_outputMixerHandle, NULL, NULL); | 203 errVal = LATE(snd_mixer_selem_register)(_outputMixerHandle, NULL, NULL); |
| 226 if (errVal < 0) | 204 if (errVal < 0) |
| 227 { | 205 { |
| 228 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 206 LOG(LS_ERROR) |
| 229 " snd_mixer_selem_register(_outputMixerHandle," | 207 << "snd_mixer_selem_register(_outputMixerHandle, NULL, NULL), " |
| 230 " NULL, NULL), error: %s", | 208 << "error: " << LATE(snd_strerror)(errVal); |
| 231 LATE(snd_strerror)(errVal)); | |
| 232 _outputMixerHandle = NULL; | 209 _outputMixerHandle = NULL; |
| 233 return -1; | 210 return -1; |
| 234 } | 211 } |
| 235 | 212 |
| 236 // Load and find the proper mixer element | 213 // Load and find the proper mixer element |
| 237 if (LoadSpeakerMixerElement() < 0) | 214 if (LoadSpeakerMixerElement() < 0) |
| 238 { | 215 { |
| 239 return -1; | 216 return -1; |
| 240 } | 217 } |
| 241 | 218 |
| 242 if (_outputMixerHandle != NULL) | 219 if (_outputMixerHandle != NULL) |
| 243 { | 220 { |
| 244 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 221 LOG(LS_VERBOSE) << "the output mixer device is now open (" |
| 245 " the output mixer device is now open (0x%x)", | 222 << _outputMixerHandle << ")"; |
| 246 _outputMixerHandle); | |
| 247 } | 223 } |
| 248 | 224 |
| 249 return 0; | 225 return 0; |
| 250 } | 226 } |
| 251 | 227 |
| 252 int32_t AudioMixerManagerLinuxALSA::OpenMicrophone(char *deviceName) | 228 int32_t AudioMixerManagerLinuxALSA::OpenMicrophone(char *deviceName) |
| 253 { | 229 { |
| 254 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 230 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::OpenMicrophone(name=" |
| 255 "AudioMixerManagerLinuxALSA::OpenMicrophone(name=%s)", | 231 << deviceName << ")"; |
| 256 deviceName); | |
| 257 | 232 |
| 258 rtc::CritScope lock(&_critSect); | 233 rtc::CritScope lock(&_critSect); |
| 259 | 234 |
| 260 int errVal = 0; | 235 int errVal = 0; |
| 261 | 236 |
| 262 // Close any existing input mixer handle | 237 // Close any existing input mixer handle |
| 263 // | 238 // |
| 264 if (_inputMixerHandle != NULL) | 239 if (_inputMixerHandle != NULL) |
| 265 { | 240 { |
| 266 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 241 LOG(LS_VERBOSE) << "Closing record mixer"; |
| 267 "Closing record mixer"); | |
| 268 | 242 |
| 269 LATE(snd_mixer_free)(_inputMixerHandle); | 243 LATE(snd_mixer_free)(_inputMixerHandle); |
| 270 if (errVal < 0) | 244 if (errVal < 0) |
| 271 { | 245 { |
| 272 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 246 LOG(LS_ERROR) << "Error freeing record mixer: " |
| 273 " Error freeing record mixer: %s", | 247 << LATE(snd_strerror)(errVal); |
| 274 LATE(snd_strerror)(errVal)); | |
| 275 } | 248 } |
| 276 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 249 LOG(LS_VERBOSE) << "Closing record mixer"; |
| 277 "Closing record mixer"); | |
| 278 | 250 |
| 279 errVal = LATE(snd_mixer_detach)(_inputMixerHandle, _inputMixerStr); | 251 errVal = LATE(snd_mixer_detach)(_inputMixerHandle, _inputMixerStr); |
| 280 if (errVal < 0) | 252 if (errVal < 0) |
| 281 { | 253 { |
| 282 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 254 LOG(LS_ERROR) << "Error detaching record mixer: " |
| 283 " Error detachinging record mixer: %s", | 255 << LATE(snd_strerror)(errVal); |
| 284 LATE(snd_strerror)(errVal)); | |
| 285 } | 256 } |
| 286 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 257 LOG(LS_VERBOSE) << "Closing record mixer"; |
| 287 "Closing record mixer"); | |
| 288 | 258 |
| 289 errVal = LATE(snd_mixer_close)(_inputMixerHandle); | 259 errVal = LATE(snd_mixer_close)(_inputMixerHandle); |
| 290 if (errVal < 0) | 260 if (errVal < 0) |
| 291 { | 261 { |
| 292 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 262 LOG(LS_ERROR) << "Error snd_mixer_close(handleMixer) errVal=" |
| 293 " Error snd_mixer_close(handleMixer) errVal=%d", | 263 << errVal; |
| 294 errVal); | |
| 295 } | 264 } |
| 296 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 265 LOG(LS_VERBOSE) << "Closing record mixer"; |
| 297 "Closing record mixer"); | |
| 298 } | 266 } |
| 299 _inputMixerHandle = NULL; | 267 _inputMixerHandle = NULL; |
| 300 _inputMixerElement = NULL; | 268 _inputMixerElement = NULL; |
| 301 | 269 |
| 302 errVal = LATE(snd_mixer_open)(&_inputMixerHandle, 0); | 270 errVal = LATE(snd_mixer_open)(&_inputMixerHandle, 0); |
| 303 if (errVal < 0) | 271 if (errVal < 0) |
| 304 { | 272 { |
| 305 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 273 LOG(LS_ERROR) << "snd_mixer_open(&_inputMixerHandle, 0) - error"; |
| 306 " snd_mixer_open(&_inputMixerHandle, 0) - error"); | |
| 307 return -1; | 274 return -1; |
| 308 } | 275 } |
| 309 | 276 |
| 310 char controlName[kAdmMaxDeviceNameSize] = { 0 }; | 277 char controlName[kAdmMaxDeviceNameSize] = { 0 }; |
| 311 GetControlName(controlName, deviceName); | 278 GetControlName(controlName, deviceName); |
| 312 | 279 |
| 313 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 280 LOG(LS_VERBOSE) << "snd_mixer_attach(_inputMixerHandle, " << controlName |
| 314 " snd_mixer_attach(_inputMixerHandle, %s)", controlName); | 281 << ")"; |
| 315 | 282 |
| 316 errVal = LATE(snd_mixer_attach)(_inputMixerHandle, controlName); | 283 errVal = LATE(snd_mixer_attach)(_inputMixerHandle, controlName); |
| 317 if (errVal < 0) | 284 if (errVal < 0) |
| 318 { | 285 { |
| 319 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 286 LOG(LS_ERROR) << "snd_mixer_attach(_inputMixerHandle, " << controlName |
| 320 " snd_mixer_attach(_inputMixerHandle, %s) error: %s", | 287 << ") error: " << LATE(snd_strerror)(errVal); |
| 321 controlName, LATE(snd_strerror)(errVal)); | |
| 322 | 288 |
| 323 _inputMixerHandle = NULL; | 289 _inputMixerHandle = NULL; |
| 324 return -1; | 290 return -1; |
| 325 } | 291 } |
| 326 strcpy(_inputMixerStr, controlName); | 292 strcpy(_inputMixerStr, controlName); |
| 327 | 293 |
| 328 errVal = LATE(snd_mixer_selem_register)(_inputMixerHandle, NULL, NULL); | 294 errVal = LATE(snd_mixer_selem_register)(_inputMixerHandle, NULL, NULL); |
| 329 if (errVal < 0) | 295 if (errVal < 0) |
| 330 { | 296 { |
| 331 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 297 LOG(LS_ERROR) |
| 332 " snd_mixer_selem_register(_inputMixerHandle," | 298 << "snd_mixer_selem_register(_inputMixerHandle, NULL, NULL), " |
| 333 " NULL, NULL), error: %s", | 299 << "error: " << LATE(snd_strerror)(errVal); |
| 334 LATE(snd_strerror)(errVal)); | |
| 335 | 300 |
| 336 _inputMixerHandle = NULL; | 301 _inputMixerHandle = NULL; |
| 337 return -1; | 302 return -1; |
| 338 } | 303 } |
| 339 // Load and find the proper mixer element | 304 // Load and find the proper mixer element |
| 340 if (LoadMicMixerElement() < 0) | 305 if (LoadMicMixerElement() < 0) |
| 341 { | 306 { |
| 342 return -1; | 307 return -1; |
| 343 } | 308 } |
| 344 | 309 |
| 345 if (_inputMixerHandle != NULL) | 310 if (_inputMixerHandle != NULL) |
| 346 { | 311 { |
| 347 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 312 LOG(LS_VERBOSE) << "the input mixer device is now open (" |
| 348 " the input mixer device is now open (0x%x)", | 313 << _inputMixerHandle << ")"; |
| 349 _inputMixerHandle); | |
| 350 } | 314 } |
| 351 | 315 |
| 352 return 0; | 316 return 0; |
| 353 } | 317 } |
| 354 | 318 |
| 355 bool AudioMixerManagerLinuxALSA::SpeakerIsInitialized() const | 319 bool AudioMixerManagerLinuxALSA::SpeakerIsInitialized() const |
| 356 { | 320 { |
| 357 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__); | 321 LOG(LS_INFO) << __FUNCTION__; |
| 358 | 322 |
| 359 return (_outputMixerHandle != NULL); | 323 return (_outputMixerHandle != NULL); |
| 360 } | 324 } |
| 361 | 325 |
| 362 bool AudioMixerManagerLinuxALSA::MicrophoneIsInitialized() const | 326 bool AudioMixerManagerLinuxALSA::MicrophoneIsInitialized() const |
| 363 { | 327 { |
| 364 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", | 328 LOG(LS_INFO) << __FUNCTION__; |
| 365 __FUNCTION__); | |
| 366 | 329 |
| 367 return (_inputMixerHandle != NULL); | 330 return (_inputMixerHandle != NULL); |
| 368 } | 331 } |
| 369 | 332 |
| 370 int32_t AudioMixerManagerLinuxALSA::SetSpeakerVolume( | 333 int32_t AudioMixerManagerLinuxALSA::SetSpeakerVolume( |
| 371 uint32_t volume) | 334 uint32_t volume) |
| 372 { | 335 { |
| 373 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 336 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::SetSpeakerVolume(volume=" |
| 374 "AudioMixerManagerLinuxALSA::SetSpeakerVolume(volume=%u)", | 337 << volume << ")"; |
| 375 volume); | |
| 376 | 338 |
| 377 rtc::CritScope lock(&_critSect); | 339 rtc::CritScope lock(&_critSect); |
| 378 | 340 |
| 379 if (_outputMixerElement == NULL) | 341 if (_outputMixerElement == NULL) |
| 380 { | 342 { |
| 381 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 343 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 382 " no avaliable output mixer element exists"); | |
| 383 return -1; | 344 return -1; |
| 384 } | 345 } |
| 385 | 346 |
| 386 int errVal = | 347 int errVal = |
| 387 LATE(snd_mixer_selem_set_playback_volume_all)(_outputMixerElement, | 348 LATE(snd_mixer_selem_set_playback_volume_all)(_outputMixerElement, |
| 388 volume); | 349 volume); |
| 389 if (errVal < 0) | 350 if (errVal < 0) |
| 390 { | 351 { |
| 391 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 352 LOG(LS_ERROR) << "Error changing master volume: " |
| 392 " Error changing master volume: %s", | 353 << LATE(snd_strerror)(errVal); |
| 393 LATE(snd_strerror)(errVal)); | |
| 394 return -1; | 354 return -1; |
| 395 } | 355 } |
| 396 | 356 |
| 397 return (0); | 357 return (0); |
| 398 } | 358 } |
| 399 | 359 |
| 400 int32_t AudioMixerManagerLinuxALSA::SpeakerVolume( | 360 int32_t AudioMixerManagerLinuxALSA::SpeakerVolume( |
| 401 uint32_t& volume) const | 361 uint32_t& volume) const |
| 402 { | 362 { |
| 403 | 363 |
| 404 if (_outputMixerElement == NULL) | 364 if (_outputMixerElement == NULL) |
| 405 { | 365 { |
| 406 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 366 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 407 " no avaliable output mixer element exists"); | |
| 408 return -1; | 367 return -1; |
| 409 } | 368 } |
| 410 | 369 |
| 411 long int vol(0); | 370 long int vol(0); |
| 412 | 371 |
| 413 int | 372 int |
| 414 errVal = LATE(snd_mixer_selem_get_playback_volume)( | 373 errVal = LATE(snd_mixer_selem_get_playback_volume)( |
| 415 _outputMixerElement, | 374 _outputMixerElement, |
| 416 (snd_mixer_selem_channel_id_t) 0, | 375 (snd_mixer_selem_channel_id_t) 0, |
| 417 &vol); | 376 &vol); |
| 418 if (errVal < 0) | 377 if (errVal < 0) |
| 419 { | 378 { |
| 420 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 379 LOG(LS_ERROR) << "Error getting outputvolume: " |
| 421 "Error getting outputvolume: %s", | 380 << LATE(snd_strerror)(errVal); |
| 422 LATE(snd_strerror)(errVal)); | |
| 423 return -1; | 381 return -1; |
| 424 } | 382 } |
| 425 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 383 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::SpeakerVolume() => vol=" |
| 426 " AudioMixerManagerLinuxALSA::SpeakerVolume() => vol=%i", | 384 << vol; |
| 427 vol); | |
| 428 | 385 |
| 429 volume = static_cast<uint32_t> (vol); | 386 volume = static_cast<uint32_t> (vol); |
| 430 | 387 |
| 431 return 0; | 388 return 0; |
| 432 } | 389 } |
| 433 | 390 |
| 434 int32_t AudioMixerManagerLinuxALSA::MaxSpeakerVolume( | 391 int32_t AudioMixerManagerLinuxALSA::MaxSpeakerVolume( |
| 435 uint32_t& maxVolume) const | 392 uint32_t& maxVolume) const |
| 436 { | 393 { |
| 437 | 394 |
| 438 if (_outputMixerElement == NULL) | 395 if (_outputMixerElement == NULL) |
| 439 { | 396 { |
| 440 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 397 LOG(LS_WARNING) << "no avilable output mixer element exists"; |
| 441 " no avilable output mixer element exists"); | |
| 442 return -1; | 398 return -1; |
| 443 } | 399 } |
| 444 | 400 |
| 445 long int minVol(0); | 401 long int minVol(0); |
| 446 long int maxVol(0); | 402 long int maxVol(0); |
| 447 | 403 |
| 448 int errVal = | 404 int errVal = |
| 449 LATE(snd_mixer_selem_get_playback_volume_range)(_outputMixerElement, | 405 LATE(snd_mixer_selem_get_playback_volume_range)(_outputMixerElement, |
| 450 &minVol, &maxVol); | 406 &minVol, &maxVol); |
| 451 | 407 |
| 452 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 408 LOG(LS_VERBOSE) << "Playout hardware volume range, min: " << minVol |
| 453 " Playout hardware volume range, min: %d, max: %d", | 409 << ", max: " << maxVol; |
| 454 minVol, maxVol); | |
| 455 | 410 |
| 456 if (maxVol <= minVol) | 411 if (maxVol <= minVol) |
| 457 { | 412 { |
| 458 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 413 LOG(LS_ERROR) << "Error getting get_playback_volume_range: " |
| 459 " Error getting get_playback_volume_range: %s", | 414 << LATE(snd_strerror)(errVal); |
| 460 LATE(snd_strerror)(errVal)); | |
| 461 } | 415 } |
| 462 | 416 |
| 463 maxVolume = static_cast<uint32_t> (maxVol); | 417 maxVolume = static_cast<uint32_t> (maxVol); |
| 464 | 418 |
| 465 return 0; | 419 return 0; |
| 466 } | 420 } |
| 467 | 421 |
| 468 int32_t AudioMixerManagerLinuxALSA::MinSpeakerVolume( | 422 int32_t AudioMixerManagerLinuxALSA::MinSpeakerVolume( |
| 469 uint32_t& minVolume) const | 423 uint32_t& minVolume) const |
| 470 { | 424 { |
| 471 | 425 |
| 472 if (_outputMixerElement == NULL) | 426 if (_outputMixerElement == NULL) |
| 473 { | 427 { |
| 474 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 428 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 475 " no avaliable output mixer element exists"); | |
| 476 return -1; | 429 return -1; |
| 477 } | 430 } |
| 478 | 431 |
| 479 long int minVol(0); | 432 long int minVol(0); |
| 480 long int maxVol(0); | 433 long int maxVol(0); |
| 481 | 434 |
| 482 int errVal = | 435 int errVal = |
| 483 LATE(snd_mixer_selem_get_playback_volume_range)(_outputMixerElement, | 436 LATE(snd_mixer_selem_get_playback_volume_range)(_outputMixerElement, |
| 484 &minVol, &maxVol); | 437 &minVol, &maxVol); |
| 485 | 438 |
| 486 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 439 LOG(LS_VERBOSE) << "Playout hardware volume range, min: " << minVol |
| 487 " Playout hardware volume range, min: %d, max: %d", | 440 << ", max: " << maxVol; |
| 488 minVol, maxVol); | |
| 489 | 441 |
| 490 if (maxVol <= minVol) | 442 if (maxVol <= minVol) |
| 491 { | 443 { |
| 492 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 444 LOG(LS_ERROR) << "Error getting get_playback_volume_range: " |
| 493 " Error getting get_playback_volume_range: %s", | 445 << LATE(snd_strerror)(errVal); |
| 494 LATE(snd_strerror)(errVal)); | |
| 495 } | 446 } |
| 496 | 447 |
| 497 minVolume = static_cast<uint32_t> (minVol); | 448 minVolume = static_cast<uint32_t> (minVol); |
| 498 | 449 |
| 499 return 0; | 450 return 0; |
| 500 } | 451 } |
| 501 | 452 |
| 502 // TL: Have done testnig with these but they don't seem reliable and | 453 // TL: Have done testnig with these but they don't seem reliable and |
| 503 // they were therefore not added | 454 // they were therefore not added |
| 504 /* | 455 /* |
| 505 // ---------------------------------------------------------------------------- | 456 // ---------------------------------------------------------------------------- |
| 506 // SetMaxSpeakerVolume | 457 // SetMaxSpeakerVolume |
| 507 // ---------------------------------------------------------------------------- | 458 // ---------------------------------------------------------------------------- |
| 508 | 459 |
| 509 int32_t AudioMixerManagerLinuxALSA::SetMaxSpeakerVolume( | 460 int32_t AudioMixerManagerLinuxALSA::SetMaxSpeakerVolume( |
| 510 uint32_t maxVolume) | 461 uint32_t maxVolume) |
| 511 { | 462 { |
| 512 | 463 |
| 513 if (_outputMixerElement == NULL) | 464 if (_outputMixerElement == NULL) |
| 514 { | 465 { |
| 515 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 466 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 516 " no avaliable output mixer element exists"); | |
| 517 return -1; | 467 return -1; |
| 518 } | 468 } |
| 519 | 469 |
| 520 long int minVol(0); | 470 long int minVol(0); |
| 521 long int maxVol(0); | 471 long int maxVol(0); |
| 522 | 472 |
| 523 int errVal = snd_mixer_selem_get_playback_volume_range( | 473 int errVal = snd_mixer_selem_get_playback_volume_range( |
| 524 _outputMixerElement, &minVol, &maxVol); | 474 _outputMixerElement, &minVol, &maxVol); |
| 525 if ((maxVol <= minVol) || (errVal != 0)) | 475 if ((maxVol <= minVol) || (errVal != 0)) |
| 526 { | 476 { |
| 527 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 477 LOG(LS_WARNING) << "Error getting playback volume range: " |
| 528 " Error getting playback volume range: %s", snd_strerror(errVal)); | 478 << snd_strerror(errVal); |
| 529 } | 479 } |
| 530 | 480 |
| 531 maxVol = maxVolume; | 481 maxVol = maxVolume; |
| 532 errVal = snd_mixer_selem_set_playback_volume_range( | 482 errVal = snd_mixer_selem_set_playback_volume_range( |
| 533 _outputMixerElement, minVol, maxVol); | 483 _outputMixerElement, minVol, maxVol); |
| 534 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 484 LOG(LS_VERBOSE) << "Playout hardware volume range, min: " << minVol |
| 535 " Playout hardware volume range, min: %d, max: %d", minVol, maxVol); | 485 << ", max: " << maxVol; |
| 536 if (errVal != 0) | 486 if (errVal != 0) |
| 537 { | 487 { |
| 538 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 488 LOG(LS_ERROR) << "Error setting playback volume range: " |
| 539 " Error setting playback volume range: %s", snd_strerror(errVal)); | 489 << snd_strerror(errVal); |
| 540 return -1; | 490 return -1; |
| 541 } | 491 } |
| 542 | 492 |
| 543 return 0; | 493 return 0; |
| 544 } | 494 } |
| 545 | 495 |
| 546 // ---------------------------------------------------------------------------- | 496 // ---------------------------------------------------------------------------- |
| 547 // SetMinSpeakerVolume | 497 // SetMinSpeakerVolume |
| 548 // ---------------------------------------------------------------------------- | 498 // ---------------------------------------------------------------------------- |
| 549 | 499 |
| 550 int32_t AudioMixerManagerLinuxALSA::SetMinSpeakerVolume( | 500 int32_t AudioMixerManagerLinuxALSA::SetMinSpeakerVolume( |
| 551 uint32_t minVolume) | 501 uint32_t minVolume) |
| 552 { | 502 { |
| 553 | 503 |
| 554 if (_outputMixerElement == NULL) | 504 if (_outputMixerElement == NULL) |
| 555 { | 505 { |
| 556 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 506 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 557 " no avaliable output mixer element exists"); | |
| 558 return -1; | 507 return -1; |
| 559 } | 508 } |
| 560 | 509 |
| 561 long int minVol(0); | 510 long int minVol(0); |
| 562 long int maxVol(0); | 511 long int maxVol(0); |
| 563 | 512 |
| 564 int errVal = snd_mixer_selem_get_playback_volume_range( | 513 int errVal = snd_mixer_selem_get_playback_volume_range( |
| 565 _outputMixerElement, &minVol, &maxVol); | 514 _outputMixerElement, &minVol, &maxVol); |
| 566 if ((maxVol <= minVol) || (errVal != 0)) | 515 if ((maxVol <= minVol) || (errVal != 0)) |
| 567 { | 516 { |
| 568 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 517 LOG(LS_WARNING) << "Error getting playback volume range: " |
| 569 " Error getting playback volume range: %s", snd_strerror(errVal)); | 518 << snd_strerror(errVal); |
| 570 } | 519 } |
| 571 | 520 |
| 572 minVol = minVolume; | 521 minVol = minVolume; |
| 573 errVal = snd_mixer_selem_set_playback_volume_range( | 522 errVal = snd_mixer_selem_set_playback_volume_range( |
| 574 _outputMixerElement, minVol, maxVol); | 523 _outputMixerElement, minVol, maxVol); |
| 575 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 524 LOG(LS_VERBOSE) << "Playout hardware volume range, min: " << minVol |
| 576 " Playout hardware volume range, min: %d, max: %d", minVol, maxVol); | 525 << ", max: " << maxVol; |
| 577 if (errVal != 0) | 526 if (errVal != 0) |
| 578 { | 527 { |
| 579 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 528 LOG(LS_ERROR) << "Error setting playback volume range: " |
| 580 " Error setting playback volume range: %s", snd_strerror(errVal)); | 529 << snd_strerror(errVal); |
| 581 return -1; | 530 return -1; |
| 582 } | 531 } |
| 583 | 532 |
| 584 return 0; | 533 return 0; |
| 585 } | 534 } |
| 586 */ | 535 */ |
| 587 | 536 |
| 588 int32_t AudioMixerManagerLinuxALSA::SpeakerVolumeStepSize( | 537 int32_t AudioMixerManagerLinuxALSA::SpeakerVolumeStepSize( |
| 589 uint16_t& stepSize) const | 538 uint16_t& stepSize) const |
| 590 { | 539 { |
| 591 | 540 |
| 592 if (_outputMixerHandle == NULL) | 541 if (_outputMixerHandle == NULL) |
| 593 { | 542 { |
| 594 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 543 LOG(LS_WARNING) << "no avaliable output mixer exists"; |
| 595 " no avaliable output mixer exists"); | |
| 596 return -1; | 544 return -1; |
| 597 } | 545 } |
| 598 | 546 |
| 599 // The step size is always 1 for ALSA | 547 // The step size is always 1 for ALSA |
| 600 stepSize = 1; | 548 stepSize = 1; |
| 601 | 549 |
| 602 return 0; | 550 return 0; |
| 603 } | 551 } |
| 604 | 552 |
| 605 int32_t AudioMixerManagerLinuxALSA::SpeakerVolumeIsAvailable( | 553 int32_t AudioMixerManagerLinuxALSA::SpeakerVolumeIsAvailable( |
| 606 bool& available) | 554 bool& available) |
| 607 { | 555 { |
| 608 if (_outputMixerElement == NULL) | 556 if (_outputMixerElement == NULL) |
| 609 { | 557 { |
| 610 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 558 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 611 " no avaliable output mixer element exists"); | |
| 612 return -1; | 559 return -1; |
| 613 } | 560 } |
| 614 | 561 |
| 615 available = LATE(snd_mixer_selem_has_playback_volume)(_outputMixerElement); | 562 available = LATE(snd_mixer_selem_has_playback_volume)(_outputMixerElement); |
| 616 | 563 |
| 617 return 0; | 564 return 0; |
| 618 } | 565 } |
| 619 | 566 |
| 620 int32_t AudioMixerManagerLinuxALSA::SpeakerMuteIsAvailable( | 567 int32_t AudioMixerManagerLinuxALSA::SpeakerMuteIsAvailable( |
| 621 bool& available) | 568 bool& available) |
| 622 { | 569 { |
| 623 if (_outputMixerElement == NULL) | 570 if (_outputMixerElement == NULL) |
| 624 { | 571 { |
| 625 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 572 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 626 " no avaliable output mixer element exists"); | |
| 627 return -1; | 573 return -1; |
| 628 } | 574 } |
| 629 | 575 |
| 630 available = LATE(snd_mixer_selem_has_playback_switch)(_outputMixerElement); | 576 available = LATE(snd_mixer_selem_has_playback_switch)(_outputMixerElement); |
| 631 | 577 |
| 632 return 0; | 578 return 0; |
| 633 } | 579 } |
| 634 | 580 |
| 635 int32_t AudioMixerManagerLinuxALSA::SetSpeakerMute(bool enable) | 581 int32_t AudioMixerManagerLinuxALSA::SetSpeakerMute(bool enable) |
| 636 { | 582 { |
| 637 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 583 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::SetSpeakerMute(enable=" |
| 638 "AudioMixerManagerLinuxALSA::SetSpeakerMute(enable=%u)", | 584 << enable << ")"; |
| 639 enable); | |
| 640 | 585 |
| 641 rtc::CritScope lock(&_critSect); | 586 rtc::CritScope lock(&_critSect); |
| 642 | 587 |
| 643 if (_outputMixerElement == NULL) | 588 if (_outputMixerElement == NULL) |
| 644 { | 589 { |
| 645 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 590 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 646 " no avaliable output mixer element exists"); | |
| 647 return -1; | 591 return -1; |
| 648 } | 592 } |
| 649 | 593 |
| 650 // Ensure that the selected speaker destination has a valid mute control. | 594 // Ensure that the selected speaker destination has a valid mute control. |
| 651 bool available(false); | 595 bool available(false); |
| 652 SpeakerMuteIsAvailable(available); | 596 SpeakerMuteIsAvailable(available); |
| 653 if (!available) | 597 if (!available) |
| 654 { | 598 { |
| 655 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 599 LOG(LS_WARNING) << "it is not possible to mute the speaker"; |
| 656 " it is not possible to mute the speaker"); | |
| 657 return -1; | 600 return -1; |
| 658 } | 601 } |
| 659 | 602 |
| 660 // Note value = 0 (off) means muted | 603 // Note value = 0 (off) means muted |
| 661 int errVal = | 604 int errVal = |
| 662 LATE(snd_mixer_selem_set_playback_switch_all)(_outputMixerElement, | 605 LATE(snd_mixer_selem_set_playback_switch_all)(_outputMixerElement, |
| 663 !enable); | 606 !enable); |
| 664 if (errVal < 0) | 607 if (errVal < 0) |
| 665 { | 608 { |
| 666 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 609 LOG(LS_ERROR) << "Error setting playback switch: " |
| 667 " Error setting playback switch: %s", | 610 << LATE(snd_strerror)(errVal); |
| 668 LATE(snd_strerror)(errVal)); | |
| 669 return -1; | 611 return -1; |
| 670 } | 612 } |
| 671 | 613 |
| 672 return (0); | 614 return (0); |
| 673 } | 615 } |
| 674 | 616 |
| 675 int32_t AudioMixerManagerLinuxALSA::SpeakerMute(bool& enabled) const | 617 int32_t AudioMixerManagerLinuxALSA::SpeakerMute(bool& enabled) const |
| 676 { | 618 { |
| 677 | 619 |
| 678 if (_outputMixerElement == NULL) | 620 if (_outputMixerElement == NULL) |
| 679 { | 621 { |
| 680 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 622 LOG(LS_WARNING) << "no avaliable output mixer exists"; |
| 681 " no avaliable output mixer exists"); | |
| 682 return -1; | 623 return -1; |
| 683 } | 624 } |
| 684 | 625 |
| 685 // Ensure that the selected speaker destination has a valid mute control. | 626 // Ensure that the selected speaker destination has a valid mute control. |
| 686 bool available = | 627 bool available = |
| 687 LATE(snd_mixer_selem_has_playback_switch)(_outputMixerElement); | 628 LATE(snd_mixer_selem_has_playback_switch)(_outputMixerElement); |
| 688 if (!available) | 629 if (!available) |
| 689 { | 630 { |
| 690 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 631 LOG(LS_WARNING) << "it is not possible to mute the speaker"; |
| 691 " it is not possible to mute the speaker"); | |
| 692 return -1; | 632 return -1; |
| 693 } | 633 } |
| 694 | 634 |
| 695 int value(false); | 635 int value(false); |
| 696 | 636 |
| 697 // Retrieve one boolean control value for a specified mute-control | 637 // Retrieve one boolean control value for a specified mute-control |
| 698 // | 638 // |
| 699 int | 639 int |
| 700 errVal = LATE(snd_mixer_selem_get_playback_switch)( | 640 errVal = LATE(snd_mixer_selem_get_playback_switch)( |
| 701 _outputMixerElement, | 641 _outputMixerElement, |
| 702 (snd_mixer_selem_channel_id_t) 0, | 642 (snd_mixer_selem_channel_id_t) 0, |
| 703 &value); | 643 &value); |
| 704 if (errVal < 0) | 644 if (errVal < 0) |
| 705 { | 645 { |
| 706 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 646 LOG(LS_ERROR) << "Error getting playback switch: " |
| 707 " Error getting playback switch: %s", | 647 << LATE(snd_strerror)(errVal); |
| 708 LATE(snd_strerror)(errVal)); | |
| 709 return -1; | 648 return -1; |
| 710 } | 649 } |
| 711 | 650 |
| 712 // Note value = 0 (off) means muted | 651 // Note value = 0 (off) means muted |
| 713 enabled = (bool) !value; | 652 enabled = (bool) !value; |
| 714 | 653 |
| 715 return 0; | 654 return 0; |
| 716 } | 655 } |
| 717 | 656 |
| 718 int32_t AudioMixerManagerLinuxALSA::MicrophoneMuteIsAvailable( | 657 int32_t AudioMixerManagerLinuxALSA::MicrophoneMuteIsAvailable( |
| 719 bool& available) | 658 bool& available) |
| 720 { | 659 { |
| 721 if (_inputMixerElement == NULL) | 660 if (_inputMixerElement == NULL) |
| 722 { | 661 { |
| 723 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 662 LOG(LS_WARNING) << "no avaliable input mixer element exists"; |
| 724 " no avaliable input mixer element exists"); | |
| 725 return -1; | 663 return -1; |
| 726 } | 664 } |
| 727 | 665 |
| 728 available = LATE(snd_mixer_selem_has_capture_switch)(_inputMixerElement); | 666 available = LATE(snd_mixer_selem_has_capture_switch)(_inputMixerElement); |
| 729 return 0; | 667 return 0; |
| 730 } | 668 } |
| 731 | 669 |
| 732 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneMute(bool enable) | 670 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneMute(bool enable) |
| 733 { | 671 { |
| 734 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 672 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::SetMicrophoneMute(enable=" |
| 735 "AudioMixerManagerLinuxALSA::SetMicrophoneMute(enable=%u)", | 673 << enable << ")"; |
| 736 enable); | |
| 737 | 674 |
| 738 rtc::CritScope lock(&_critSect); | 675 rtc::CritScope lock(&_critSect); |
| 739 | 676 |
| 740 if (_inputMixerElement == NULL) | 677 if (_inputMixerElement == NULL) |
| 741 { | 678 { |
| 742 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 679 LOG(LS_WARNING) << "no avaliable input mixer element exists"; |
| 743 " no avaliable input mixer element exists"); | |
| 744 return -1; | 680 return -1; |
| 745 } | 681 } |
| 746 | 682 |
| 747 // Ensure that the selected microphone destination has a valid mute control. | 683 // Ensure that the selected microphone destination has a valid mute control. |
| 748 bool available(false); | 684 bool available(false); |
| 749 MicrophoneMuteIsAvailable(available); | 685 MicrophoneMuteIsAvailable(available); |
| 750 if (!available) | 686 if (!available) |
| 751 { | 687 { |
| 752 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 688 LOG(LS_WARNING) << "it is not possible to mute the microphone"; |
| 753 " it is not possible to mute the microphone"); | |
| 754 return -1; | 689 return -1; |
| 755 } | 690 } |
| 756 | 691 |
| 757 // Note value = 0 (off) means muted | 692 // Note value = 0 (off) means muted |
| 758 int errVal = | 693 int errVal = |
| 759 LATE(snd_mixer_selem_set_capture_switch_all)(_inputMixerElement, | 694 LATE(snd_mixer_selem_set_capture_switch_all)(_inputMixerElement, |
| 760 !enable); | 695 !enable); |
| 761 if (errVal < 0) | 696 if (errVal < 0) |
| 762 { | 697 { |
| 763 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 698 LOG(LS_ERROR) << "Error setting capture switch: " |
| 764 " Error setting capture switch: %s", | 699 << LATE(snd_strerror)(errVal); |
| 765 LATE(snd_strerror)(errVal)); | |
| 766 return -1; | 700 return -1; |
| 767 } | 701 } |
| 768 | 702 |
| 769 return (0); | 703 return (0); |
| 770 } | 704 } |
| 771 | 705 |
| 772 int32_t AudioMixerManagerLinuxALSA::MicrophoneMute(bool& enabled) const | 706 int32_t AudioMixerManagerLinuxALSA::MicrophoneMute(bool& enabled) const |
| 773 { | 707 { |
| 774 | 708 |
| 775 if (_inputMixerElement == NULL) | 709 if (_inputMixerElement == NULL) |
| 776 { | 710 { |
| 777 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 711 LOG(LS_WARNING) << "no avaliable input mixer exists"; |
| 778 " no avaliable input mixer exists"); | |
| 779 return -1; | 712 return -1; |
| 780 } | 713 } |
| 781 | 714 |
| 782 // Ensure that the selected microphone destination has a valid mute control. | 715 // Ensure that the selected microphone destination has a valid mute control. |
| 783 bool available = | 716 bool available = |
| 784 LATE(snd_mixer_selem_has_capture_switch)(_inputMixerElement); | 717 LATE(snd_mixer_selem_has_capture_switch)(_inputMixerElement); |
| 785 if (!available) | 718 if (!available) |
| 786 { | 719 { |
| 787 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 720 LOG(LS_WARNING) << "it is not possible to mute the microphone"; |
| 788 " it is not possible to mute the microphone"); | |
| 789 return -1; | 721 return -1; |
| 790 } | 722 } |
| 791 | 723 |
| 792 int value(false); | 724 int value(false); |
| 793 | 725 |
| 794 // Retrieve one boolean control value for a specified mute-control | 726 // Retrieve one boolean control value for a specified mute-control |
| 795 // | 727 // |
| 796 int | 728 int |
| 797 errVal = LATE(snd_mixer_selem_get_capture_switch)( | 729 errVal = LATE(snd_mixer_selem_get_capture_switch)( |
| 798 _inputMixerElement, | 730 _inputMixerElement, |
| 799 (snd_mixer_selem_channel_id_t) 0, | 731 (snd_mixer_selem_channel_id_t) 0, |
| 800 &value); | 732 &value); |
| 801 if (errVal < 0) | 733 if (errVal < 0) |
| 802 { | 734 { |
| 803 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 735 LOG(LS_ERROR) << "Error getting capture switch: " |
| 804 " Error getting capture switch: %s", | 736 << LATE(snd_strerror)(errVal); |
| 805 LATE(snd_strerror)(errVal)); | |
| 806 return -1; | 737 return -1; |
| 807 } | 738 } |
| 808 | 739 |
| 809 // Note value = 0 (off) means muted | 740 // Note value = 0 (off) means muted |
| 810 enabled = (bool) !value; | 741 enabled = (bool) !value; |
| 811 | 742 |
| 812 return 0; | 743 return 0; |
| 813 } | 744 } |
| 814 | 745 |
| 815 int32_t AudioMixerManagerLinuxALSA::MicrophoneBoostIsAvailable( | 746 int32_t AudioMixerManagerLinuxALSA::MicrophoneBoostIsAvailable( |
| 816 bool& available) | 747 bool& available) |
| 817 { | 748 { |
| 818 if (_inputMixerHandle == NULL) | 749 if (_inputMixerHandle == NULL) |
| 819 { | 750 { |
| 820 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 751 LOG(LS_WARNING) << "no avaliable input mixer exists"; |
| 821 " no avaliable input mixer exists"); | |
| 822 return -1; | 752 return -1; |
| 823 } | 753 } |
| 824 | 754 |
| 825 // Microphone boost cannot be enabled through ALSA Simple Mixer Interface | 755 // Microphone boost cannot be enabled through ALSA Simple Mixer Interface |
| 826 available = false; | 756 available = false; |
| 827 | 757 |
| 828 return 0; | 758 return 0; |
| 829 } | 759 } |
| 830 | 760 |
| 831 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneBoost(bool enable) | 761 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneBoost(bool enable) |
| 832 { | 762 { |
| 833 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 763 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::SetMicrophoneBoost(enable=" |
| 834 "AudioMixerManagerLinuxALSA::SetMicrophoneBoost(enable=%u)", | 764 << enable << ")"; |
| 835 enable); | |
| 836 | 765 |
| 837 rtc::CritScope lock(&_critSect); | 766 rtc::CritScope lock(&_critSect); |
| 838 | 767 |
| 839 if (_inputMixerHandle == NULL) | 768 if (_inputMixerHandle == NULL) |
| 840 { | 769 { |
| 841 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 770 LOG(LS_WARNING) << "no avaliable input mixer exists"; |
| 842 " no avaliable input mixer exists"); | |
| 843 return -1; | 771 return -1; |
| 844 } | 772 } |
| 845 | 773 |
| 846 // Ensure that the selected microphone destination has a valid mute control. | 774 // Ensure that the selected microphone destination has a valid mute control. |
| 847 bool available(false); | 775 bool available(false); |
| 848 MicrophoneMuteIsAvailable(available); | 776 MicrophoneMuteIsAvailable(available); |
| 849 if (!available) | 777 if (!available) |
| 850 { | 778 { |
| 851 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 779 LOG(LS_WARNING) << "it is not possible to enable microphone boost"; |
| 852 " it is not possible to enable microphone boost"); | |
| 853 return -1; | 780 return -1; |
| 854 } | 781 } |
| 855 | 782 |
| 856 // It is assumed that the call above fails! | 783 // It is assumed that the call above fails! |
| 857 | 784 |
| 858 return (0); | 785 return (0); |
| 859 } | 786 } |
| 860 | 787 |
| 861 int32_t AudioMixerManagerLinuxALSA::MicrophoneBoost(bool& enabled) const | 788 int32_t AudioMixerManagerLinuxALSA::MicrophoneBoost(bool& enabled) const |
| 862 { | 789 { |
| 863 | 790 |
| 864 if (_inputMixerHandle == NULL) | 791 if (_inputMixerHandle == NULL) |
| 865 { | 792 { |
| 866 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 793 LOG(LS_WARNING) << "no avaliable input mixer exists"; |
| 867 " no avaliable input mixer exists"); | |
| 868 return -1; | 794 return -1; |
| 869 } | 795 } |
| 870 | 796 |
| 871 // Microphone boost cannot be enabled on this platform! | 797 // Microphone boost cannot be enabled on this platform! |
| 872 enabled = false; | 798 enabled = false; |
| 873 | 799 |
| 874 return 0; | 800 return 0; |
| 875 } | 801 } |
| 876 | 802 |
| 877 int32_t AudioMixerManagerLinuxALSA::MicrophoneVolumeIsAvailable( | 803 int32_t AudioMixerManagerLinuxALSA::MicrophoneVolumeIsAvailable( |
| 878 bool& available) | 804 bool& available) |
| 879 { | 805 { |
| 880 if (_inputMixerElement == NULL) | 806 if (_inputMixerElement == NULL) |
| 881 { | 807 { |
| 882 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 808 LOG(LS_WARNING) << "no avaliable input mixer element exists"; |
| 883 " no avaliable input mixer element exists"); | |
| 884 return -1; | 809 return -1; |
| 885 } | 810 } |
| 886 | 811 |
| 887 available = LATE(snd_mixer_selem_has_capture_volume)(_inputMixerElement); | 812 available = LATE(snd_mixer_selem_has_capture_volume)(_inputMixerElement); |
| 888 | 813 |
| 889 return 0; | 814 return 0; |
| 890 } | 815 } |
| 891 | 816 |
| 892 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneVolume( | 817 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneVolume( |
| 893 uint32_t volume) | 818 uint32_t volume) |
| 894 { | 819 { |
| 895 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 820 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::SetMicrophoneVolume(volume=" |
| 896 "AudioMixerManagerLinuxALSA::SetMicrophoneVolume(volume=%u)", | 821 << volume << ")"; |
| 897 volume); | |
| 898 | 822 |
| 899 rtc::CritScope lock(&_critSect); | 823 rtc::CritScope lock(&_critSect); |
| 900 | 824 |
| 901 if (_inputMixerElement == NULL) | 825 if (_inputMixerElement == NULL) |
| 902 { | 826 { |
| 903 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 827 LOG(LS_WARNING) << "no avaliable input mixer element exists"; |
| 904 " no avaliable input mixer element exists"); | |
| 905 return -1; | 828 return -1; |
| 906 } | 829 } |
| 907 | 830 |
| 908 int | 831 int |
| 909 errVal = | 832 errVal = |
| 910 LATE(snd_mixer_selem_set_capture_volume_all)(_inputMixerElement, | 833 LATE(snd_mixer_selem_set_capture_volume_all)(_inputMixerElement, |
| 911 volume); | 834 volume); |
| 912 if (errVal < 0) | 835 if (errVal < 0) |
| 913 { | 836 { |
| 914 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 837 LOG(LS_ERROR) << "Error changing microphone volume: " |
| 915 " Error changing microphone volume: %s", | 838 << LATE(snd_strerror)(errVal); |
| 916 LATE(snd_strerror)(errVal)); | |
| 917 return -1; | 839 return -1; |
| 918 } | 840 } |
| 919 | 841 |
| 920 return (0); | 842 return (0); |
| 921 } | 843 } |
| 922 | 844 |
| 923 // TL: Have done testnig with these but they don't seem reliable and | 845 // TL: Have done testnig with these but they don't seem reliable and |
| 924 // they were therefore not added | 846 // they were therefore not added |
| 925 /* | 847 /* |
| 926 // ---------------------------------------------------------------------------- | 848 // ---------------------------------------------------------------------------- |
| 927 // SetMaxMicrophoneVolume | 849 // SetMaxMicrophoneVolume |
| 928 // ---------------------------------------------------------------------------- | 850 // ---------------------------------------------------------------------------- |
| 929 | 851 |
| 930 int32_t AudioMixerManagerLinuxALSA::SetMaxMicrophoneVolume( | 852 int32_t AudioMixerManagerLinuxALSA::SetMaxMicrophoneVolume( |
| 931 uint32_t maxVolume) | 853 uint32_t maxVolume) |
| 932 { | 854 { |
| 933 | 855 |
| 934 if (_inputMixerElement == NULL) | 856 if (_inputMixerElement == NULL) |
| 935 { | 857 { |
| 936 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 858 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 937 " no avaliable output mixer element exists"); | |
| 938 return -1; | 859 return -1; |
| 939 } | 860 } |
| 940 | 861 |
| 941 long int minVol(0); | 862 long int minVol(0); |
| 942 long int maxVol(0); | 863 long int maxVol(0); |
| 943 | 864 |
| 944 int errVal = snd_mixer_selem_get_capture_volume_range(_inputMixerElement, | 865 int errVal = snd_mixer_selem_get_capture_volume_range(_inputMixerElement, |
| 945 &minVol, &maxVol); | 866 &minVol, &maxVol); |
| 946 if ((maxVol <= minVol) || (errVal != 0)) | 867 if ((maxVol <= minVol) || (errVal != 0)) |
| 947 { | 868 { |
| 948 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 869 LOG(LS_WARNING) << "Error getting capture volume range: " |
| 949 " Error getting capture volume range: %s", snd_strerror(errVal)); | 870 << snd_strerror(errVal); |
| 950 } | 871 } |
| 951 | 872 |
| 952 maxVol = (long int)maxVolume; | 873 maxVol = (long int)maxVolume; |
| 953 printf("min %d max %d", minVol, maxVol); | 874 printf("min %d max %d", minVol, maxVol); |
| 954 errVal = snd_mixer_selem_set_capture_volume_range(_inputMixerElement, minVol, m
axVol); | 875 errVal = snd_mixer_selem_set_capture_volume_range(_inputMixerElement, minVol, m
axVol); |
| 955 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 876 LOG(LS_VERBOSE) << "Capture hardware volume range, min: " << minVol |
| 956 " Capture hardware volume range, min: %d, max: %d", minVol, maxVol); | 877 << ", max: " << maxVol; |
| 957 if (errVal != 0) | 878 if (errVal != 0) |
| 958 { | 879 { |
| 959 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 880 LOG(LS_ERROR) << "Error setting capture volume range: " |
| 960 " Error setting capture volume range: %s", snd_strerror(errVal)); | 881 << snd_strerror(errVal); |
| 961 return -1; | 882 return -1; |
| 962 } | 883 } |
| 963 | 884 |
| 964 return 0; | 885 return 0; |
| 965 } | 886 } |
| 966 | 887 |
| 967 // ---------------------------------------------------------------------------- | 888 // ---------------------------------------------------------------------------- |
| 968 // SetMinMicrophoneVolume | 889 // SetMinMicrophoneVolume |
| 969 // ---------------------------------------------------------------------------- | 890 // ---------------------------------------------------------------------------- |
| 970 | 891 |
| 971 int32_t AudioMixerManagerLinuxALSA::SetMinMicrophoneVolume( | 892 int32_t AudioMixerManagerLinuxALSA::SetMinMicrophoneVolume( |
| 972 uint32_t minVolume) | 893 uint32_t minVolume) |
| 973 { | 894 { |
| 974 | 895 |
| 975 if (_inputMixerElement == NULL) | 896 if (_inputMixerElement == NULL) |
| 976 { | 897 { |
| 977 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 898 LOG(LS_WARNING) << "no avaliable output mixer element exists"; |
| 978 " no avaliable output mixer element exists"); | |
| 979 return -1; | 899 return -1; |
| 980 } | 900 } |
| 981 | 901 |
| 982 long int minVol(0); | 902 long int minVol(0); |
| 983 long int maxVol(0); | 903 long int maxVol(0); |
| 984 | 904 |
| 985 int errVal = snd_mixer_selem_get_capture_volume_range( | 905 int errVal = snd_mixer_selem_get_capture_volume_range( |
| 986 _inputMixerElement, &minVol, &maxVol); | 906 _inputMixerElement, &minVol, &maxVol); |
| 987 if (maxVol <= minVol) | 907 if (maxVol <= minVol) |
| 988 { | 908 { |
| 989 //maxVol = 255; | 909 //maxVol = 255; |
| 990 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 910 LOG(LS_WARNING) << "Error getting capture volume range: " |
| 991 " Error getting capture volume range: %s", snd_strerror(errVal)); | 911 << snd_strerror(errVal); |
| 992 } | 912 } |
| 993 | 913 |
| 994 printf("min %d max %d", minVol, maxVol); | 914 printf("min %d max %d", minVol, maxVol); |
| 995 minVol = (long int)minVolume; | 915 minVol = (long int)minVolume; |
| 996 errVal = snd_mixer_selem_set_capture_volume_range( | 916 errVal = snd_mixer_selem_set_capture_volume_range( |
| 997 _inputMixerElement, minVol, maxVol); | 917 _inputMixerElement, minVol, maxVol); |
| 998 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 918 LOG(LS_VERBOSE) << "Capture hardware volume range, min: " << minVol |
| 999 " Capture hardware volume range, min: %d, max: %d", minVol, maxVol); | 919 << ", max: " << maxVol; |
| 1000 if (errVal != 0) | 920 if (errVal != 0) |
| 1001 { | 921 { |
| 1002 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 922 LOG(LS_ERROR) << "Error setting capture volume range: " |
| 1003 " Error setting capture volume range: %s", snd_strerror(errVal)); | 923 << snd_strerror(errVal); |
| 1004 return -1; | 924 return -1; |
| 1005 } | 925 } |
| 1006 | 926 |
| 1007 return 0; | 927 return 0; |
| 1008 } | 928 } |
| 1009 */ | 929 */ |
| 1010 | 930 |
| 1011 int32_t AudioMixerManagerLinuxALSA::MicrophoneVolume( | 931 int32_t AudioMixerManagerLinuxALSA::MicrophoneVolume( |
| 1012 uint32_t& volume) const | 932 uint32_t& volume) const |
| 1013 { | 933 { |
| 1014 | 934 |
| 1015 if (_inputMixerElement == NULL) | 935 if (_inputMixerElement == NULL) |
| 1016 { | 936 { |
| 1017 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 937 LOG(LS_WARNING) << "no avaliable input mixer element exists"; |
| 1018 " no avaliable input mixer element exists"); | |
| 1019 return -1; | 938 return -1; |
| 1020 } | 939 } |
| 1021 | 940 |
| 1022 long int vol(0); | 941 long int vol(0); |
| 1023 | 942 |
| 1024 int | 943 int |
| 1025 errVal = | 944 errVal = |
| 1026 LATE(snd_mixer_selem_get_capture_volume)( | 945 LATE(snd_mixer_selem_get_capture_volume)( |
| 1027 _inputMixerElement, | 946 _inputMixerElement, |
| 1028 (snd_mixer_selem_channel_id_t) 0, | 947 (snd_mixer_selem_channel_id_t) 0, |
| 1029 &vol); | 948 &vol); |
| 1030 if (errVal < 0) | 949 if (errVal < 0) |
| 1031 { | 950 { |
| 1032 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 951 LOG(LS_ERROR) << "Error getting inputvolume: " |
| 1033 "Error getting inputvolume: %s", | 952 << LATE(snd_strerror)(errVal); |
| 1034 LATE(snd_strerror)(errVal)); | |
| 1035 return -1; | 953 return -1; |
| 1036 } | 954 } |
| 1037 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 955 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxALSA::MicrophoneVolume() => vol=" |
| 1038 " AudioMixerManagerLinuxALSA::MicrophoneVolume() => vol=%i"
, | 956 << vol; |
| 1039 vol); | |
| 1040 | 957 |
| 1041 volume = static_cast<uint32_t> (vol); | 958 volume = static_cast<uint32_t> (vol); |
| 1042 | 959 |
| 1043 return 0; | 960 return 0; |
| 1044 } | 961 } |
| 1045 | 962 |
| 1046 int32_t AudioMixerManagerLinuxALSA::MaxMicrophoneVolume( | 963 int32_t AudioMixerManagerLinuxALSA::MaxMicrophoneVolume( |
| 1047 uint32_t& maxVolume) const | 964 uint32_t& maxVolume) const |
| 1048 { | 965 { |
| 1049 | 966 |
| 1050 if (_inputMixerElement == NULL) | 967 if (_inputMixerElement == NULL) |
| 1051 { | 968 { |
| 1052 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 969 LOG(LS_WARNING) << "no avaliable input mixer element exists"; |
| 1053 " no avaliable input mixer element exists"); | |
| 1054 return -1; | 970 return -1; |
| 1055 } | 971 } |
| 1056 | 972 |
| 1057 long int minVol(0); | 973 long int minVol(0); |
| 1058 long int maxVol(0); | 974 long int maxVol(0); |
| 1059 | 975 |
| 1060 // check if we have mic volume at all | 976 // check if we have mic volume at all |
| 1061 if (!LATE(snd_mixer_selem_has_capture_volume)(_inputMixerElement)) | 977 if (!LATE(snd_mixer_selem_has_capture_volume)(_inputMixerElement)) |
| 1062 { | 978 { |
| 1063 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 979 LOG(LS_ERROR) << "No microphone volume available"; |
| 1064 " No microphone volume available"); | |
| 1065 return -1; | 980 return -1; |
| 1066 } | 981 } |
| 1067 | 982 |
| 1068 int errVal = | 983 int errVal = |
| 1069 LATE(snd_mixer_selem_get_capture_volume_range)(_inputMixerElement, | 984 LATE(snd_mixer_selem_get_capture_volume_range)(_inputMixerElement, |
| 1070 &minVol, &maxVol); | 985 &minVol, &maxVol); |
| 1071 | 986 |
| 1072 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 987 LOG(LS_VERBOSE) << "Microphone hardware volume range, min: " << minVol |
| 1073 " Microphone hardware volume range, min: %d, max: %d", | 988 << ", max: " << maxVol; |
| 1074 minVol, maxVol); | |
| 1075 if (maxVol <= minVol) | 989 if (maxVol <= minVol) |
| 1076 { | 990 { |
| 1077 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 991 LOG(LS_ERROR) << "Error getting microphone volume range: " |
| 1078 " Error getting microphone volume range: %s", | 992 << LATE(snd_strerror)(errVal); |
| 1079 LATE(snd_strerror)(errVal)); | |
| 1080 } | 993 } |
| 1081 | 994 |
| 1082 maxVolume = static_cast<uint32_t> (maxVol); | 995 maxVolume = static_cast<uint32_t> (maxVol); |
| 1083 | 996 |
| 1084 return 0; | 997 return 0; |
| 1085 } | 998 } |
| 1086 | 999 |
| 1087 int32_t AudioMixerManagerLinuxALSA::MinMicrophoneVolume( | 1000 int32_t AudioMixerManagerLinuxALSA::MinMicrophoneVolume( |
| 1088 uint32_t& minVolume) const | 1001 uint32_t& minVolume) const |
| 1089 { | 1002 { |
| 1090 | 1003 |
| 1091 if (_inputMixerElement == NULL) | 1004 if (_inputMixerElement == NULL) |
| 1092 { | 1005 { |
| 1093 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1006 LOG(LS_WARNING) << "no avaliable input mixer element exists"; |
| 1094 " no avaliable input mixer element exists"); | |
| 1095 return -1; | 1007 return -1; |
| 1096 } | 1008 } |
| 1097 | 1009 |
| 1098 long int minVol(0); | 1010 long int minVol(0); |
| 1099 long int maxVol(0); | 1011 long int maxVol(0); |
| 1100 | 1012 |
| 1101 int errVal = | 1013 int errVal = |
| 1102 LATE(snd_mixer_selem_get_capture_volume_range)(_inputMixerElement, | 1014 LATE(snd_mixer_selem_get_capture_volume_range)(_inputMixerElement, |
| 1103 &minVol, &maxVol); | 1015 &minVol, &maxVol); |
| 1104 | 1016 |
| 1105 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1017 LOG(LS_VERBOSE) << "Microphone hardware volume range, min: " << minVol |
| 1106 " Microphone hardware volume range, min: %d, max: %d", | 1018 << ", max: " << maxVol; |
| 1107 minVol, maxVol); | |
| 1108 if (maxVol <= minVol) | 1019 if (maxVol <= minVol) |
| 1109 { | 1020 { |
| 1110 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1021 LOG(LS_ERROR) << "Error getting microphone volume range: " |
| 1111 " Error getting microphone volume range: %s", | 1022 << LATE(snd_strerror)(errVal); |
| 1112 LATE(snd_strerror)(errVal)); | |
| 1113 } | 1023 } |
| 1114 | 1024 |
| 1115 minVolume = static_cast<uint32_t> (minVol); | 1025 minVolume = static_cast<uint32_t> (minVol); |
| 1116 | 1026 |
| 1117 return 0; | 1027 return 0; |
| 1118 } | 1028 } |
| 1119 | 1029 |
| 1120 int32_t AudioMixerManagerLinuxALSA::MicrophoneVolumeStepSize( | 1030 int32_t AudioMixerManagerLinuxALSA::MicrophoneVolumeStepSize( |
| 1121 uint16_t& stepSize) const | 1031 uint16_t& stepSize) const |
| 1122 { | 1032 { |
| 1123 | 1033 |
| 1124 if (_inputMixerHandle == NULL) | 1034 if (_inputMixerHandle == NULL) |
| 1125 { | 1035 { |
| 1126 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1036 LOG(LS_WARNING) << "no avaliable input mixer exists"; |
| 1127 " no avaliable input mixer exists"); | |
| 1128 return -1; | 1037 return -1; |
| 1129 } | 1038 } |
| 1130 | 1039 |
| 1131 // The step size is always 1 for ALSA | 1040 // The step size is always 1 for ALSA |
| 1132 stepSize = 1; | 1041 stepSize = 1; |
| 1133 | 1042 |
| 1134 return 0; | 1043 return 0; |
| 1135 } | 1044 } |
| 1136 | 1045 |
| 1137 // ============================================================================ | 1046 // ============================================================================ |
| 1138 // Private Methods | 1047 // Private Methods |
| 1139 // ============================================================================ | 1048 // ============================================================================ |
| 1140 | 1049 |
| 1141 int32_t AudioMixerManagerLinuxALSA::LoadMicMixerElement() const | 1050 int32_t AudioMixerManagerLinuxALSA::LoadMicMixerElement() const |
| 1142 { | 1051 { |
| 1143 int errVal = LATE(snd_mixer_load)(_inputMixerHandle); | 1052 int errVal = LATE(snd_mixer_load)(_inputMixerHandle); |
| 1144 if (errVal < 0) | 1053 if (errVal < 0) |
| 1145 { | 1054 { |
| 1146 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1055 LOG(LS_ERROR) << "snd_mixer_load(_inputMixerHandle), error: " |
| 1147 "snd_mixer_load(_inputMixerHandle), error: %s", | 1056 << LATE(snd_strerror)(errVal); |
| 1148 LATE(snd_strerror)(errVal)); | |
| 1149 _inputMixerHandle = NULL; | 1057 _inputMixerHandle = NULL; |
| 1150 return -1; | 1058 return -1; |
| 1151 } | 1059 } |
| 1152 | 1060 |
| 1153 snd_mixer_elem_t *elem = NULL; | 1061 snd_mixer_elem_t *elem = NULL; |
| 1154 snd_mixer_elem_t *micElem = NULL; | 1062 snd_mixer_elem_t *micElem = NULL; |
| 1155 unsigned mixerIdx = 0; | 1063 unsigned mixerIdx = 0; |
| 1156 const char *selemName = NULL; | 1064 const char *selemName = NULL; |
| 1157 | 1065 |
| 1158 // Find and store handles to the right mixer elements | 1066 // Find and store handles to the right mixer elements |
| 1159 for (elem = LATE(snd_mixer_first_elem)(_inputMixerHandle); elem; elem | 1067 for (elem = LATE(snd_mixer_first_elem)(_inputMixerHandle); elem; elem |
| 1160 = LATE(snd_mixer_elem_next)(elem), mixerIdx++) | 1068 = LATE(snd_mixer_elem_next)(elem), mixerIdx++) |
| 1161 { | 1069 { |
| 1162 if (LATE(snd_mixer_selem_is_active)(elem)) | 1070 if (LATE(snd_mixer_selem_is_active)(elem)) |
| 1163 { | 1071 { |
| 1164 selemName = LATE(snd_mixer_selem_get_name)(elem); | 1072 selemName = LATE(snd_mixer_selem_get_name)(elem); |
| 1165 if (strcmp(selemName, "Capture") == 0) // "Capture", "Mic" | 1073 if (strcmp(selemName, "Capture") == 0) // "Capture", "Mic" |
| 1166 { | 1074 { |
| 1167 _inputMixerElement = elem; | 1075 _inputMixerElement = elem; |
| 1168 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, | 1076 LOG(LS_VERBOSE) << "Capture element set"; |
| 1169 _id, " Capture element set"); | |
| 1170 } else if (strcmp(selemName, "Mic") == 0) | 1077 } else if (strcmp(selemName, "Mic") == 0) |
| 1171 { | 1078 { |
| 1172 micElem = elem; | 1079 micElem = elem; |
| 1173 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, | 1080 LOG(LS_VERBOSE) << "Mic element found"; |
| 1174 _id, " Mic element found"); | |
| 1175 } | 1081 } |
| 1176 } | 1082 } |
| 1177 | 1083 |
| 1178 if (_inputMixerElement) | 1084 if (_inputMixerElement) |
| 1179 { | 1085 { |
| 1180 // Use the first Capture element that is found | 1086 // Use the first Capture element that is found |
| 1181 // The second one may not work | 1087 // The second one may not work |
| 1182 break; | 1088 break; |
| 1183 } | 1089 } |
| 1184 } | 1090 } |
| 1185 | 1091 |
| 1186 if (_inputMixerElement == NULL) | 1092 if (_inputMixerElement == NULL) |
| 1187 { | 1093 { |
| 1188 // We didn't find a Capture handle, use Mic. | 1094 // We didn't find a Capture handle, use Mic. |
| 1189 if (micElem != NULL) | 1095 if (micElem != NULL) |
| 1190 { | 1096 { |
| 1191 _inputMixerElement = micElem; | 1097 _inputMixerElement = micElem; |
| 1192 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1098 LOG(LS_VERBOSE) << "Using Mic as capture volume."; |
| 1193 " Using Mic as capture volume."); | |
| 1194 } else | 1099 } else |
| 1195 { | 1100 { |
| 1196 _inputMixerElement = NULL; | 1101 _inputMixerElement = NULL; |
| 1197 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1102 LOG(LS_ERROR) << "Could not find capture volume on the mixer."; |
| 1198 "Could not find capture volume on the mixer."); | |
| 1199 | 1103 |
| 1200 return -1; | 1104 return -1; |
| 1201 } | 1105 } |
| 1202 } | 1106 } |
| 1203 | 1107 |
| 1204 return 0; | 1108 return 0; |
| 1205 } | 1109 } |
| 1206 | 1110 |
| 1207 int32_t AudioMixerManagerLinuxALSA::LoadSpeakerMixerElement() const | 1111 int32_t AudioMixerManagerLinuxALSA::LoadSpeakerMixerElement() const |
| 1208 { | 1112 { |
| 1209 int errVal = LATE(snd_mixer_load)(_outputMixerHandle); | 1113 int errVal = LATE(snd_mixer_load)(_outputMixerHandle); |
| 1210 if (errVal < 0) | 1114 if (errVal < 0) |
| 1211 { | 1115 { |
| 1212 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1116 LOG(LS_ERROR) << "snd_mixer_load(_outputMixerHandle), error: " |
| 1213 " snd_mixer_load(_outputMixerHandle), error: %s", | 1117 << LATE(snd_strerror)(errVal); |
| 1214 LATE(snd_strerror)(errVal)); | |
| 1215 _outputMixerHandle = NULL; | 1118 _outputMixerHandle = NULL; |
| 1216 return -1; | 1119 return -1; |
| 1217 } | 1120 } |
| 1218 | 1121 |
| 1219 snd_mixer_elem_t *elem = NULL; | 1122 snd_mixer_elem_t *elem = NULL; |
| 1220 snd_mixer_elem_t *masterElem = NULL; | 1123 snd_mixer_elem_t *masterElem = NULL; |
| 1221 snd_mixer_elem_t *speakerElem = NULL; | 1124 snd_mixer_elem_t *speakerElem = NULL; |
| 1222 unsigned mixerIdx = 0; | 1125 unsigned mixerIdx = 0; |
| 1223 const char *selemName = NULL; | 1126 const char *selemName = NULL; |
| 1224 | 1127 |
| 1225 // Find and store handles to the right mixer elements | 1128 // Find and store handles to the right mixer elements |
| 1226 for (elem = LATE(snd_mixer_first_elem)(_outputMixerHandle); elem; elem | 1129 for (elem = LATE(snd_mixer_first_elem)(_outputMixerHandle); elem; elem |
| 1227 = LATE(snd_mixer_elem_next)(elem), mixerIdx++) | 1130 = LATE(snd_mixer_elem_next)(elem), mixerIdx++) |
| 1228 { | 1131 { |
| 1229 if (LATE(snd_mixer_selem_is_active)(elem)) | 1132 if (LATE(snd_mixer_selem_is_active)(elem)) |
| 1230 { | 1133 { |
| 1231 selemName = LATE(snd_mixer_selem_get_name)(elem); | 1134 selemName = LATE(snd_mixer_selem_get_name)(elem); |
| 1232 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1135 LOG(LS_VERBOSE) << "snd_mixer_selem_get_name " << mixerIdx << ": " |
| 1233 "snd_mixer_selem_get_name %d: %s =%x", mixerIdx, | 1136 << selemName << " =" << elem; |
| 1234 selemName, elem); | |
| 1235 | 1137 |
| 1236 // "Master", "PCM", "Wave", "Master Mono", "PC Speaker", "PCM", "Wav
e" | 1138 // "Master", "PCM", "Wave", "Master Mono", "PC Speaker", "PCM", "Wav
e" |
| 1237 if (strcmp(selemName, "PCM") == 0) | 1139 if (strcmp(selemName, "PCM") == 0) |
| 1238 { | 1140 { |
| 1239 _outputMixerElement = elem; | 1141 _outputMixerElement = elem; |
| 1240 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, | 1142 LOG(LS_VERBOSE) << "PCM element set"; |
| 1241 _id, " PCM element set"); | |
| 1242 } else if (strcmp(selemName, "Master") == 0) | 1143 } else if (strcmp(selemName, "Master") == 0) |
| 1243 { | 1144 { |
| 1244 masterElem = elem; | 1145 masterElem = elem; |
| 1245 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, | 1146 LOG(LS_VERBOSE) << "Master element found"; |
| 1246 _id, " Master element found"); | |
| 1247 } else if (strcmp(selemName, "Speaker") == 0) | 1147 } else if (strcmp(selemName, "Speaker") == 0) |
| 1248 { | 1148 { |
| 1249 speakerElem = elem; | 1149 speakerElem = elem; |
| 1250 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, | 1150 LOG(LS_VERBOSE) << "Speaker element found"; |
| 1251 _id, " Speaker element found"); | |
| 1252 } | 1151 } |
| 1253 } | 1152 } |
| 1254 | 1153 |
| 1255 if (_outputMixerElement) | 1154 if (_outputMixerElement) |
| 1256 { | 1155 { |
| 1257 // We have found the element we want | 1156 // We have found the element we want |
| 1258 break; | 1157 break; |
| 1259 } | 1158 } |
| 1260 } | 1159 } |
| 1261 | 1160 |
| 1262 // If we didn't find a PCM Handle, use Master or Speaker | 1161 // If we didn't find a PCM Handle, use Master or Speaker |
| 1263 if (_outputMixerElement == NULL) | 1162 if (_outputMixerElement == NULL) |
| 1264 { | 1163 { |
| 1265 if (masterElem != NULL) | 1164 if (masterElem != NULL) |
| 1266 { | 1165 { |
| 1267 _outputMixerElement = masterElem; | 1166 _outputMixerElement = masterElem; |
| 1268 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1167 LOG(LS_VERBOSE) << "Using Master as output volume."; |
| 1269 " Using Master as output volume."); | |
| 1270 } else if (speakerElem != NULL) | 1168 } else if (speakerElem != NULL) |
| 1271 { | 1169 { |
| 1272 _outputMixerElement = speakerElem; | 1170 _outputMixerElement = speakerElem; |
| 1273 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1171 LOG(LS_VERBOSE) << "Using Speaker as output volume."; |
| 1274 " Using Speaker as output volume."); | |
| 1275 } else | 1172 } else |
| 1276 { | 1173 { |
| 1277 _outputMixerElement = NULL; | 1174 _outputMixerElement = NULL; |
| 1278 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1175 LOG(LS_ERROR) << "Could not find output volume in the mixer."; |
| 1279 "Could not find output volume in the mixer."); | |
| 1280 return -1; | 1176 return -1; |
| 1281 } | 1177 } |
| 1282 } | 1178 } |
| 1283 | 1179 |
| 1284 return 0; | 1180 return 0; |
| 1285 } | 1181 } |
| 1286 | 1182 |
| 1287 void AudioMixerManagerLinuxALSA::GetControlName(char* controlName, | 1183 void AudioMixerManagerLinuxALSA::GetControlName(char* controlName, |
| 1288 char* deviceName) const | 1184 char* deviceName) const |
| 1289 { | 1185 { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1301 int nChar = (int) (pos2 - pos1); | 1197 int nChar = (int) (pos2 - pos1); |
| 1302 strncpy(&controlName[2], pos1, nChar); | 1198 strncpy(&controlName[2], pos1, nChar); |
| 1303 controlName[2 + nChar] = '\0'; | 1199 controlName[2 + nChar] = '\0'; |
| 1304 } else { | 1200 } else { |
| 1305 strcpy(controlName, deviceName); | 1201 strcpy(controlName, deviceName); |
| 1306 } | 1202 } |
| 1307 | 1203 |
| 1308 } | 1204 } |
| 1309 | 1205 |
| 1310 } | 1206 } |
| OLD | NEW |