| 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 "webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h" | 11 #include "webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h" |
| 12 | 12 |
| 13 #include <unistd.h> // getpid() | 13 #include <unistd.h> // getpid() |
| 14 | 14 |
| 15 namespace webrtc { | 15 namespace webrtc { |
| 16 | 16 |
| 17 #define WEBRTC_CA_RETURN_ON_ERR(expr) \ | 17 #define WEBRTC_CA_RETURN_ON_ERR(expr) \ |
| 18 do { \ | 18 do { \ |
| 19 err = expr; \ | 19 err = expr; \ |
| 20 if (err != noErr) { \ | 20 if (err != noErr) { \ |
| 21 logCAMsg(kTraceError, kTraceAudioDevice, _id, "Error in " #expr, \ | 21 logCAMsg(rtc::LS_ERROR, "Error in " #expr, \ |
| 22 (const char*) & err); \ | 22 (const char*) & err); \ |
| 23 return -1; \ | 23 return -1; \ |
| 24 } \ | 24 } \ |
| 25 } while (0) | 25 } while (0) |
| 26 | 26 |
| 27 #define WEBRTC_CA_LOG_ERR(expr) \ | 27 #define WEBRTC_CA_LOG_ERR(expr) \ |
| 28 do { \ | 28 do { \ |
| 29 err = expr; \ | 29 err = expr; \ |
| 30 if (err != noErr) { \ | 30 if (err != noErr) { \ |
| 31 logCAMsg(kTraceError, kTraceAudioDevice, _id, "Error in " #expr, \ | 31 logCAMsg(rtc::LS_ERROR, "Error in " #expr, \ |
| 32 (const char*) & err); \ | 32 (const char*) & err); \ |
| 33 } \ | 33 } \ |
| 34 } while (0) | 34 } while (0) |
| 35 | 35 |
| 36 #define WEBRTC_CA_LOG_WARN(expr) \ | 36 #define WEBRTC_CA_LOG_WARN(expr) \ |
| 37 do { \ | 37 do { \ |
| 38 err = expr; \ | 38 err = expr; \ |
| 39 if (err != noErr) { \ | 39 if (err != noErr) { \ |
| 40 logCAMsg(kTraceWarning, kTraceAudioDevice, _id, "Error in " #expr, \ | 40 logCAMsg(rtc::LS_WARNING, "Error in " #expr, \ |
| 41 (const char*) & err); \ | 41 (const char*) & err); \ |
| 42 } \ | 42 } \ |
| 43 } while (0) | 43 } while (0) |
| 44 | 44 |
| 45 AudioMixerManagerMac::AudioMixerManagerMac(const int32_t id) | 45 AudioMixerManagerMac::AudioMixerManagerMac() |
| 46 : _id(id), | 46 : _inputDeviceID(kAudioObjectUnknown), |
| 47 _inputDeviceID(kAudioObjectUnknown), | |
| 48 _outputDeviceID(kAudioObjectUnknown), | 47 _outputDeviceID(kAudioObjectUnknown), |
| 49 _noInputChannels(0), | 48 _noInputChannels(0), |
| 50 _noOutputChannels(0) { | 49 _noOutputChannels(0) { |
| 51 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s constructed", | 50 LOG(LS_INFO) << __FUNCTION__ << " created"; |
| 52 __FUNCTION__); | |
| 53 } | 51 } |
| 54 | 52 |
| 55 AudioMixerManagerMac::~AudioMixerManagerMac() { | 53 AudioMixerManagerMac::~AudioMixerManagerMac() { |
| 56 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destructed", | 54 LOG(LS_INFO) << __FUNCTION__ << " destroyed"; |
| 57 __FUNCTION__); | |
| 58 Close(); | 55 Close(); |
| 59 } | 56 } |
| 60 | 57 |
| 61 // ============================================================================ | 58 // ============================================================================ |
| 62 // PUBLIC METHODS | 59 // PUBLIC METHODS |
| 63 // ============================================================================ | 60 // ============================================================================ |
| 64 | 61 |
| 65 int32_t AudioMixerManagerMac::Close() { | 62 int32_t AudioMixerManagerMac::Close() { |
| 66 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); | 63 LOG(LS_VERBOSE) << __FUNCTION__; |
| 67 | 64 |
| 68 rtc::CritScope lock(&_critSect); | 65 rtc::CritScope lock(&_critSect); |
| 69 | 66 |
| 70 CloseSpeaker(); | 67 CloseSpeaker(); |
| 71 CloseMicrophone(); | 68 CloseMicrophone(); |
| 72 | 69 |
| 73 return 0; | 70 return 0; |
| 74 } | 71 } |
| 75 | 72 |
| 76 int32_t AudioMixerManagerMac::CloseSpeaker() { | 73 int32_t AudioMixerManagerMac::CloseSpeaker() { |
| 77 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); | 74 LOG(LS_VERBOSE) << __FUNCTION__; |
| 78 | 75 |
| 79 rtc::CritScope lock(&_critSect); | 76 rtc::CritScope lock(&_critSect); |
| 80 | 77 |
| 81 _outputDeviceID = kAudioObjectUnknown; | 78 _outputDeviceID = kAudioObjectUnknown; |
| 82 _noOutputChannels = 0; | 79 _noOutputChannels = 0; |
| 83 | 80 |
| 84 return 0; | 81 return 0; |
| 85 } | 82 } |
| 86 | 83 |
| 87 int32_t AudioMixerManagerMac::CloseMicrophone() { | 84 int32_t AudioMixerManagerMac::CloseMicrophone() { |
| 88 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); | 85 LOG(LS_VERBOSE) << __FUNCTION__; |
| 89 | 86 |
| 90 rtc::CritScope lock(&_critSect); | 87 rtc::CritScope lock(&_critSect); |
| 91 | 88 |
| 92 _inputDeviceID = kAudioObjectUnknown; | 89 _inputDeviceID = kAudioObjectUnknown; |
| 93 _noInputChannels = 0; | 90 _noInputChannels = 0; |
| 94 | 91 |
| 95 return 0; | 92 return 0; |
| 96 } | 93 } |
| 97 | 94 |
| 98 int32_t AudioMixerManagerMac::OpenSpeaker(AudioDeviceID deviceID) { | 95 int32_t AudioMixerManagerMac::OpenSpeaker(AudioDeviceID deviceID) { |
| 99 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 96 LOG(LS_VERBOSE) << "AudioMixerManagerMac::OpenSpeaker(id=" << deviceID << ")"; |
| 100 "AudioMixerManagerMac::OpenSpeaker(id=%d)", deviceID); | |
| 101 | 97 |
| 102 rtc::CritScope lock(&_critSect); | 98 rtc::CritScope lock(&_critSect); |
| 103 | 99 |
| 104 OSStatus err = noErr; | 100 OSStatus err = noErr; |
| 105 UInt32 size = 0; | 101 UInt32 size = 0; |
| 106 pid_t hogPid = -1; | 102 pid_t hogPid = -1; |
| 107 | 103 |
| 108 _outputDeviceID = deviceID; | 104 _outputDeviceID = deviceID; |
| 109 | 105 |
| 110 // Check which process, if any, has hogged the device. | 106 // Check which process, if any, has hogged the device. |
| 111 AudioObjectPropertyAddress propertyAddress = { | 107 AudioObjectPropertyAddress propertyAddress = { |
| 112 kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeOutput, 0}; | 108 kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeOutput, 0}; |
| 113 | 109 |
| 114 size = sizeof(hogPid); | 110 size = sizeof(hogPid); |
| 115 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 111 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 116 _outputDeviceID, &propertyAddress, 0, NULL, &size, &hogPid)); | 112 _outputDeviceID, &propertyAddress, 0, NULL, &size, &hogPid)); |
| 117 | 113 |
| 118 if (hogPid == -1) { | 114 if (hogPid == -1) { |
| 119 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 115 LOG(LS_VERBOSE) << "No process has hogged the input device"; |
| 120 " No process has hogged the input device"); | |
| 121 } | 116 } |
| 122 // getpid() is apparently "always successful" | 117 // getpid() is apparently "always successful" |
| 123 else if (hogPid == getpid()) { | 118 else if (hogPid == getpid()) { |
| 124 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 119 LOG(LS_VERBOSE) << "Our process has hogged the input device"; |
| 125 " Our process has hogged the input device"); | |
| 126 } else { | 120 } else { |
| 127 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 121 LOG(LS_WARNING) << "Another process (pid = " << static_cast<int>(hogPid) |
| 128 " Another process (pid = %d) has hogged the input device", | 122 << ") has hogged the input device"; |
| 129 static_cast<int>(hogPid)); | |
| 130 | 123 |
| 131 return -1; | 124 return -1; |
| 132 } | 125 } |
| 133 | 126 |
| 134 // get number of channels from stream format | 127 // get number of channels from stream format |
| 135 propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; | 128 propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; |
| 136 | 129 |
| 137 // Get the stream format, to be able to read the number of channels. | 130 // Get the stream format, to be able to read the number of channels. |
| 138 AudioStreamBasicDescription streamFormat; | 131 AudioStreamBasicDescription streamFormat; |
| 139 size = sizeof(AudioStreamBasicDescription); | 132 size = sizeof(AudioStreamBasicDescription); |
| 140 memset(&streamFormat, 0, size); | 133 memset(&streamFormat, 0, size); |
| 141 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 134 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 142 _outputDeviceID, &propertyAddress, 0, NULL, &size, &streamFormat)); | 135 _outputDeviceID, &propertyAddress, 0, NULL, &size, &streamFormat)); |
| 143 | 136 |
| 144 _noOutputChannels = streamFormat.mChannelsPerFrame; | 137 _noOutputChannels = streamFormat.mChannelsPerFrame; |
| 145 | 138 |
| 146 return 0; | 139 return 0; |
| 147 } | 140 } |
| 148 | 141 |
| 149 int32_t AudioMixerManagerMac::OpenMicrophone(AudioDeviceID deviceID) { | 142 int32_t AudioMixerManagerMac::OpenMicrophone(AudioDeviceID deviceID) { |
| 150 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 143 LOG(LS_VERBOSE) << "AudioMixerManagerMac::OpenMicrophone(id=" << deviceID |
| 151 "AudioMixerManagerMac::OpenMicrophone(id=%d)", deviceID); | 144 << ")"; |
| 152 | 145 |
| 153 rtc::CritScope lock(&_critSect); | 146 rtc::CritScope lock(&_critSect); |
| 154 | 147 |
| 155 OSStatus err = noErr; | 148 OSStatus err = noErr; |
| 156 UInt32 size = 0; | 149 UInt32 size = 0; |
| 157 pid_t hogPid = -1; | 150 pid_t hogPid = -1; |
| 158 | 151 |
| 159 _inputDeviceID = deviceID; | 152 _inputDeviceID = deviceID; |
| 160 | 153 |
| 161 // Check which process, if any, has hogged the device. | 154 // Check which process, if any, has hogged the device. |
| 162 AudioObjectPropertyAddress propertyAddress = { | 155 AudioObjectPropertyAddress propertyAddress = { |
| 163 kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeInput, 0}; | 156 kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeInput, 0}; |
| 164 size = sizeof(hogPid); | 157 size = sizeof(hogPid); |
| 165 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 158 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 166 _inputDeviceID, &propertyAddress, 0, NULL, &size, &hogPid)); | 159 _inputDeviceID, &propertyAddress, 0, NULL, &size, &hogPid)); |
| 167 if (hogPid == -1) { | 160 if (hogPid == -1) { |
| 168 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 161 LOG(LS_VERBOSE) << "No process has hogged the input device"; |
| 169 " No process has hogged the input device"); | |
| 170 } | 162 } |
| 171 // getpid() is apparently "always successful" | 163 // getpid() is apparently "always successful" |
| 172 else if (hogPid == getpid()) { | 164 else if (hogPid == getpid()) { |
| 173 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 165 LOG(LS_VERBOSE) << "Our process has hogged the input device"; |
| 174 " Our process has hogged the input device"); | |
| 175 } else { | 166 } else { |
| 176 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 167 LOG(LS_WARNING) << "Another process (pid = " << static_cast<int>(hogPid) |
| 177 " Another process (pid = %d) has hogged the input device", | 168 << ") has hogged the input device"; |
| 178 static_cast<int>(hogPid)); | |
| 179 | 169 |
| 180 return -1; | 170 return -1; |
| 181 } | 171 } |
| 182 | 172 |
| 183 // get number of channels from stream format | 173 // get number of channels from stream format |
| 184 propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; | 174 propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; |
| 185 | 175 |
| 186 // Get the stream format, to be able to read the number of channels. | 176 // Get the stream format, to be able to read the number of channels. |
| 187 AudioStreamBasicDescription streamFormat; | 177 AudioStreamBasicDescription streamFormat; |
| 188 size = sizeof(AudioStreamBasicDescription); | 178 size = sizeof(AudioStreamBasicDescription); |
| 189 memset(&streamFormat, 0, size); | 179 memset(&streamFormat, 0, size); |
| 190 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 180 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 191 _inputDeviceID, &propertyAddress, 0, NULL, &size, &streamFormat)); | 181 _inputDeviceID, &propertyAddress, 0, NULL, &size, &streamFormat)); |
| 192 | 182 |
| 193 _noInputChannels = streamFormat.mChannelsPerFrame; | 183 _noInputChannels = streamFormat.mChannelsPerFrame; |
| 194 | 184 |
| 195 return 0; | 185 return 0; |
| 196 } | 186 } |
| 197 | 187 |
| 198 bool AudioMixerManagerMac::SpeakerIsInitialized() const { | 188 bool AudioMixerManagerMac::SpeakerIsInitialized() const { |
| 199 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__); | 189 LOG(LS_INFO) << __FUNCTION__; |
| 200 | 190 |
| 201 return (_outputDeviceID != kAudioObjectUnknown); | 191 return (_outputDeviceID != kAudioObjectUnknown); |
| 202 } | 192 } |
| 203 | 193 |
| 204 bool AudioMixerManagerMac::MicrophoneIsInitialized() const { | 194 bool AudioMixerManagerMac::MicrophoneIsInitialized() const { |
| 205 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__); | 195 LOG(LS_INFO) << __FUNCTION__; |
| 206 | 196 |
| 207 return (_inputDeviceID != kAudioObjectUnknown); | 197 return (_inputDeviceID != kAudioObjectUnknown); |
| 208 } | 198 } |
| 209 | 199 |
| 210 int32_t AudioMixerManagerMac::SetSpeakerVolume(uint32_t volume) { | 200 int32_t AudioMixerManagerMac::SetSpeakerVolume(uint32_t volume) { |
| 211 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 201 LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetSpeakerVolume(volume=" << volume |
| 212 "AudioMixerManagerMac::SetSpeakerVolume(volume=%u)", volume); | 202 << ")"; |
| 213 | 203 |
| 214 rtc::CritScope lock(&_critSect); | 204 rtc::CritScope lock(&_critSect); |
| 215 | 205 |
| 216 if (_outputDeviceID == kAudioObjectUnknown) { | 206 if (_outputDeviceID == kAudioObjectUnknown) { |
| 217 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 207 LOG(LS_WARNING) << "device ID has not been set"; |
| 218 " device ID has not been set"); | |
| 219 return -1; | 208 return -1; |
| 220 } | 209 } |
| 221 | 210 |
| 222 OSStatus err = noErr; | 211 OSStatus err = noErr; |
| 223 UInt32 size = 0; | 212 UInt32 size = 0; |
| 224 bool success = false; | 213 bool success = false; |
| 225 | 214 |
| 226 // volume range is 0.0 - 1.0, convert from 0 -255 | 215 // volume range is 0.0 - 1.0, convert from 0 -255 |
| 227 const Float32 vol = (Float32)(volume / 255.0); | 216 const Float32 vol = (Float32)(volume / 255.0); |
| 228 | 217 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 251 &isSettable); | 240 &isSettable); |
| 252 if (err == noErr && isSettable) { | 241 if (err == noErr && isSettable) { |
| 253 size = sizeof(vol); | 242 size = sizeof(vol); |
| 254 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( | 243 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( |
| 255 _outputDeviceID, &propertyAddress, 0, NULL, size, &vol)); | 244 _outputDeviceID, &propertyAddress, 0, NULL, size, &vol)); |
| 256 } | 245 } |
| 257 success = true; | 246 success = true; |
| 258 } | 247 } |
| 259 | 248 |
| 260 if (!success) { | 249 if (!success) { |
| 261 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 250 LOG(LS_WARNING) << "Unable to set a volume on any output channel"; |
| 262 " Unable to set a volume on any output channel"); | |
| 263 return -1; | 251 return -1; |
| 264 } | 252 } |
| 265 | 253 |
| 266 return 0; | 254 return 0; |
| 267 } | 255 } |
| 268 | 256 |
| 269 int32_t AudioMixerManagerMac::SpeakerVolume(uint32_t& volume) const { | 257 int32_t AudioMixerManagerMac::SpeakerVolume(uint32_t& volume) const { |
| 270 if (_outputDeviceID == kAudioObjectUnknown) { | 258 if (_outputDeviceID == kAudioObjectUnknown) { |
| 271 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 259 LOG(LS_WARNING) << "device ID has not been set"; |
| 272 " device ID has not been set"); | |
| 273 return -1; | 260 return -1; |
| 274 } | 261 } |
| 275 | 262 |
| 276 OSStatus err = noErr; | 263 OSStatus err = noErr; |
| 277 UInt32 size = 0; | 264 UInt32 size = 0; |
| 278 unsigned int channels = 0; | 265 unsigned int channels = 0; |
| 279 Float32 channelVol = 0; | 266 Float32 channelVol = 0; |
| 280 Float32 vol = 0; | 267 Float32 vol = 0; |
| 281 | 268 |
| 282 // Does the device have a master volume control? | 269 // Does the device have a master volume control? |
| (...skipping 20 matching lines...) Expand all Loading... |
| 303 size = sizeof(channelVol); | 290 size = sizeof(channelVol); |
| 304 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 291 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 305 _outputDeviceID, &propertyAddress, 0, NULL, &size, &channelVol)); | 292 _outputDeviceID, &propertyAddress, 0, NULL, &size, &channelVol)); |
| 306 | 293 |
| 307 vol += channelVol; | 294 vol += channelVol; |
| 308 channels++; | 295 channels++; |
| 309 } | 296 } |
| 310 } | 297 } |
| 311 | 298 |
| 312 if (channels == 0) { | 299 if (channels == 0) { |
| 313 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 300 LOG(LS_WARNING) << "Unable to get a volume on any channel"; |
| 314 " Unable to get a volume on any channel"); | |
| 315 return -1; | 301 return -1; |
| 316 } | 302 } |
| 317 | 303 |
| 318 assert(channels > 0); | 304 assert(channels > 0); |
| 319 // vol 0.0 to 1.0 -> convert to 0 - 255 | 305 // vol 0.0 to 1.0 -> convert to 0 - 255 |
| 320 volume = static_cast<uint32_t>(255 * vol / channels + 0.5); | 306 volume = static_cast<uint32_t>(255 * vol / channels + 0.5); |
| 321 } | 307 } |
| 322 | 308 |
| 323 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 309 LOG(LS_VERBOSE) << "AudioMixerManagerMac::SpeakerVolume() => vol=" << vol; |
| 324 " AudioMixerManagerMac::SpeakerVolume() => vol=%i", vol); | |
| 325 | 310 |
| 326 return 0; | 311 return 0; |
| 327 } | 312 } |
| 328 | 313 |
| 329 int32_t AudioMixerManagerMac::MaxSpeakerVolume(uint32_t& maxVolume) const { | 314 int32_t AudioMixerManagerMac::MaxSpeakerVolume(uint32_t& maxVolume) const { |
| 330 if (_outputDeviceID == kAudioObjectUnknown) { | 315 if (_outputDeviceID == kAudioObjectUnknown) { |
| 331 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 316 LOG(LS_WARNING) << "device ID has not been set"; |
| 332 " device ID has not been set"); | |
| 333 return -1; | 317 return -1; |
| 334 } | 318 } |
| 335 | 319 |
| 336 // volume range is 0.0 to 1.0 | 320 // volume range is 0.0 to 1.0 |
| 337 // we convert that to 0 - 255 | 321 // we convert that to 0 - 255 |
| 338 maxVolume = 255; | 322 maxVolume = 255; |
| 339 | 323 |
| 340 return 0; | 324 return 0; |
| 341 } | 325 } |
| 342 | 326 |
| 343 int32_t AudioMixerManagerMac::MinSpeakerVolume(uint32_t& minVolume) const { | 327 int32_t AudioMixerManagerMac::MinSpeakerVolume(uint32_t& minVolume) const { |
| 344 if (_outputDeviceID == kAudioObjectUnknown) { | 328 if (_outputDeviceID == kAudioObjectUnknown) { |
| 345 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 329 LOG(LS_WARNING) << "device ID has not been set"; |
| 346 " device ID has not been set"); | |
| 347 return -1; | 330 return -1; |
| 348 } | 331 } |
| 349 | 332 |
| 350 // volume range is 0.0 to 1.0 | 333 // volume range is 0.0 to 1.0 |
| 351 // we convert that to 0 - 255 | 334 // we convert that to 0 - 255 |
| 352 minVolume = 0; | 335 minVolume = 0; |
| 353 | 336 |
| 354 return 0; | 337 return 0; |
| 355 } | 338 } |
| 356 | 339 |
| 357 int32_t AudioMixerManagerMac::SpeakerVolumeStepSize(uint16_t& stepSize) const { | 340 int32_t AudioMixerManagerMac::SpeakerVolumeStepSize(uint16_t& stepSize) const { |
| 358 if (_outputDeviceID == kAudioObjectUnknown) { | 341 if (_outputDeviceID == kAudioObjectUnknown) { |
| 359 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 342 LOG(LS_WARNING) << "device ID has not been set"; |
| 360 " device ID has not been set"); | |
| 361 return -1; | 343 return -1; |
| 362 } | 344 } |
| 363 | 345 |
| 364 // volume range is 0.0 to 1.0 | 346 // volume range is 0.0 to 1.0 |
| 365 // we convert that to 0 - 255 | 347 // we convert that to 0 - 255 |
| 366 stepSize = 1; | 348 stepSize = 1; |
| 367 | 349 |
| 368 return 0; | 350 return 0; |
| 369 } | 351 } |
| 370 | 352 |
| 371 int32_t AudioMixerManagerMac::SpeakerVolumeIsAvailable(bool& available) { | 353 int32_t AudioMixerManagerMac::SpeakerVolumeIsAvailable(bool& available) { |
| 372 if (_outputDeviceID == kAudioObjectUnknown) { | 354 if (_outputDeviceID == kAudioObjectUnknown) { |
| 373 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 355 LOG(LS_WARNING) << "device ID has not been set"; |
| 374 " device ID has not been set"); | |
| 375 return -1; | 356 return -1; |
| 376 } | 357 } |
| 377 | 358 |
| 378 OSStatus err = noErr; | 359 OSStatus err = noErr; |
| 379 | 360 |
| 380 // Does the capture device have a master volume control? | 361 // Does the capture device have a master volume control? |
| 381 // If so, use it exclusively. | 362 // If so, use it exclusively. |
| 382 AudioObjectPropertyAddress propertyAddress = { | 363 AudioObjectPropertyAddress propertyAddress = { |
| 383 kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0}; | 364 kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0}; |
| 384 Boolean isSettable = false; | 365 Boolean isSettable = false; |
| 385 err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress, | 366 err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress, |
| 386 &isSettable); | 367 &isSettable); |
| 387 if (err == noErr && isSettable) { | 368 if (err == noErr && isSettable) { |
| 388 available = true; | 369 available = true; |
| 389 return 0; | 370 return 0; |
| 390 } | 371 } |
| 391 | 372 |
| 392 // Otherwise try to set each channel. | 373 // Otherwise try to set each channel. |
| 393 for (UInt32 i = 1; i <= _noOutputChannels; i++) { | 374 for (UInt32 i = 1; i <= _noOutputChannels; i++) { |
| 394 propertyAddress.mElement = i; | 375 propertyAddress.mElement = i; |
| 395 isSettable = false; | 376 isSettable = false; |
| 396 err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress, | 377 err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress, |
| 397 &isSettable); | 378 &isSettable); |
| 398 if (err != noErr || !isSettable) { | 379 if (err != noErr || !isSettable) { |
| 399 available = false; | 380 available = false; |
| 400 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 381 LOG(LS_WARNING) << "Volume cannot be set for output channel " << i |
| 401 " Volume cannot be set for output channel %d, err=%d", i, | 382 << ", err=" << err; |
| 402 err); | |
| 403 return -1; | 383 return -1; |
| 404 } | 384 } |
| 405 } | 385 } |
| 406 | 386 |
| 407 available = true; | 387 available = true; |
| 408 return 0; | 388 return 0; |
| 409 } | 389 } |
| 410 | 390 |
| 411 int32_t AudioMixerManagerMac::SpeakerMuteIsAvailable(bool& available) { | 391 int32_t AudioMixerManagerMac::SpeakerMuteIsAvailable(bool& available) { |
| 412 if (_outputDeviceID == kAudioObjectUnknown) { | 392 if (_outputDeviceID == kAudioObjectUnknown) { |
| 413 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 393 LOG(LS_WARNING) << "device ID has not been set"; |
| 414 " device ID has not been set"); | |
| 415 return -1; | 394 return -1; |
| 416 } | 395 } |
| 417 | 396 |
| 418 OSStatus err = noErr; | 397 OSStatus err = noErr; |
| 419 | 398 |
| 420 // Does the capture device have a master mute control? | 399 // Does the capture device have a master mute control? |
| 421 // If so, use it exclusively. | 400 // If so, use it exclusively. |
| 422 AudioObjectPropertyAddress propertyAddress = { | 401 AudioObjectPropertyAddress propertyAddress = { |
| 423 kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0}; | 402 kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0}; |
| 424 Boolean isSettable = false; | 403 Boolean isSettable = false; |
| 425 err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress, | 404 err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress, |
| 426 &isSettable); | 405 &isSettable); |
| 427 if (err == noErr && isSettable) { | 406 if (err == noErr && isSettable) { |
| 428 available = true; | 407 available = true; |
| 429 return 0; | 408 return 0; |
| 430 } | 409 } |
| 431 | 410 |
| 432 // Otherwise try to set each channel. | 411 // Otherwise try to set each channel. |
| 433 for (UInt32 i = 1; i <= _noOutputChannels; i++) { | 412 for (UInt32 i = 1; i <= _noOutputChannels; i++) { |
| 434 propertyAddress.mElement = i; | 413 propertyAddress.mElement = i; |
| 435 isSettable = false; | 414 isSettable = false; |
| 436 err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress, | 415 err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress, |
| 437 &isSettable); | 416 &isSettable); |
| 438 if (err != noErr || !isSettable) { | 417 if (err != noErr || !isSettable) { |
| 439 available = false; | 418 available = false; |
| 440 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 419 LOG(LS_WARNING) << "Mute cannot be set for output channel " << i |
| 441 " Mute cannot be set for output channel %d, err=%d", i, err); | 420 << ", err=" << err; |
| 442 return -1; | 421 return -1; |
| 443 } | 422 } |
| 444 } | 423 } |
| 445 | 424 |
| 446 available = true; | 425 available = true; |
| 447 return 0; | 426 return 0; |
| 448 } | 427 } |
| 449 | 428 |
| 450 int32_t AudioMixerManagerMac::SetSpeakerMute(bool enable) { | 429 int32_t AudioMixerManagerMac::SetSpeakerMute(bool enable) { |
| 451 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 430 LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetSpeakerMute(enable=" << enable |
| 452 "AudioMixerManagerMac::SetSpeakerMute(enable=%u)", enable); | 431 << ")"; |
| 453 | 432 |
| 454 rtc::CritScope lock(&_critSect); | 433 rtc::CritScope lock(&_critSect); |
| 455 | 434 |
| 456 if (_outputDeviceID == kAudioObjectUnknown) { | 435 if (_outputDeviceID == kAudioObjectUnknown) { |
| 457 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 436 LOG(LS_WARNING) << "device ID has not been set"; |
| 458 " device ID has not been set"); | |
| 459 return -1; | 437 return -1; |
| 460 } | 438 } |
| 461 | 439 |
| 462 OSStatus err = noErr; | 440 OSStatus err = noErr; |
| 463 UInt32 size = 0; | 441 UInt32 size = 0; |
| 464 UInt32 mute = enable ? 1 : 0; | 442 UInt32 mute = enable ? 1 : 0; |
| 465 bool success = false; | 443 bool success = false; |
| 466 | 444 |
| 467 // Does the render device have a master mute control? | 445 // Does the render device have a master mute control? |
| 468 // If so, use it exclusively. | 446 // If so, use it exclusively. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 487 &isSettable); | 465 &isSettable); |
| 488 if (err == noErr && isSettable) { | 466 if (err == noErr && isSettable) { |
| 489 size = sizeof(mute); | 467 size = sizeof(mute); |
| 490 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( | 468 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( |
| 491 _outputDeviceID, &propertyAddress, 0, NULL, size, &mute)); | 469 _outputDeviceID, &propertyAddress, 0, NULL, size, &mute)); |
| 492 } | 470 } |
| 493 success = true; | 471 success = true; |
| 494 } | 472 } |
| 495 | 473 |
| 496 if (!success) { | 474 if (!success) { |
| 497 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 475 LOG(LS_WARNING) << "Unable to set mute on any input channel"; |
| 498 " Unable to set mute on any input channel"); | |
| 499 return -1; | 476 return -1; |
| 500 } | 477 } |
| 501 | 478 |
| 502 return 0; | 479 return 0; |
| 503 } | 480 } |
| 504 | 481 |
| 505 int32_t AudioMixerManagerMac::SpeakerMute(bool& enabled) const { | 482 int32_t AudioMixerManagerMac::SpeakerMute(bool& enabled) const { |
| 506 if (_outputDeviceID == kAudioObjectUnknown) { | 483 if (_outputDeviceID == kAudioObjectUnknown) { |
| 507 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 484 LOG(LS_WARNING) << "device ID has not been set"; |
| 508 " device ID has not been set"); | |
| 509 return -1; | 485 return -1; |
| 510 } | 486 } |
| 511 | 487 |
| 512 OSStatus err = noErr; | 488 OSStatus err = noErr; |
| 513 UInt32 size = 0; | 489 UInt32 size = 0; |
| 514 unsigned int channels = 0; | 490 unsigned int channels = 0; |
| 515 UInt32 channelMuted = 0; | 491 UInt32 channelMuted = 0; |
| 516 UInt32 muted = 0; | 492 UInt32 muted = 0; |
| 517 | 493 |
| 518 // Does the device have a master volume control? | 494 // Does the device have a master volume control? |
| (...skipping 19 matching lines...) Expand all Loading... |
| 538 size = sizeof(channelMuted); | 514 size = sizeof(channelMuted); |
| 539 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 515 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 540 _outputDeviceID, &propertyAddress, 0, NULL, &size, &channelMuted)); | 516 _outputDeviceID, &propertyAddress, 0, NULL, &size, &channelMuted)); |
| 541 | 517 |
| 542 muted = (muted && channelMuted); | 518 muted = (muted && channelMuted); |
| 543 channels++; | 519 channels++; |
| 544 } | 520 } |
| 545 } | 521 } |
| 546 | 522 |
| 547 if (channels == 0) { | 523 if (channels == 0) { |
| 548 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 524 LOG(LS_WARNING) << "Unable to get mute for any channel"; |
| 549 " Unable to get mute for any channel"); | |
| 550 return -1; | 525 return -1; |
| 551 } | 526 } |
| 552 | 527 |
| 553 assert(channels > 0); | 528 assert(channels > 0); |
| 554 // 1 means muted | 529 // 1 means muted |
| 555 enabled = static_cast<bool>(muted); | 530 enabled = static_cast<bool>(muted); |
| 556 } | 531 } |
| 557 | 532 |
| 558 WEBRTC_TRACE( | 533 LOG(LS_VERBOSE) << "AudioMixerManagerMac::SpeakerMute() => enabled=" |
| 559 kTraceInfo, kTraceAudioDevice, _id, | 534 << enabled; |
| 560 " AudioMixerManagerMac::SpeakerMute() => enabled=%d, enabled"); | |
| 561 | 535 |
| 562 return 0; | 536 return 0; |
| 563 } | 537 } |
| 564 | 538 |
| 565 int32_t AudioMixerManagerMac::StereoPlayoutIsAvailable(bool& available) { | 539 int32_t AudioMixerManagerMac::StereoPlayoutIsAvailable(bool& available) { |
| 566 if (_outputDeviceID == kAudioObjectUnknown) { | 540 if (_outputDeviceID == kAudioObjectUnknown) { |
| 567 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 541 LOG(LS_WARNING) << "device ID has not been set"; |
| 568 " device ID has not been set"); | |
| 569 return -1; | 542 return -1; |
| 570 } | 543 } |
| 571 | 544 |
| 572 available = (_noOutputChannels == 2); | 545 available = (_noOutputChannels == 2); |
| 573 return 0; | 546 return 0; |
| 574 } | 547 } |
| 575 | 548 |
| 576 int32_t AudioMixerManagerMac::StereoRecordingIsAvailable(bool& available) { | 549 int32_t AudioMixerManagerMac::StereoRecordingIsAvailable(bool& available) { |
| 577 if (_inputDeviceID == kAudioObjectUnknown) { | 550 if (_inputDeviceID == kAudioObjectUnknown) { |
| 578 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 551 LOG(LS_WARNING) << "device ID has not been set"; |
| 579 " device ID has not been set"); | |
| 580 return -1; | 552 return -1; |
| 581 } | 553 } |
| 582 | 554 |
| 583 available = (_noInputChannels == 2); | 555 available = (_noInputChannels == 2); |
| 584 return 0; | 556 return 0; |
| 585 } | 557 } |
| 586 | 558 |
| 587 int32_t AudioMixerManagerMac::MicrophoneMuteIsAvailable(bool& available) { | 559 int32_t AudioMixerManagerMac::MicrophoneMuteIsAvailable(bool& available) { |
| 588 if (_inputDeviceID == kAudioObjectUnknown) { | 560 if (_inputDeviceID == kAudioObjectUnknown) { |
| 589 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 561 LOG(LS_WARNING) << "device ID has not been set"; |
| 590 " device ID has not been set"); | |
| 591 return -1; | 562 return -1; |
| 592 } | 563 } |
| 593 | 564 |
| 594 OSStatus err = noErr; | 565 OSStatus err = noErr; |
| 595 | 566 |
| 596 // Does the capture device have a master mute control? | 567 // Does the capture device have a master mute control? |
| 597 // If so, use it exclusively. | 568 // If so, use it exclusively. |
| 598 AudioObjectPropertyAddress propertyAddress = { | 569 AudioObjectPropertyAddress propertyAddress = { |
| 599 kAudioDevicePropertyMute, kAudioDevicePropertyScopeInput, 0}; | 570 kAudioDevicePropertyMute, kAudioDevicePropertyScopeInput, 0}; |
| 600 Boolean isSettable = false; | 571 Boolean isSettable = false; |
| 601 err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress, | 572 err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress, |
| 602 &isSettable); | 573 &isSettable); |
| 603 if (err == noErr && isSettable) { | 574 if (err == noErr && isSettable) { |
| 604 available = true; | 575 available = true; |
| 605 return 0; | 576 return 0; |
| 606 } | 577 } |
| 607 | 578 |
| 608 // Otherwise try to set each channel. | 579 // Otherwise try to set each channel. |
| 609 for (UInt32 i = 1; i <= _noInputChannels; i++) { | 580 for (UInt32 i = 1; i <= _noInputChannels; i++) { |
| 610 propertyAddress.mElement = i; | 581 propertyAddress.mElement = i; |
| 611 isSettable = false; | 582 isSettable = false; |
| 612 err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress, | 583 err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress, |
| 613 &isSettable); | 584 &isSettable); |
| 614 if (err != noErr || !isSettable) { | 585 if (err != noErr || !isSettable) { |
| 615 available = false; | 586 available = false; |
| 616 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 587 LOG(LS_WARNING) << "Mute cannot be set for output channel " << i |
| 617 " Mute cannot be set for output channel %d, err=%d", i, err); | 588 << ", err=" << err; |
| 618 return -1; | 589 return -1; |
| 619 } | 590 } |
| 620 } | 591 } |
| 621 | 592 |
| 622 available = true; | 593 available = true; |
| 623 return 0; | 594 return 0; |
| 624 } | 595 } |
| 625 | 596 |
| 626 int32_t AudioMixerManagerMac::SetMicrophoneMute(bool enable) { | 597 int32_t AudioMixerManagerMac::SetMicrophoneMute(bool enable) { |
| 627 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 598 LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetMicrophoneMute(enable=" << enable |
| 628 "AudioMixerManagerMac::SetMicrophoneMute(enable=%u)", enable); | 599 << ")"; |
| 629 | 600 |
| 630 rtc::CritScope lock(&_critSect); | 601 rtc::CritScope lock(&_critSect); |
| 631 | 602 |
| 632 if (_inputDeviceID == kAudioObjectUnknown) { | 603 if (_inputDeviceID == kAudioObjectUnknown) { |
| 633 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 604 LOG(LS_WARNING) << "device ID has not been set"; |
| 634 " device ID has not been set"); | |
| 635 return -1; | 605 return -1; |
| 636 } | 606 } |
| 637 | 607 |
| 638 OSStatus err = noErr; | 608 OSStatus err = noErr; |
| 639 UInt32 size = 0; | 609 UInt32 size = 0; |
| 640 UInt32 mute = enable ? 1 : 0; | 610 UInt32 mute = enable ? 1 : 0; |
| 641 bool success = false; | 611 bool success = false; |
| 642 | 612 |
| 643 // Does the capture device have a master mute control? | 613 // Does the capture device have a master mute control? |
| 644 // If so, use it exclusively. | 614 // If so, use it exclusively. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 663 &isSettable); | 633 &isSettable); |
| 664 if (err == noErr && isSettable) { | 634 if (err == noErr && isSettable) { |
| 665 size = sizeof(mute); | 635 size = sizeof(mute); |
| 666 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( | 636 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( |
| 667 _inputDeviceID, &propertyAddress, 0, NULL, size, &mute)); | 637 _inputDeviceID, &propertyAddress, 0, NULL, size, &mute)); |
| 668 } | 638 } |
| 669 success = true; | 639 success = true; |
| 670 } | 640 } |
| 671 | 641 |
| 672 if (!success) { | 642 if (!success) { |
| 673 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 643 LOG(LS_WARNING) << "Unable to set mute on any input channel"; |
| 674 " Unable to set mute on any input channel"); | |
| 675 return -1; | 644 return -1; |
| 676 } | 645 } |
| 677 | 646 |
| 678 return 0; | 647 return 0; |
| 679 } | 648 } |
| 680 | 649 |
| 681 int32_t AudioMixerManagerMac::MicrophoneMute(bool& enabled) const { | 650 int32_t AudioMixerManagerMac::MicrophoneMute(bool& enabled) const { |
| 682 if (_inputDeviceID == kAudioObjectUnknown) { | 651 if (_inputDeviceID == kAudioObjectUnknown) { |
| 683 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 652 LOG(LS_WARNING) << "device ID has not been set"; |
| 684 " device ID has not been set"); | |
| 685 return -1; | 653 return -1; |
| 686 } | 654 } |
| 687 | 655 |
| 688 OSStatus err = noErr; | 656 OSStatus err = noErr; |
| 689 UInt32 size = 0; | 657 UInt32 size = 0; |
| 690 unsigned int channels = 0; | 658 unsigned int channels = 0; |
| 691 UInt32 channelMuted = 0; | 659 UInt32 channelMuted = 0; |
| 692 UInt32 muted = 0; | 660 UInt32 muted = 0; |
| 693 | 661 |
| 694 // Does the device have a master volume control? | 662 // Does the device have a master volume control? |
| (...skipping 19 matching lines...) Expand all Loading... |
| 714 size = sizeof(channelMuted); | 682 size = sizeof(channelMuted); |
| 715 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 683 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 716 _inputDeviceID, &propertyAddress, 0, NULL, &size, &channelMuted)); | 684 _inputDeviceID, &propertyAddress, 0, NULL, &size, &channelMuted)); |
| 717 | 685 |
| 718 muted = (muted && channelMuted); | 686 muted = (muted && channelMuted); |
| 719 channels++; | 687 channels++; |
| 720 } | 688 } |
| 721 } | 689 } |
| 722 | 690 |
| 723 if (channels == 0) { | 691 if (channels == 0) { |
| 724 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 692 LOG(LS_WARNING) << "Unable to get mute for any channel"; |
| 725 " Unable to get mute for any channel"); | |
| 726 return -1; | 693 return -1; |
| 727 } | 694 } |
| 728 | 695 |
| 729 assert(channels > 0); | 696 assert(channels > 0); |
| 730 // 1 means muted | 697 // 1 means muted |
| 731 enabled = static_cast<bool>(muted); | 698 enabled = static_cast<bool>(muted); |
| 732 } | 699 } |
| 733 | 700 |
| 734 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 701 LOG(LS_VERBOSE) << "AudioMixerManagerMac::MicrophoneMute() => enabled=" |
| 735 " AudioMixerManagerMac::MicrophoneMute() => enabled=%d", | 702 << enabled; |
| 736 enabled); | |
| 737 | 703 |
| 738 return 0; | 704 return 0; |
| 739 } | 705 } |
| 740 | 706 |
| 741 int32_t AudioMixerManagerMac::MicrophoneBoostIsAvailable(bool& available) { | 707 int32_t AudioMixerManagerMac::MicrophoneBoostIsAvailable(bool& available) { |
| 742 if (_inputDeviceID == kAudioObjectUnknown) { | 708 if (_inputDeviceID == kAudioObjectUnknown) { |
| 743 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 709 LOG(LS_WARNING) << "device ID has not been set"; |
| 744 " device ID has not been set"); | |
| 745 return -1; | 710 return -1; |
| 746 } | 711 } |
| 747 | 712 |
| 748 available = false; // No AudioObjectPropertySelector value for Mic Boost | 713 available = false; // No AudioObjectPropertySelector value for Mic Boost |
| 749 | 714 |
| 750 return 0; | 715 return 0; |
| 751 } | 716 } |
| 752 | 717 |
| 753 int32_t AudioMixerManagerMac::SetMicrophoneBoost(bool enable) { | 718 int32_t AudioMixerManagerMac::SetMicrophoneBoost(bool enable) { |
| 754 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 719 LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetMicrophoneBoost(enable=" |
| 755 "AudioMixerManagerMac::SetMicrophoneBoost(enable=%u)", enable); | 720 << enable << ")"; |
| 756 | 721 |
| 757 rtc::CritScope lock(&_critSect); | 722 rtc::CritScope lock(&_critSect); |
| 758 | 723 |
| 759 if (_inputDeviceID == kAudioObjectUnknown) { | 724 if (_inputDeviceID == kAudioObjectUnknown) { |
| 760 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 725 LOG(LS_WARNING) << "device ID has not been set"; |
| 761 " device ID has not been set"); | |
| 762 return -1; | 726 return -1; |
| 763 } | 727 } |
| 764 | 728 |
| 765 // Ensure that the selected microphone has a valid boost control. | 729 // Ensure that the selected microphone has a valid boost control. |
| 766 bool available(false); | 730 bool available(false); |
| 767 MicrophoneBoostIsAvailable(available); | 731 MicrophoneBoostIsAvailable(available); |
| 768 if (!available) { | 732 if (!available) { |
| 769 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 733 LOG(LS_WARNING) << "it is not possible to enable microphone boost"; |
| 770 " it is not possible to enable microphone boost"); | |
| 771 return -1; | 734 return -1; |
| 772 } | 735 } |
| 773 | 736 |
| 774 // It is assumed that the call above fails! | 737 // It is assumed that the call above fails! |
| 775 return 0; | 738 return 0; |
| 776 } | 739 } |
| 777 | 740 |
| 778 int32_t AudioMixerManagerMac::MicrophoneBoost(bool& enabled) const { | 741 int32_t AudioMixerManagerMac::MicrophoneBoost(bool& enabled) const { |
| 779 if (_inputDeviceID == kAudioObjectUnknown) { | 742 if (_inputDeviceID == kAudioObjectUnknown) { |
| 780 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 743 LOG(LS_WARNING) << "device ID has not been set"; |
| 781 " device ID has not been set"); | |
| 782 return -1; | 744 return -1; |
| 783 } | 745 } |
| 784 | 746 |
| 785 // Microphone boost cannot be enabled on this platform! | 747 // Microphone boost cannot be enabled on this platform! |
| 786 enabled = false; | 748 enabled = false; |
| 787 | 749 |
| 788 return 0; | 750 return 0; |
| 789 } | 751 } |
| 790 | 752 |
| 791 int32_t AudioMixerManagerMac::MicrophoneVolumeIsAvailable(bool& available) { | 753 int32_t AudioMixerManagerMac::MicrophoneVolumeIsAvailable(bool& available) { |
| 792 if (_inputDeviceID == kAudioObjectUnknown) { | 754 if (_inputDeviceID == kAudioObjectUnknown) { |
| 793 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 755 LOG(LS_WARNING) << "device ID has not been set"; |
| 794 " device ID has not been set"); | |
| 795 return -1; | 756 return -1; |
| 796 } | 757 } |
| 797 | 758 |
| 798 OSStatus err = noErr; | 759 OSStatus err = noErr; |
| 799 | 760 |
| 800 // Does the capture device have a master volume control? | 761 // Does the capture device have a master volume control? |
| 801 // If so, use it exclusively. | 762 // If so, use it exclusively. |
| 802 AudioObjectPropertyAddress propertyAddress = { | 763 AudioObjectPropertyAddress propertyAddress = { |
| 803 kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeInput, 0}; | 764 kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeInput, 0}; |
| 804 Boolean isSettable = false; | 765 Boolean isSettable = false; |
| 805 err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress, | 766 err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress, |
| 806 &isSettable); | 767 &isSettable); |
| 807 if (err == noErr && isSettable) { | 768 if (err == noErr && isSettable) { |
| 808 available = true; | 769 available = true; |
| 809 return 0; | 770 return 0; |
| 810 } | 771 } |
| 811 | 772 |
| 812 // Otherwise try to set each channel. | 773 // Otherwise try to set each channel. |
| 813 for (UInt32 i = 1; i <= _noInputChannels; i++) { | 774 for (UInt32 i = 1; i <= _noInputChannels; i++) { |
| 814 propertyAddress.mElement = i; | 775 propertyAddress.mElement = i; |
| 815 isSettable = false; | 776 isSettable = false; |
| 816 err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress, | 777 err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress, |
| 817 &isSettable); | 778 &isSettable); |
| 818 if (err != noErr || !isSettable) { | 779 if (err != noErr || !isSettable) { |
| 819 available = false; | 780 available = false; |
| 820 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 781 LOG(LS_WARNING) << "Volume cannot be set for input channel " << i |
| 821 " Volume cannot be set for input channel %d, err=%d", i, | 782 << ", err=" << err; |
| 822 err); | |
| 823 return -1; | 783 return -1; |
| 824 } | 784 } |
| 825 } | 785 } |
| 826 | 786 |
| 827 available = true; | 787 available = true; |
| 828 return 0; | 788 return 0; |
| 829 } | 789 } |
| 830 | 790 |
| 831 int32_t AudioMixerManagerMac::SetMicrophoneVolume(uint32_t volume) { | 791 int32_t AudioMixerManagerMac::SetMicrophoneVolume(uint32_t volume) { |
| 832 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 792 LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetMicrophoneVolume(volume=" |
| 833 "AudioMixerManagerMac::SetMicrophoneVolume(volume=%u)", volume); | 793 << volume << ")"; |
| 834 | 794 |
| 835 rtc::CritScope lock(&_critSect); | 795 rtc::CritScope lock(&_critSect); |
| 836 | 796 |
| 837 if (_inputDeviceID == kAudioObjectUnknown) { | 797 if (_inputDeviceID == kAudioObjectUnknown) { |
| 838 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 798 LOG(LS_WARNING) << "device ID has not been set"; |
| 839 " device ID has not been set"); | |
| 840 return -1; | 799 return -1; |
| 841 } | 800 } |
| 842 | 801 |
| 843 OSStatus err = noErr; | 802 OSStatus err = noErr; |
| 844 UInt32 size = 0; | 803 UInt32 size = 0; |
| 845 bool success = false; | 804 bool success = false; |
| 846 | 805 |
| 847 // volume range is 0.0 - 1.0, convert from 0 - 255 | 806 // volume range is 0.0 - 1.0, convert from 0 - 255 |
| 848 const Float32 vol = (Float32)(volume / 255.0); | 807 const Float32 vol = (Float32)(volume / 255.0); |
| 849 | 808 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 872 &isSettable); | 831 &isSettable); |
| 873 if (err == noErr && isSettable) { | 832 if (err == noErr && isSettable) { |
| 874 size = sizeof(vol); | 833 size = sizeof(vol); |
| 875 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( | 834 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( |
| 876 _inputDeviceID, &propertyAddress, 0, NULL, size, &vol)); | 835 _inputDeviceID, &propertyAddress, 0, NULL, size, &vol)); |
| 877 } | 836 } |
| 878 success = true; | 837 success = true; |
| 879 } | 838 } |
| 880 | 839 |
| 881 if (!success) { | 840 if (!success) { |
| 882 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 841 LOG(LS_WARNING) << "Unable to set a level on any input channel"; |
| 883 " Unable to set a level on any input channel"); | |
| 884 return -1; | 842 return -1; |
| 885 } | 843 } |
| 886 | 844 |
| 887 return 0; | 845 return 0; |
| 888 } | 846 } |
| 889 | 847 |
| 890 int32_t AudioMixerManagerMac::MicrophoneVolume(uint32_t& volume) const { | 848 int32_t AudioMixerManagerMac::MicrophoneVolume(uint32_t& volume) const { |
| 891 if (_inputDeviceID == kAudioObjectUnknown) { | 849 if (_inputDeviceID == kAudioObjectUnknown) { |
| 892 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 850 LOG(LS_WARNING) << "device ID has not been set"; |
| 893 " device ID has not been set"); | |
| 894 return -1; | 851 return -1; |
| 895 } | 852 } |
| 896 | 853 |
| 897 OSStatus err = noErr; | 854 OSStatus err = noErr; |
| 898 UInt32 size = 0; | 855 UInt32 size = 0; |
| 899 unsigned int channels = 0; | 856 unsigned int channels = 0; |
| 900 Float32 channelVol = 0; | 857 Float32 channelVol = 0; |
| 901 Float32 volFloat32 = 0; | 858 Float32 volFloat32 = 0; |
| 902 | 859 |
| 903 // Does the device have a master volume control? | 860 // Does the device have a master volume control? |
| (...skipping 20 matching lines...) Expand all Loading... |
| 924 size = sizeof(channelVol); | 881 size = sizeof(channelVol); |
| 925 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 882 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 926 _inputDeviceID, &propertyAddress, 0, NULL, &size, &channelVol)); | 883 _inputDeviceID, &propertyAddress, 0, NULL, &size, &channelVol)); |
| 927 | 884 |
| 928 volFloat32 += channelVol; | 885 volFloat32 += channelVol; |
| 929 channels++; | 886 channels++; |
| 930 } | 887 } |
| 931 } | 888 } |
| 932 | 889 |
| 933 if (channels == 0) { | 890 if (channels == 0) { |
| 934 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 891 LOG(LS_WARNING) << "Unable to get a level on any channel"; |
| 935 " Unable to get a level on any channel"); | |
| 936 return -1; | 892 return -1; |
| 937 } | 893 } |
| 938 | 894 |
| 939 assert(channels > 0); | 895 assert(channels > 0); |
| 940 // vol 0.0 to 1.0 -> convert to 0 - 255 | 896 // vol 0.0 to 1.0 -> convert to 0 - 255 |
| 941 volume = static_cast<uint32_t>(255 * volFloat32 / channels + 0.5); | 897 volume = static_cast<uint32_t>(255 * volFloat32 / channels + 0.5); |
| 942 } | 898 } |
| 943 | 899 |
| 944 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 900 LOG(LS_VERBOSE) << "AudioMixerManagerMac::MicrophoneVolume() => vol=" |
| 945 " AudioMixerManagerMac::MicrophoneVolume() => vol=%u", | 901 << volume; |
| 946 volume); | |
| 947 | 902 |
| 948 return 0; | 903 return 0; |
| 949 } | 904 } |
| 950 | 905 |
| 951 int32_t AudioMixerManagerMac::MaxMicrophoneVolume(uint32_t& maxVolume) const { | 906 int32_t AudioMixerManagerMac::MaxMicrophoneVolume(uint32_t& maxVolume) const { |
| 952 if (_inputDeviceID == kAudioObjectUnknown) { | 907 if (_inputDeviceID == kAudioObjectUnknown) { |
| 953 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 908 LOG(LS_WARNING) << "device ID has not been set"; |
| 954 " device ID has not been set"); | |
| 955 return -1; | 909 return -1; |
| 956 } | 910 } |
| 957 | 911 |
| 958 // volume range is 0.0 to 1.0 | 912 // volume range is 0.0 to 1.0 |
| 959 // we convert that to 0 - 255 | 913 // we convert that to 0 - 255 |
| 960 maxVolume = 255; | 914 maxVolume = 255; |
| 961 | 915 |
| 962 return 0; | 916 return 0; |
| 963 } | 917 } |
| 964 | 918 |
| 965 int32_t AudioMixerManagerMac::MinMicrophoneVolume(uint32_t& minVolume) const { | 919 int32_t AudioMixerManagerMac::MinMicrophoneVolume(uint32_t& minVolume) const { |
| 966 if (_inputDeviceID == kAudioObjectUnknown) { | 920 if (_inputDeviceID == kAudioObjectUnknown) { |
| 967 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 921 LOG(LS_WARNING) << "device ID has not been set"; |
| 968 " device ID has not been set"); | |
| 969 return -1; | 922 return -1; |
| 970 } | 923 } |
| 971 | 924 |
| 972 // volume range is 0.0 to 1.0 | 925 // volume range is 0.0 to 1.0 |
| 973 // we convert that to 0 - 10 | 926 // we convert that to 0 - 10 |
| 974 minVolume = 0; | 927 minVolume = 0; |
| 975 | 928 |
| 976 return 0; | 929 return 0; |
| 977 } | 930 } |
| 978 | 931 |
| 979 int32_t AudioMixerManagerMac::MicrophoneVolumeStepSize( | 932 int32_t AudioMixerManagerMac::MicrophoneVolumeStepSize( |
| 980 uint16_t& stepSize) const { | 933 uint16_t& stepSize) const { |
| 981 if (_inputDeviceID == kAudioObjectUnknown) { | 934 if (_inputDeviceID == kAudioObjectUnknown) { |
| 982 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 935 LOG(LS_WARNING) << "device ID has not been set"; |
| 983 " device ID has not been set"); | |
| 984 return -1; | 936 return -1; |
| 985 } | 937 } |
| 986 | 938 |
| 987 // volume range is 0.0 to 1.0 | 939 // volume range is 0.0 to 1.0 |
| 988 // we convert that to 0 - 10 | 940 // we convert that to 0 - 10 |
| 989 stepSize = 1; | 941 stepSize = 1; |
| 990 | 942 |
| 991 return 0; | 943 return 0; |
| 992 } | 944 } |
| 993 | 945 |
| 994 // ============================================================================ | 946 // ============================================================================ |
| 995 // Private Methods | 947 // Private Methods |
| 996 // ============================================================================ | 948 // ============================================================================ |
| 997 | 949 |
| 998 // CoreAudio errors are best interpreted as four character strings. | 950 // CoreAudio errors are best interpreted as four character strings. |
| 999 void AudioMixerManagerMac::logCAMsg(const TraceLevel level, | 951 void AudioMixerManagerMac::logCAMsg(const rtc::LoggingSeverity sev, |
| 1000 const TraceModule module, | 952 const char* msg, |
| 1001 const int32_t id, | 953 const char* err) { |
| 1002 const char* msg, | 954 RTC_DCHECK(msg != NULL); |
| 1003 const char* err) { | 955 RTC_DCHECK(err != NULL); |
| 1004 assert(msg != NULL); | 956 RTC_DCHECK(sev == rtc::LS_ERROR || sev == rtc::LS_WARNING); |
| 1005 assert(err != NULL); | |
| 1006 | 957 |
| 1007 #ifdef WEBRTC_ARCH_BIG_ENDIAN | 958 #ifdef WEBRTC_ARCH_BIG_ENDIAN |
| 1008 WEBRTC_TRACE(level, module, id, "%s: %.4s", msg, err); | 959 switch (sev) { |
| 960 case rtc::LS_ERROR: |
| 961 LOG(LS_ERROR) << msg << ": " << err[0] << err[1] << err[2] << err[3]; |
| 962 break; |
| 963 case rtc::LS_WARNING: |
| 964 LOG(LS_WARNING) << msg << ": " << err[0] << err[1] << err[2] << err[3]; |
| 965 break; |
| 966 default: |
| 967 break; |
| 968 } |
| 1009 #else | 969 #else |
| 1010 // We need to flip the characters in this case. | 970 // We need to flip the characters in this case. |
| 1011 WEBRTC_TRACE(level, module, id, "%s: %.1s%.1s%.1s%.1s", msg, err + 3, err + 2, | 971 switch (sev) { |
| 1012 err + 1, err); | 972 case rtc::LS_ERROR: |
| 973 LOG(LS_ERROR) << msg << ": " << err[3] << err[2] << err[1] << err[0]; |
| 974 break; |
| 975 case rtc::LS_WARNING: |
| 976 LOG(LS_WARNING) << msg << ": " << err[3] << err[2] << err[1] << err[0]; |
| 977 break; |
| 978 default: |
| 979 break; |
| 980 } |
| 1013 #endif | 981 #endif |
| 1014 } | 982 } |
| 1015 | 983 |
| 1016 } // namespace webrtc | 984 } // namespace webrtc |
| 1017 // EOF | 985 // EOF |
| OLD | NEW |