aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc')
-rw-r--r--webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc1907
1 files changed, 881 insertions, 1026 deletions
diff --git a/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc b/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc
index 9016ffe508..e7e0754695 100644
--- a/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc
+++ b/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc
@@ -11,1134 +11,989 @@
#include "webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h"
#include "webrtc/system_wrappers/include/trace.h"
-#include <unistd.h> // getpid()
+#include <unistd.h> // getpid()
namespace webrtc {
-
-#define WEBRTC_CA_RETURN_ON_ERR(expr) \
- do { \
- err = expr; \
- if (err != noErr) { \
- logCAMsg(kTraceError, kTraceAudioDevice, _id, \
- "Error in " #expr, (const char *)&err); \
- return -1; \
- } \
- } while(0)
-
-#define WEBRTC_CA_LOG_ERR(expr) \
- do { \
- err = expr; \
- if (err != noErr) { \
- logCAMsg(kTraceError, kTraceAudioDevice, _id, \
- "Error in " #expr, (const char *)&err); \
- } \
- } while(0)
-
-#define WEBRTC_CA_LOG_WARN(expr) \
- do { \
- err = expr; \
- if (err != noErr) { \
- logCAMsg(kTraceWarning, kTraceAudioDevice, _id, \
- "Error in " #expr, (const char *)&err); \
- } \
- } while(0)
-
-AudioMixerManagerMac::AudioMixerManagerMac(const int32_t id) :
- _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
- _id(id),
- _inputDeviceID(kAudioObjectUnknown),
- _outputDeviceID(kAudioObjectUnknown),
- _noInputChannels(0),
- _noOutputChannels(0)
-{
- WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id,
- "%s constructed", __FUNCTION__);
-}
-
-AudioMixerManagerMac::~AudioMixerManagerMac()
-{
- WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id,
- "%s destructed", __FUNCTION__);
- Close();
-
- delete &_critSect;
+#define WEBRTC_CA_RETURN_ON_ERR(expr) \
+ do { \
+ err = expr; \
+ if (err != noErr) { \
+ logCAMsg(kTraceError, kTraceAudioDevice, _id, "Error in " #expr, \
+ (const char*) & err); \
+ return -1; \
+ } \
+ } while (0)
+
+#define WEBRTC_CA_LOG_ERR(expr) \
+ do { \
+ err = expr; \
+ if (err != noErr) { \
+ logCAMsg(kTraceError, kTraceAudioDevice, _id, "Error in " #expr, \
+ (const char*) & err); \
+ } \
+ } while (0)
+
+#define WEBRTC_CA_LOG_WARN(expr) \
+ do { \
+ err = expr; \
+ if (err != noErr) { \
+ logCAMsg(kTraceWarning, kTraceAudioDevice, _id, "Error in " #expr, \
+ (const char*) & err); \
+ } \
+ } while (0)
+
+AudioMixerManagerMac::AudioMixerManagerMac(const int32_t id)
+ : _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
+ _id(id),
+ _inputDeviceID(kAudioObjectUnknown),
+ _outputDeviceID(kAudioObjectUnknown),
+ _noInputChannels(0),
+ _noOutputChannels(0) {
+ WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s constructed",
+ __FUNCTION__);
+}
+
+AudioMixerManagerMac::~AudioMixerManagerMac() {
+ WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destructed",
+ __FUNCTION__);
+
+ Close();
+
+ delete &_critSect;
}
// ============================================================================
// PUBLIC METHODS
// ============================================================================
-int32_t AudioMixerManagerMac::Close()
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s",
- __FUNCTION__);
+int32_t AudioMixerManagerMac::Close() {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__);
- CriticalSectionScoped lock(&_critSect);
+ CriticalSectionScoped lock(&_critSect);
- CloseSpeaker();
- CloseMicrophone();
-
- return 0;
+ CloseSpeaker();
+ CloseMicrophone();
+ return 0;
}
-int32_t AudioMixerManagerMac::CloseSpeaker()
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s",
- __FUNCTION__);
+int32_t AudioMixerManagerMac::CloseSpeaker() {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__);
- CriticalSectionScoped lock(&_critSect);
+ CriticalSectionScoped lock(&_critSect);
- _outputDeviceID = kAudioObjectUnknown;
- _noOutputChannels = 0;
+ _outputDeviceID = kAudioObjectUnknown;
+ _noOutputChannels = 0;
- return 0;
+ return 0;
}
-int32_t AudioMixerManagerMac::CloseMicrophone()
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s",
- __FUNCTION__);
+int32_t AudioMixerManagerMac::CloseMicrophone() {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__);
- CriticalSectionScoped lock(&_critSect);
+ CriticalSectionScoped lock(&_critSect);
- _inputDeviceID = kAudioObjectUnknown;
- _noInputChannels = 0;
+ _inputDeviceID = kAudioObjectUnknown;
+ _noInputChannels = 0;
- return 0;
+ return 0;
}
-int32_t AudioMixerManagerMac::OpenSpeaker(AudioDeviceID deviceID)
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "AudioMixerManagerMac::OpenSpeaker(id=%d)", deviceID);
-
- CriticalSectionScoped lock(&_critSect);
-
- OSStatus err = noErr;
- UInt32 size = 0;
- pid_t hogPid = -1;
+int32_t AudioMixerManagerMac::OpenSpeaker(AudioDeviceID deviceID) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "AudioMixerManagerMac::OpenSpeaker(id=%d)", deviceID);
- _outputDeviceID = deviceID;
+ CriticalSectionScoped lock(&_critSect);
- // Check which process, if any, has hogged the device.
- AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyHogMode,
- kAudioDevicePropertyScopeOutput, 0 };
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ pid_t hogPid = -1;
- size = sizeof(hogPid);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, &size, &hogPid));
-
- if (hogPid == -1)
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " No process has hogged the input device");
- }
- // getpid() is apparently "always successful"
- else if (hogPid == getpid())
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " Our process has hogged the input device");
- } else
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Another process (pid = %d) has hogged the input device",
- static_cast<int> (hogPid));
-
- return -1;
- }
+ _outputDeviceID = deviceID;
- // get number of channels from stream format
- propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
+ // Check which process, if any, has hogged the device.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeOutput, 0};
- // Get the stream format, to be able to read the number of channels.
- AudioStreamBasicDescription streamFormat;
- size = sizeof(AudioStreamBasicDescription);
- memset(&streamFormat, 0, size);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, &size, &streamFormat));
+ size = sizeof(hogPid);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &hogPid));
- _noOutputChannels = streamFormat.mChannelsPerFrame;
-
- return 0;
-}
-
-int32_t AudioMixerManagerMac::OpenMicrophone(AudioDeviceID deviceID)
-{
+ if (hogPid == -1) {
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "AudioMixerManagerMac::OpenMicrophone(id=%d)", deviceID);
-
- CriticalSectionScoped lock(&_critSect);
-
- OSStatus err = noErr;
- UInt32 size = 0;
- pid_t hogPid = -1;
-
- _inputDeviceID = deviceID;
-
- // Check which process, if any, has hogged the device.
- AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyHogMode,
- kAudioDevicePropertyScopeInput, 0 };
- size = sizeof(hogPid);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &hogPid));
- if (hogPid == -1)
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " No process has hogged the input device");
- }
- // getpid() is apparently "always successful"
- else if (hogPid == getpid())
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " Our process has hogged the input device");
- } else
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Another process (pid = %d) has hogged the input device",
- static_cast<int> (hogPid));
-
- return -1;
- }
-
- // get number of channels from stream format
- propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
-
- // Get the stream format, to be able to read the number of channels.
- AudioStreamBasicDescription streamFormat;
- size = sizeof(AudioStreamBasicDescription);
- memset(&streamFormat, 0, size);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &streamFormat));
-
- _noInputChannels = streamFormat.mChannelsPerFrame;
+ " No process has hogged the input device");
+ }
+ // getpid() is apparently "always successful"
+ else if (hogPid == getpid()) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " Our process has hogged the input device");
+ } else {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Another process (pid = %d) has hogged the input device",
+ static_cast<int>(hogPid));
- return 0;
-}
+ return -1;
+ }
-bool AudioMixerManagerMac::SpeakerIsInitialized() const
-{
- WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s",
- __FUNCTION__);
+ // get number of channels from stream format
+ propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
- return (_outputDeviceID != kAudioObjectUnknown);
-}
+ // Get the stream format, to be able to read the number of channels.
+ AudioStreamBasicDescription streamFormat;
+ size = sizeof(AudioStreamBasicDescription);
+ memset(&streamFormat, 0, size);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &streamFormat));
-bool AudioMixerManagerMac::MicrophoneIsInitialized() const
-{
- WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s",
- __FUNCTION__);
+ _noOutputChannels = streamFormat.mChannelsPerFrame;
- return (_inputDeviceID != kAudioObjectUnknown);
+ return 0;
}
-int32_t AudioMixerManagerMac::SetSpeakerVolume(uint32_t volume)
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "AudioMixerManagerMac::SetSpeakerVolume(volume=%u)", volume);
+int32_t AudioMixerManagerMac::OpenMicrophone(AudioDeviceID deviceID) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "AudioMixerManagerMac::OpenMicrophone(id=%d)", deviceID);
- CriticalSectionScoped lock(&_critSect);
+ CriticalSectionScoped lock(&_critSect);
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ pid_t hogPid = -1;
- OSStatus err = noErr;
- UInt32 size = 0;
- bool success = false;
+ _inputDeviceID = deviceID;
- // volume range is 0.0 - 1.0, convert from 0 -255
- const Float32 vol = (Float32)(volume / 255.0);
+ // Check which process, if any, has hogged the device.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeInput, 0};
+ size = sizeof(hogPid);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &hogPid));
+ if (hogPid == -1) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " No process has hogged the input device");
+ }
+ // getpid() is apparently "always successful"
+ else if (hogPid == getpid()) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " Our process has hogged the input device");
+ } else {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Another process (pid = %d) has hogged the input device",
+ static_cast<int>(hogPid));
- assert(vol <= 1.0 && vol >= 0.0);
+ return -1;
+ }
- // Does the capture device have a master volume control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = {
- kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput,
- 0 };
- Boolean isSettable = false;
- err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
- &isSettable);
- if (err == noErr && isSettable)
- {
- size = sizeof(vol);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, size, &vol));
+ // get number of channels from stream format
+ propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
- return 0;
- }
-
- // Otherwise try to set each channel.
- for (UInt32 i = 1; i <= _noOutputChannels; i++)
- {
- propertyAddress.mElement = i;
- isSettable = false;
- err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
- &isSettable);
- if (err == noErr && isSettable)
- {
- size = sizeof(vol);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, size, &vol));
- }
- success = true;
- }
+ // Get the stream format, to be able to read the number of channels.
+ AudioStreamBasicDescription streamFormat;
+ size = sizeof(AudioStreamBasicDescription);
+ memset(&streamFormat, 0, size);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &streamFormat));
- if (!success)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Unable to set a volume on any output channel");
- return -1;
- }
+ _noInputChannels = streamFormat.mChannelsPerFrame;
- return 0;
+ return 0;
}
-int32_t AudioMixerManagerMac::SpeakerVolume(uint32_t& volume) const
-{
+bool AudioMixerManagerMac::SpeakerIsInitialized() const {
+ WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
- UInt32 size = 0;
- unsigned int channels = 0;
- Float32 channelVol = 0;
- Float32 vol = 0;
-
- // Does the device have a master volume control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = {
- kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput,
- 0 };
- Boolean hasProperty = AudioObjectHasProperty(_outputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- size = sizeof(vol);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, &size, &vol));
-
- // vol 0.0 to 1.0 -> convert to 0 - 255
- volume = static_cast<uint32_t> (vol * 255 + 0.5);
- } else
- {
- // Otherwise get the average volume across channels.
- vol = 0;
- for (UInt32 i = 1; i <= _noOutputChannels; i++)
- {
- channelVol = 0;
- propertyAddress.mElement = i;
- hasProperty = AudioObjectHasProperty(_outputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- size = sizeof(channelVol);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, &size, &channelVol));
-
- vol += channelVol;
- channels++;
- }
- }
-
- if (channels == 0)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Unable to get a volume on any channel");
- return -1;
- }
-
- assert(channels > 0);
- // vol 0.0 to 1.0 -> convert to 0 - 255
- volume = static_cast<uint32_t> (255 * vol / channels + 0.5);
- }
-
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " AudioMixerManagerMac::SpeakerVolume() => vol=%i", vol);
-
- return 0;
+ return (_outputDeviceID != kAudioObjectUnknown);
}
-int32_t
-AudioMixerManagerMac::MaxSpeakerVolume(uint32_t& maxVolume) const
-{
+bool AudioMixerManagerMac::MicrophoneIsInitialized() const {
+ WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", __FUNCTION__);
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- // volume range is 0.0 to 1.0
- // we convert that to 0 - 255
- maxVolume = 255;
-
- return 0;
+ return (_inputDeviceID != kAudioObjectUnknown);
}
-int32_t
-AudioMixerManagerMac::MinSpeakerVolume(uint32_t& minVolume) const
-{
+int32_t AudioMixerManagerMac::SetSpeakerVolume(uint32_t volume) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "AudioMixerManagerMac::SetSpeakerVolume(volume=%u)", volume);
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
+ CriticalSectionScoped lock(&_critSect);
- // volume range is 0.0 to 1.0
- // we convert that to 0 - 255
- minVolume = 0;
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
- return 0;
-}
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ bool success = false;
-int32_t
-AudioMixerManagerMac::SpeakerVolumeStepSize(uint16_t& stepSize) const
-{
+ // volume range is 0.0 - 1.0, convert from 0 -255
+ const Float32 vol = (Float32)(volume / 255.0);
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
+ assert(vol <= 1.0 && vol >= 0.0);
- // volume range is 0.0 to 1.0
- // we convert that to 0 - 255
- stepSize = 1;
+ // Does the capture device have a master volume control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0};
+ Boolean isSettable = false;
+ err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
+ size = sizeof(vol);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, size, &vol));
return 0;
-}
+ }
-int32_t AudioMixerManagerMac::SpeakerVolumeIsAvailable(bool& available)
-{
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
-
- // Does the capture device have a master volume control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = {
- kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput,
- 0 };
- Boolean isSettable = false;
+ // Otherwise try to set each channel.
+ for (UInt32 i = 1; i <= _noOutputChannels; i++) {
+ propertyAddress.mElement = i;
+ isSettable = false;
err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
&isSettable);
- if (err == noErr && isSettable)
- {
- available = true;
- return 0;
- }
-
- // Otherwise try to set each channel.
- for (UInt32 i = 1; i <= _noOutputChannels; i++)
- {
- propertyAddress.mElement = i;
- isSettable = false;
- err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
- &isSettable);
- if (err != noErr || !isSettable)
- {
- available = false;
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Volume cannot be set for output channel %d, err=%d",
- i, err);
- return -1;
- }
- }
-
+ if (err == noErr && isSettable) {
+ size = sizeof(vol);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, size, &vol));
+ }
+ success = true;
+ }
+
+ if (!success) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Unable to set a volume on any output channel");
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::SpeakerVolume(uint32_t& volume) const {
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ unsigned int channels = 0;
+ Float32 channelVol = 0;
+ Float32 vol = 0;
+
+ // Does the device have a master volume control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0};
+ Boolean hasProperty =
+ AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ size = sizeof(vol);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &vol));
+
+ // vol 0.0 to 1.0 -> convert to 0 - 255
+ volume = static_cast<uint32_t>(vol * 255 + 0.5);
+ } else {
+ // Otherwise get the average volume across channels.
+ vol = 0;
+ for (UInt32 i = 1; i <= _noOutputChannels; i++) {
+ channelVol = 0;
+ propertyAddress.mElement = i;
+ hasProperty = AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ size = sizeof(channelVol);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &channelVol));
+
+ vol += channelVol;
+ channels++;
+ }
+ }
+
+ if (channels == 0) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Unable to get a volume on any channel");
+ return -1;
+ }
+
+ assert(channels > 0);
+ // vol 0.0 to 1.0 -> convert to 0 - 255
+ volume = static_cast<uint32_t>(255 * vol / channels + 0.5);
+ }
+
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " AudioMixerManagerMac::SpeakerVolume() => vol=%i", vol);
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MaxSpeakerVolume(uint32_t& maxVolume) const {
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ // volume range is 0.0 to 1.0
+ // we convert that to 0 - 255
+ maxVolume = 255;
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MinSpeakerVolume(uint32_t& minVolume) const {
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ // volume range is 0.0 to 1.0
+ // we convert that to 0 - 255
+ minVolume = 0;
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::SpeakerVolumeStepSize(uint16_t& stepSize) const {
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ // volume range is 0.0 to 1.0
+ // we convert that to 0 - 255
+ stepSize = 1;
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::SpeakerVolumeIsAvailable(bool& available) {
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+
+ // Does the capture device have a master volume control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0};
+ Boolean isSettable = false;
+ err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
available = true;
return 0;
-}
-
-int32_t AudioMixerManagerMac::SpeakerMuteIsAvailable(bool& available)
-{
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
+ }
- OSStatus err = noErr;
-
- // Does the capture device have a master mute control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyMute,
- kAudioDevicePropertyScopeOutput, 0 };
- Boolean isSettable = false;
+ // Otherwise try to set each channel.
+ for (UInt32 i = 1; i <= _noOutputChannels; i++) {
+ propertyAddress.mElement = i;
+ isSettable = false;
err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
&isSettable);
- if (err == noErr && isSettable)
- {
- available = true;
- return 0;
- }
-
- // Otherwise try to set each channel.
- for (UInt32 i = 1; i <= _noOutputChannels; i++)
- {
- propertyAddress.mElement = i;
- isSettable = false;
- err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
- &isSettable);
- if (err != noErr || !isSettable)
- {
- available = false;
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Mute cannot be set for output channel %d, err=%d",
- i, err);
- return -1;
- }
- }
-
+ if (err != noErr || !isSettable) {
+ available = false;
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Volume cannot be set for output channel %d, err=%d", i,
+ err);
+ return -1;
+ }
+ }
+
+ available = true;
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::SpeakerMuteIsAvailable(bool& available) {
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+
+ // Does the capture device have a master mute control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0};
+ Boolean isSettable = false;
+ err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
available = true;
return 0;
-}
-
-int32_t AudioMixerManagerMac::SetSpeakerMute(bool enable)
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "AudioMixerManagerMac::SetSpeakerMute(enable=%u)", enable);
-
- CriticalSectionScoped lock(&_critSect);
-
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
- UInt32 size = 0;
- UInt32 mute = enable ? 1 : 0;
- bool success = false;
+ }
- // Does the render device have a master mute control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyMute,
- kAudioDevicePropertyScopeOutput, 0 };
- Boolean isSettable = false;
+ // Otherwise try to set each channel.
+ for (UInt32 i = 1; i <= _noOutputChannels; i++) {
+ propertyAddress.mElement = i;
+ isSettable = false;
err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
&isSettable);
- if (err == noErr && isSettable)
- {
- size = sizeof(mute);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, size, &mute));
-
- return 0;
- }
-
- // Otherwise try to set each channel.
- for (UInt32 i = 1; i <= _noOutputChannels; i++)
- {
- propertyAddress.mElement = i;
- isSettable = false;
- err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
- &isSettable);
- if (err == noErr && isSettable)
- {
- size = sizeof(mute);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, size, &mute));
- }
- success = true;
- }
-
- if (!success)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Unable to set mute on any input channel");
- return -1;
- }
+ if (err != noErr || !isSettable) {
+ available = false;
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Mute cannot be set for output channel %d, err=%d", i, err);
+ return -1;
+ }
+ }
+
+ available = true;
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::SetSpeakerMute(bool enable) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "AudioMixerManagerMac::SetSpeakerMute(enable=%u)", enable);
+
+ CriticalSectionScoped lock(&_critSect);
+
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ UInt32 mute = enable ? 1 : 0;
+ bool success = false;
+
+ // Does the render device have a master mute control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0};
+ Boolean isSettable = false;
+ err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
+ size = sizeof(mute);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, size, &mute));
return 0;
-}
+ }
-int32_t AudioMixerManagerMac::SpeakerMute(bool& enabled) const
-{
-
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
- UInt32 size = 0;
- unsigned int channels = 0;
- UInt32 channelMuted = 0;
- UInt32 muted = 0;
-
- // Does the device have a master volume control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyMute,
- kAudioDevicePropertyScopeOutput, 0 };
- Boolean hasProperty = AudioObjectHasProperty(_outputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- size = sizeof(muted);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, &size, &muted));
-
- // 1 means muted
- enabled = static_cast<bool> (muted);
- } else
- {
- // Otherwise check if all channels are muted.
- for (UInt32 i = 1; i <= _noOutputChannels; i++)
- {
- muted = 0;
- propertyAddress.mElement = i;
- hasProperty = AudioObjectHasProperty(_outputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- size = sizeof(channelMuted);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, &size, &channelMuted));
-
- muted = (muted && channelMuted);
- channels++;
- }
- }
-
- if (channels == 0)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Unable to get mute for any channel");
- return -1;
- }
-
- assert(channels > 0);
- // 1 means muted
- enabled = static_cast<bool> (muted);
- }
-
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " AudioMixerManagerMac::SpeakerMute() => enabled=%d, enabled");
-
- return 0;
-}
-
-int32_t AudioMixerManagerMac::StereoPlayoutIsAvailable(bool& available)
-{
- if (_outputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- available = (_noOutputChannels == 2);
- return 0;
-}
-
-int32_t AudioMixerManagerMac::StereoRecordingIsAvailable(bool& available)
-{
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- available = (_noInputChannels == 2);
- return 0;
-}
-
-int32_t AudioMixerManagerMac::MicrophoneMuteIsAvailable(bool& available)
-{
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
-
- // Does the capture device have a master mute control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyMute,
- kAudioDevicePropertyScopeInput, 0 };
- Boolean isSettable = false;
- err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
+ // Otherwise try to set each channel.
+ for (UInt32 i = 1; i <= _noOutputChannels; i++) {
+ propertyAddress.mElement = i;
+ isSettable = false;
+ err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
&isSettable);
- if (err == noErr && isSettable)
- {
- available = true;
- return 0;
- }
-
- // Otherwise try to set each channel.
- for (UInt32 i = 1; i <= _noInputChannels; i++)
- {
- propertyAddress.mElement = i;
- isSettable = false;
- err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
- &isSettable);
- if (err != noErr || !isSettable)
- {
- available = false;
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Mute cannot be set for output channel %d, err=%d",
- i, err);
- return -1;
- }
- }
-
+ if (err == noErr && isSettable) {
+ size = sizeof(mute);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, size, &mute));
+ }
+ success = true;
+ }
+
+ if (!success) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Unable to set mute on any input channel");
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::SpeakerMute(bool& enabled) const {
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ unsigned int channels = 0;
+ UInt32 channelMuted = 0;
+ UInt32 muted = 0;
+
+ // Does the device have a master volume control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0};
+ Boolean hasProperty =
+ AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ size = sizeof(muted);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &muted));
+
+ // 1 means muted
+ enabled = static_cast<bool>(muted);
+ } else {
+ // Otherwise check if all channels are muted.
+ for (UInt32 i = 1; i <= _noOutputChannels; i++) {
+ muted = 0;
+ propertyAddress.mElement = i;
+ hasProperty = AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ size = sizeof(channelMuted);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &channelMuted));
+
+ muted = (muted && channelMuted);
+ channels++;
+ }
+ }
+
+ if (channels == 0) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Unable to get mute for any channel");
+ return -1;
+ }
+
+ assert(channels > 0);
+ // 1 means muted
+ enabled = static_cast<bool>(muted);
+ }
+
+ WEBRTC_TRACE(
+ kTraceInfo, kTraceAudioDevice, _id,
+ " AudioMixerManagerMac::SpeakerMute() => enabled=%d, enabled");
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::StereoPlayoutIsAvailable(bool& available) {
+ if (_outputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ available = (_noOutputChannels == 2);
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::StereoRecordingIsAvailable(bool& available) {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ available = (_noInputChannels == 2);
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MicrophoneMuteIsAvailable(bool& available) {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+
+ // Does the capture device have a master mute control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyMute, kAudioDevicePropertyScopeInput, 0};
+ Boolean isSettable = false;
+ err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
available = true;
return 0;
-}
+ }
-int32_t AudioMixerManagerMac::SetMicrophoneMute(bool enable)
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "AudioMixerManagerMac::SetMicrophoneMute(enable=%u)", enable);
-
- CriticalSectionScoped lock(&_critSect);
-
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
- UInt32 size = 0;
- UInt32 mute = enable ? 1 : 0;
- bool success = false;
-
- // Does the capture device have a master mute control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyMute,
- kAudioDevicePropertyScopeInput, 0 };
- Boolean isSettable = false;
+ // Otherwise try to set each channel.
+ for (UInt32 i = 1; i <= _noInputChannels; i++) {
+ propertyAddress.mElement = i;
+ isSettable = false;
err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
&isSettable);
- if (err == noErr && isSettable)
- {
- size = sizeof(mute);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, size, &mute));
-
- return 0;
- }
-
- // Otherwise try to set each channel.
- for (UInt32 i = 1; i <= _noInputChannels; i++)
- {
- propertyAddress.mElement = i;
- isSettable = false;
- err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
- &isSettable);
- if (err == noErr && isSettable)
- {
- size = sizeof(mute);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, size, &mute));
- }
- success = true;
- }
-
- if (!success)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Unable to set mute on any input channel");
- return -1;
- }
-
- return 0;
-}
-
-int32_t AudioMixerManagerMac::MicrophoneMute(bool& enabled) const
-{
-
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
- UInt32 size = 0;
- unsigned int channels = 0;
- UInt32 channelMuted = 0;
- UInt32 muted = 0;
-
- // Does the device have a master volume control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyMute,
- kAudioDevicePropertyScopeInput, 0 };
- Boolean hasProperty = AudioObjectHasProperty(_inputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- size = sizeof(muted);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &muted));
-
- // 1 means muted
- enabled = static_cast<bool> (muted);
- } else
- {
- // Otherwise check if all channels are muted.
- for (UInt32 i = 1; i <= _noInputChannels; i++)
- {
- muted = 0;
- propertyAddress.mElement = i;
- hasProperty = AudioObjectHasProperty(_inputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- size = sizeof(channelMuted);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &channelMuted));
-
- muted = (muted && channelMuted);
- channels++;
- }
- }
-
- if (channels == 0)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Unable to get mute for any channel");
- return -1;
- }
-
- assert(channels > 0);
- // 1 means muted
- enabled = static_cast<bool> (muted);
- }
-
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " AudioMixerManagerMac::MicrophoneMute() => enabled=%d",
- enabled);
+ if (err != noErr || !isSettable) {
+ available = false;
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Mute cannot be set for output channel %d, err=%d", i, err);
+ return -1;
+ }
+ }
+
+ available = true;
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::SetMicrophoneMute(bool enable) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "AudioMixerManagerMac::SetMicrophoneMute(enable=%u)", enable);
+
+ CriticalSectionScoped lock(&_critSect);
+
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ UInt32 mute = enable ? 1 : 0;
+ bool success = false;
+
+ // Does the capture device have a master mute control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyMute, kAudioDevicePropertyScopeInput, 0};
+ Boolean isSettable = false;
+ err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
+ size = sizeof(mute);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, size, &mute));
return 0;
-}
-
-int32_t AudioMixerManagerMac::MicrophoneBoostIsAvailable(bool& available)
-{
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- available = false; // No AudioObjectPropertySelector value for Mic Boost
+ }
- return 0;
-}
-
-int32_t AudioMixerManagerMac::SetMicrophoneBoost(bool enable)
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "AudioMixerManagerMac::SetMicrophoneBoost(enable=%u)", enable);
-
- CriticalSectionScoped lock(&_critSect);
-
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- // Ensure that the selected microphone has a valid boost control.
- bool available(false);
- MicrophoneBoostIsAvailable(available);
- if (!available)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " it is not possible to enable microphone boost");
- return -1;
- }
-
- // It is assumed that the call above fails!
- return 0;
-}
-
-int32_t AudioMixerManagerMac::MicrophoneBoost(bool& enabled) const
-{
-
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- // Microphone boost cannot be enabled on this platform!
- enabled = false;
-
- return 0;
-}
-
-int32_t AudioMixerManagerMac::MicrophoneVolumeIsAvailable(bool& available)
-{
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
-
- // Does the capture device have a master volume control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress
- propertyAddress = { kAudioDevicePropertyVolumeScalar,
- kAudioDevicePropertyScopeInput, 0 };
- Boolean isSettable = false;
+ // Otherwise try to set each channel.
+ for (UInt32 i = 1; i <= _noInputChannels; i++) {
+ propertyAddress.mElement = i;
+ isSettable = false;
err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
&isSettable);
- if (err == noErr && isSettable)
- {
- available = true;
- return 0;
- }
-
- // Otherwise try to set each channel.
- for (UInt32 i = 1; i <= _noInputChannels; i++)
- {
- propertyAddress.mElement = i;
- isSettable = false;
- err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
- &isSettable);
- if (err != noErr || !isSettable)
- {
- available = false;
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Volume cannot be set for input channel %d, err=%d",
- i, err);
- return -1;
- }
- }
-
+ if (err == noErr && isSettable) {
+ size = sizeof(mute);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, size, &mute));
+ }
+ success = true;
+ }
+
+ if (!success) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Unable to set mute on any input channel");
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MicrophoneMute(bool& enabled) const {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ unsigned int channels = 0;
+ UInt32 channelMuted = 0;
+ UInt32 muted = 0;
+
+ // Does the device have a master volume control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyMute, kAudioDevicePropertyScopeInput, 0};
+ Boolean hasProperty =
+ AudioObjectHasProperty(_inputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ size = sizeof(muted);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &muted));
+
+ // 1 means muted
+ enabled = static_cast<bool>(muted);
+ } else {
+ // Otherwise check if all channels are muted.
+ for (UInt32 i = 1; i <= _noInputChannels; i++) {
+ muted = 0;
+ propertyAddress.mElement = i;
+ hasProperty = AudioObjectHasProperty(_inputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ size = sizeof(channelMuted);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &channelMuted));
+
+ muted = (muted && channelMuted);
+ channels++;
+ }
+ }
+
+ if (channels == 0) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Unable to get mute for any channel");
+ return -1;
+ }
+
+ assert(channels > 0);
+ // 1 means muted
+ enabled = static_cast<bool>(muted);
+ }
+
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " AudioMixerManagerMac::MicrophoneMute() => enabled=%d",
+ enabled);
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MicrophoneBoostIsAvailable(bool& available) {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ available = false; // No AudioObjectPropertySelector value for Mic Boost
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::SetMicrophoneBoost(bool enable) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "AudioMixerManagerMac::SetMicrophoneBoost(enable=%u)", enable);
+
+ CriticalSectionScoped lock(&_critSect);
+
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ // Ensure that the selected microphone has a valid boost control.
+ bool available(false);
+ MicrophoneBoostIsAvailable(available);
+ if (!available) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " it is not possible to enable microphone boost");
+ return -1;
+ }
+
+ // It is assumed that the call above fails!
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MicrophoneBoost(bool& enabled) const {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ // Microphone boost cannot be enabled on this platform!
+ enabled = false;
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MicrophoneVolumeIsAvailable(bool& available) {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+
+ // Does the capture device have a master volume control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeInput, 0};
+ Boolean isSettable = false;
+ err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
available = true;
return 0;
-}
-
-int32_t AudioMixerManagerMac::SetMicrophoneVolume(uint32_t volume)
-{
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "AudioMixerManagerMac::SetMicrophoneVolume(volume=%u)", volume);
-
- CriticalSectionScoped lock(&_critSect);
+ }
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- OSStatus err = noErr;
- UInt32 size = 0;
- bool success = false;
-
- // volume range is 0.0 - 1.0, convert from 0 - 255
- const Float32 vol = (Float32)(volume / 255.0);
-
- assert(vol <= 1.0 && vol >= 0.0);
-
- // Does the capture device have a master volume control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress
- propertyAddress = { kAudioDevicePropertyVolumeScalar,
- kAudioDevicePropertyScopeInput, 0 };
- Boolean isSettable = false;
+ // Otherwise try to set each channel.
+ for (UInt32 i = 1; i <= _noInputChannels; i++) {
+ propertyAddress.mElement = i;
+ isSettable = false;
err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
&isSettable);
- if (err == noErr && isSettable)
- {
- size = sizeof(vol);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, size, &vol));
-
- return 0;
+ if (err != noErr || !isSettable) {
+ available = false;
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Volume cannot be set for input channel %d, err=%d", i,
+ err);
+ return -1;
}
+ }
- // Otherwise try to set each channel.
- for (UInt32 i = 1; i <= _noInputChannels; i++)
- {
- propertyAddress.mElement = i;
- isSettable = false;
- err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
- &isSettable);
- if (err == noErr && isSettable)
- {
- size = sizeof(vol);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, size, &vol));
- }
- success = true;
- }
-
- if (!success)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Unable to set a level on any input channel");
- return -1;
- }
-
- return 0;
+ available = true;
+ return 0;
}
-int32_t
-AudioMixerManagerMac::MicrophoneVolume(uint32_t& volume) const
-{
-
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
+int32_t AudioMixerManagerMac::SetMicrophoneVolume(uint32_t volume) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "AudioMixerManagerMac::SetMicrophoneVolume(volume=%u)", volume);
- OSStatus err = noErr;
- UInt32 size = 0;
- unsigned int channels = 0;
- Float32 channelVol = 0;
- Float32 volFloat32 = 0;
-
- // Does the device have a master volume control?
- // If so, use it exclusively.
- AudioObjectPropertyAddress
- propertyAddress = { kAudioDevicePropertyVolumeScalar,
- kAudioDevicePropertyScopeInput, 0 };
- Boolean hasProperty = AudioObjectHasProperty(_inputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- size = sizeof(volFloat32);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &volFloat32));
-
- // vol 0.0 to 1.0 -> convert to 0 - 255
- volume = static_cast<uint32_t> (volFloat32 * 255 + 0.5);
- } else
- {
- // Otherwise get the average volume across channels.
- volFloat32 = 0;
- for (UInt32 i = 1; i <= _noInputChannels; i++)
- {
- channelVol = 0;
- propertyAddress.mElement = i;
- hasProperty = AudioObjectHasProperty(_inputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- size = sizeof(channelVol);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &channelVol));
-
- volFloat32 += channelVol;
- channels++;
- }
- }
-
- if (channels == 0)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Unable to get a level on any channel");
- return -1;
- }
-
- assert(channels > 0);
- // vol 0.0 to 1.0 -> convert to 0 - 255
- volume = static_cast<uint32_t>
- (255 * volFloat32 / channels + 0.5);
- }
+ CriticalSectionScoped lock(&_critSect);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " AudioMixerManagerMac::MicrophoneVolume() => vol=%u",
- volume);
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
- return 0;
-}
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ bool success = false;
-int32_t
-AudioMixerManagerMac::MaxMicrophoneVolume(uint32_t& maxVolume) const
-{
+ // volume range is 0.0 - 1.0, convert from 0 - 255
+ const Float32 vol = (Float32)(volume / 255.0);
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
+ assert(vol <= 1.0 && vol >= 0.0);
- // volume range is 0.0 to 1.0
- // we convert that to 0 - 255
- maxVolume = 255;
+ // Does the capture device have a master volume control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeInput, 0};
+ Boolean isSettable = false;
+ err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
+ size = sizeof(vol);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, size, &vol));
return 0;
-}
-
-int32_t
-AudioMixerManagerMac::MinMicrophoneVolume(uint32_t& minVolume) const
-{
-
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
+ }
- // volume range is 0.0 to 1.0
- // we convert that to 0 - 10
- minVolume = 0;
+ // Otherwise try to set each channel.
+ for (UInt32 i = 1; i <= _noInputChannels; i++) {
+ propertyAddress.mElement = i;
+ isSettable = false;
+ err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
+ &isSettable);
+ if (err == noErr && isSettable) {
+ size = sizeof(vol);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, size, &vol));
+ }
+ success = true;
+ }
+
+ if (!success) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Unable to set a level on any input channel");
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MicrophoneVolume(uint32_t& volume) const {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ unsigned int channels = 0;
+ Float32 channelVol = 0;
+ Float32 volFloat32 = 0;
+
+ // Does the device have a master volume control?
+ // If so, use it exclusively.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeInput, 0};
+ Boolean hasProperty =
+ AudioObjectHasProperty(_inputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ size = sizeof(volFloat32);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &volFloat32));
+
+ // vol 0.0 to 1.0 -> convert to 0 - 255
+ volume = static_cast<uint32_t>(volFloat32 * 255 + 0.5);
+ } else {
+ // Otherwise get the average volume across channels.
+ volFloat32 = 0;
+ for (UInt32 i = 1; i <= _noInputChannels; i++) {
+ channelVol = 0;
+ propertyAddress.mElement = i;
+ hasProperty = AudioObjectHasProperty(_inputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ size = sizeof(channelVol);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &channelVol));
+
+ volFloat32 += channelVol;
+ channels++;
+ }
+ }
+
+ if (channels == 0) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Unable to get a level on any channel");
+ return -1;
+ }
+
+ assert(channels > 0);
+ // vol 0.0 to 1.0 -> convert to 0 - 255
+ volume = static_cast<uint32_t>(255 * volFloat32 / channels + 0.5);
+ }
+
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " AudioMixerManagerMac::MicrophoneVolume() => vol=%u",
+ volume);
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MaxMicrophoneVolume(uint32_t& maxVolume) const {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ // volume range is 0.0 to 1.0
+ // we convert that to 0 - 255
+ maxVolume = 255;
+
+ return 0;
+}
+
+int32_t AudioMixerManagerMac::MinMicrophoneVolume(uint32_t& minVolume) const {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ // volume range is 0.0 to 1.0
+ // we convert that to 0 - 10
+ minVolume = 0;
- return 0;
+ return 0;
}
-int32_t
-AudioMixerManagerMac::MicrophoneVolumeStepSize(uint16_t& stepSize) const
-{
-
- if (_inputDeviceID == kAudioObjectUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " device ID has not been set");
- return -1;
- }
-
- // volume range is 0.0 to 1.0
- // we convert that to 0 - 10
- stepSize = 1;
-
- return 0;
+int32_t AudioMixerManagerMac::MicrophoneVolumeStepSize(
+ uint16_t& stepSize) const {
+ if (_inputDeviceID == kAudioObjectUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " device ID has not been set");
+ return -1;
+ }
+
+ // volume range is 0.0 to 1.0
+ // we convert that to 0 - 10
+ stepSize = 1;
+
+ return 0;
}
// ============================================================================
@@ -1148,18 +1003,18 @@ AudioMixerManagerMac::MicrophoneVolumeStepSize(uint16_t& stepSize) const
// CoreAudio errors are best interpreted as four character strings.
void AudioMixerManagerMac::logCAMsg(const TraceLevel level,
const TraceModule module,
- const int32_t id, const char *msg,
- const char *err)
-{
- assert(msg != NULL);
- assert(err != NULL);
+ const int32_t id,
+ const char* msg,
+ const char* err) {
+ assert(msg != NULL);
+ assert(err != NULL);
#ifdef WEBRTC_ARCH_BIG_ENDIAN
- WEBRTC_TRACE(level, module, id, "%s: %.4s", msg, err);
+ WEBRTC_TRACE(level, module, id, "%s: %.4s", msg, err);
#else
- // We need to flip the characters in this case.
- WEBRTC_TRACE(level, module, id, "%s: %.1s%.1s%.1s%.1s", msg, err + 3, err
- + 2, err + 1, err);
+ // We need to flip the characters in this case.
+ WEBRTC_TRACE(level, module, id, "%s: %.1s%.1s%.1s%.1s", msg, err + 3, err + 2,
+ err + 1, err);
#endif
}