Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc

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

Powered by Google App Engine
This is Rietveld 408576698