| Index: webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc
|
| 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 9016ffe508f27602984d772ea41a2668421159a8..e7e07546956ef46ab446442751add795efd4c835 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
|
| }
|
|
|
|
|