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