aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandrew <andrew@webrtc.org>2016-01-11 15:59:17 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-11 23:59:25 +0000
commit2bc63a1dd3188402f4da1cdb6ed24fc058819304 (patch)
tree620c9452740c785784b6b5158ec42ff4fecb8976
parenta7446d2a50167602b04f58c917f5075ad5e494dc (diff)
downloadwebrtc-2bc63a1dd3188402f4da1cdb6ed24fc058819304.tar.gz
clang-format audio_device/mac.
NOTRY=true Review URL: https://codereview.webrtc.org/1570063003 Cr-Commit-Position: refs/heads/master@{#11212}
-rw-r--r--webrtc/modules/audio_device/mac/audio_device_mac.cc4845
-rw-r--r--webrtc/modules/audio_device/mac/audio_device_mac.h572
-rw-r--r--webrtc/modules/audio_device/mac/audio_mixer_manager_mac.cc1907
-rw-r--r--webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h99
4 files changed, 3398 insertions, 4025 deletions
diff --git a/webrtc/modules/audio_device/mac/audio_device_mac.cc b/webrtc/modules/audio_device/mac/audio_device_mac.cc
index d963f2b7f2..0f33d1124d 100644
--- a/webrtc/modules/audio_device/mac/audio_device_mac.cc
+++ b/webrtc/modules/audio_device/mac/audio_device_mac.cc
@@ -18,3227 +18,2750 @@
#include "webrtc/system_wrappers/include/trace.h"
#include <ApplicationServices/ApplicationServices.h>
-#include <libkern/OSAtomic.h> // OSAtomicCompareAndSwap()
-#include <mach/mach.h> // mach_task_self()
-#include <sys/sysctl.h> // sysctlbyname()
-
-
-
-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)
-
-enum
-{
- MaxNumberDevices = 64
-};
-
-void AudioDeviceMac::AtomicSet32(int32_t* theValue, int32_t newValue)
-{
- while (1)
- {
- int32_t oldValue = *theValue;
- if (OSAtomicCompareAndSwap32Barrier(oldValue, newValue, theValue)
- == true)
- {
- return;
- }
+#include <libkern/OSAtomic.h> // OSAtomicCompareAndSwap()
+#include <mach/mach.h> // mach_task_self()
+#include <sys/sysctl.h> // sysctlbyname()
+
+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)
+
+enum { MaxNumberDevices = 64 };
+
+void AudioDeviceMac::AtomicSet32(int32_t* theValue, int32_t newValue) {
+ while (1) {
+ int32_t oldValue = *theValue;
+ if (OSAtomicCompareAndSwap32Barrier(oldValue, newValue, theValue) == true) {
+ return;
}
+ }
}
-int32_t AudioDeviceMac::AtomicGet32(int32_t* theValue)
-{
- while (1)
- {
- int32_t value = *theValue;
- if (OSAtomicCompareAndSwap32Barrier(value, value, theValue) == true)
- {
- return value;
- }
+int32_t AudioDeviceMac::AtomicGet32(int32_t* theValue) {
+ while (1) {
+ int32_t value = *theValue;
+ if (OSAtomicCompareAndSwap32Barrier(value, value, theValue) == true) {
+ return value;
}
+ }
}
// CoreAudio errors are best interpreted as four character strings.
void AudioDeviceMac::logCAMsg(const TraceLevel level,
const TraceModule module,
- const int32_t id, const char *msg,
- const char *err)
-{
+ const int32_t id,
+ const char* msg,
+ const char* err) {
RTC_DCHECK(msg != NULL);
RTC_DCHECK(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
}
-AudioDeviceMac::AudioDeviceMac(const int32_t id) :
- _ptrAudioBuffer(NULL),
- _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
- _stopEventRec(*EventWrapper::Create()),
- _stopEvent(*EventWrapper::Create()),
- _id(id),
- _mixerManager(id),
- _inputDeviceIndex(0),
- _outputDeviceIndex(0),
- _inputDeviceID(kAudioObjectUnknown),
- _outputDeviceID(kAudioObjectUnknown),
- _inputDeviceIsSpecified(false),
- _outputDeviceIsSpecified(false),
- _recChannels(N_REC_CHANNELS),
- _playChannels(N_PLAY_CHANNELS),
- _captureBufData(NULL),
- _renderBufData(NULL),
- _playBufType(AudioDeviceModule::kFixedBufferSize),
- _initialized(false),
- _isShutDown(false),
- _recording(false),
- _playing(false),
- _recIsInitialized(false),
- _playIsInitialized(false),
- _AGC(false),
- _renderDeviceIsAlive(1),
- _captureDeviceIsAlive(1),
- _twoDevices(true),
- _doStop(false),
- _doStopRec(false),
- _macBookPro(false),
- _macBookProPanRight(false),
- _captureLatencyUs(0),
- _renderLatencyUs(0),
- _captureDelayUs(0),
- _renderDelayUs(0),
- _renderDelayOffsetSamples(0),
- _playBufDelayFixed(20),
- _playWarning(0),
- _playError(0),
- _recWarning(0),
- _recError(0),
- _paCaptureBuffer(NULL),
- _paRenderBuffer(NULL),
- _captureBufSizeSamples(0),
- _renderBufSizeSamples(0),
- prev_key_state_(),
- get_mic_volume_counter_ms_(0)
-{
- WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id,
- "%s created", __FUNCTION__);
-
- RTC_DCHECK(&_stopEvent != NULL);
- RTC_DCHECK(&_stopEventRec != NULL);
-
- memset(_renderConvertData, 0, sizeof(_renderConvertData));
- memset(&_outStreamFormat, 0, sizeof(AudioStreamBasicDescription));
- memset(&_outDesiredFormat, 0, sizeof(AudioStreamBasicDescription));
- memset(&_inStreamFormat, 0, sizeof(AudioStreamBasicDescription));
- memset(&_inDesiredFormat, 0, sizeof(AudioStreamBasicDescription));
-}
-
-
-AudioDeviceMac::~AudioDeviceMac()
-{
- WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id,
- "%s destroyed", __FUNCTION__);
-
- if (!_isShutDown)
- {
- Terminate();
- }
+AudioDeviceMac::AudioDeviceMac(const int32_t id)
+ : _ptrAudioBuffer(NULL),
+ _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
+ _stopEventRec(*EventWrapper::Create()),
+ _stopEvent(*EventWrapper::Create()),
+ _id(id),
+ _mixerManager(id),
+ _inputDeviceIndex(0),
+ _outputDeviceIndex(0),
+ _inputDeviceID(kAudioObjectUnknown),
+ _outputDeviceID(kAudioObjectUnknown),
+ _inputDeviceIsSpecified(false),
+ _outputDeviceIsSpecified(false),
+ _recChannels(N_REC_CHANNELS),
+ _playChannels(N_PLAY_CHANNELS),
+ _captureBufData(NULL),
+ _renderBufData(NULL),
+ _playBufType(AudioDeviceModule::kFixedBufferSize),
+ _initialized(false),
+ _isShutDown(false),
+ _recording(false),
+ _playing(false),
+ _recIsInitialized(false),
+ _playIsInitialized(false),
+ _AGC(false),
+ _renderDeviceIsAlive(1),
+ _captureDeviceIsAlive(1),
+ _twoDevices(true),
+ _doStop(false),
+ _doStopRec(false),
+ _macBookPro(false),
+ _macBookProPanRight(false),
+ _captureLatencyUs(0),
+ _renderLatencyUs(0),
+ _captureDelayUs(0),
+ _renderDelayUs(0),
+ _renderDelayOffsetSamples(0),
+ _playBufDelayFixed(20),
+ _playWarning(0),
+ _playError(0),
+ _recWarning(0),
+ _recError(0),
+ _paCaptureBuffer(NULL),
+ _paRenderBuffer(NULL),
+ _captureBufSizeSamples(0),
+ _renderBufSizeSamples(0),
+ prev_key_state_(),
+ get_mic_volume_counter_ms_(0) {
+ WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, "%s created", __FUNCTION__);
+
+ RTC_DCHECK(&_stopEvent != NULL);
+ RTC_DCHECK(&_stopEventRec != NULL);
+
+ memset(_renderConvertData, 0, sizeof(_renderConvertData));
+ memset(&_outStreamFormat, 0, sizeof(AudioStreamBasicDescription));
+ memset(&_outDesiredFormat, 0, sizeof(AudioStreamBasicDescription));
+ memset(&_inStreamFormat, 0, sizeof(AudioStreamBasicDescription));
+ memset(&_inDesiredFormat, 0, sizeof(AudioStreamBasicDescription));
+}
+
+AudioDeviceMac::~AudioDeviceMac() {
+ WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed",
+ __FUNCTION__);
+
+ if (!_isShutDown) {
+ Terminate();
+ }
- RTC_DCHECK(!capture_worker_thread_.get());
- RTC_DCHECK(!render_worker_thread_.get());
+ RTC_DCHECK(!capture_worker_thread_.get());
+ RTC_DCHECK(!render_worker_thread_.get());
- if (_paRenderBuffer)
- {
- delete _paRenderBuffer;
- _paRenderBuffer = NULL;
- }
+ if (_paRenderBuffer) {
+ delete _paRenderBuffer;
+ _paRenderBuffer = NULL;
+ }
- if (_paCaptureBuffer)
- {
- delete _paCaptureBuffer;
- _paCaptureBuffer = NULL;
- }
+ if (_paCaptureBuffer) {
+ delete _paCaptureBuffer;
+ _paCaptureBuffer = NULL;
+ }
- if (_renderBufData)
- {
- delete[] _renderBufData;
- _renderBufData = NULL;
- }
+ if (_renderBufData) {
+ delete[] _renderBufData;
+ _renderBufData = NULL;
+ }
- if (_captureBufData)
- {
- delete[] _captureBufData;
- _captureBufData = NULL;
- }
+ if (_captureBufData) {
+ delete[] _captureBufData;
+ _captureBufData = NULL;
+ }
- kern_return_t kernErr = KERN_SUCCESS;
- kernErr = semaphore_destroy(mach_task_self(), _renderSemaphore);
- if (kernErr != KERN_SUCCESS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " semaphore_destroy() error: %d", kernErr);
- }
+ kern_return_t kernErr = KERN_SUCCESS;
+ kernErr = semaphore_destroy(mach_task_self(), _renderSemaphore);
+ if (kernErr != KERN_SUCCESS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " semaphore_destroy() error: %d", kernErr);
+ }
- kernErr = semaphore_destroy(mach_task_self(), _captureSemaphore);
- if (kernErr != KERN_SUCCESS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " semaphore_destroy() error: %d", kernErr);
- }
+ kernErr = semaphore_destroy(mach_task_self(), _captureSemaphore);
+ if (kernErr != KERN_SUCCESS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " semaphore_destroy() error: %d", kernErr);
+ }
- delete &_stopEvent;
- delete &_stopEventRec;
- delete &_critSect;
+ delete &_stopEvent;
+ delete &_stopEventRec;
+ delete &_critSect;
}
// ============================================================================
// API
// ============================================================================
-void AudioDeviceMac::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer)
-{
+void AudioDeviceMac::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
+ CriticalSectionScoped lock(&_critSect);
- CriticalSectionScoped lock(&_critSect);
+ _ptrAudioBuffer = audioBuffer;
- _ptrAudioBuffer = audioBuffer;
-
- // inform the AudioBuffer about default settings for this implementation
- _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC);
- _ptrAudioBuffer->SetPlayoutSampleRate(N_PLAY_SAMPLES_PER_SEC);
- _ptrAudioBuffer->SetRecordingChannels(N_REC_CHANNELS);
- _ptrAudioBuffer->SetPlayoutChannels(N_PLAY_CHANNELS);
+ // inform the AudioBuffer about default settings for this implementation
+ _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC);
+ _ptrAudioBuffer->SetPlayoutSampleRate(N_PLAY_SAMPLES_PER_SEC);
+ _ptrAudioBuffer->SetRecordingChannels(N_REC_CHANNELS);
+ _ptrAudioBuffer->SetPlayoutChannels(N_PLAY_CHANNELS);
}
int32_t AudioDeviceMac::ActiveAudioLayer(
- AudioDeviceModule::AudioLayer& audioLayer) const
-{
- audioLayer = AudioDeviceModule::kPlatformDefaultAudio;
- return 0;
+ AudioDeviceModule::AudioLayer& audioLayer) const {
+ audioLayer = AudioDeviceModule::kPlatformDefaultAudio;
+ return 0;
}
-int32_t AudioDeviceMac::Init()
-{
+int32_t AudioDeviceMac::Init() {
+ CriticalSectionScoped lock(&_critSect);
- CriticalSectionScoped lock(&_critSect);
+ if (_initialized) {
+ return 0;
+ }
- if (_initialized)
- {
- return 0;
- }
+ OSStatus err = noErr;
- OSStatus err = noErr;
+ _isShutDown = false;
- _isShutDown = false;
-
- // PortAudio ring buffers require an elementCount which is a power of two.
- if (_renderBufData == NULL)
- {
- UInt32 powerOfTwo = 1;
- while (powerOfTwo < PLAY_BUF_SIZE_IN_SAMPLES)
- {
- powerOfTwo <<= 1;
- }
- _renderBufSizeSamples = powerOfTwo;
- _renderBufData = new SInt16[_renderBufSizeSamples];
+ // PortAudio ring buffers require an elementCount which is a power of two.
+ if (_renderBufData == NULL) {
+ UInt32 powerOfTwo = 1;
+ while (powerOfTwo < PLAY_BUF_SIZE_IN_SAMPLES) {
+ powerOfTwo <<= 1;
}
+ _renderBufSizeSamples = powerOfTwo;
+ _renderBufData = new SInt16[_renderBufSizeSamples];
+ }
- if (_paRenderBuffer == NULL)
- {
- _paRenderBuffer = new PaUtilRingBuffer;
- PaRingBufferSize bufSize = -1;
- bufSize = PaUtil_InitializeRingBuffer(_paRenderBuffer, sizeof(SInt16),
- _renderBufSizeSamples,
- _renderBufData);
- if (bufSize == -1)
- {
- WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice,
- _id, " PaUtil_InitializeRingBuffer() error");
- return -1;
- }
+ if (_paRenderBuffer == NULL) {
+ _paRenderBuffer = new PaUtilRingBuffer;
+ PaRingBufferSize bufSize = -1;
+ bufSize = PaUtil_InitializeRingBuffer(
+ _paRenderBuffer, sizeof(SInt16), _renderBufSizeSamples, _renderBufData);
+ if (bufSize == -1) {
+ WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id,
+ " PaUtil_InitializeRingBuffer() error");
+ return -1;
}
+ }
- if (_captureBufData == NULL)
- {
- UInt32 powerOfTwo = 1;
- while (powerOfTwo < REC_BUF_SIZE_IN_SAMPLES)
- {
- powerOfTwo <<= 1;
- }
- _captureBufSizeSamples = powerOfTwo;
- _captureBufData = new Float32[_captureBufSizeSamples];
+ if (_captureBufData == NULL) {
+ UInt32 powerOfTwo = 1;
+ while (powerOfTwo < REC_BUF_SIZE_IN_SAMPLES) {
+ powerOfTwo <<= 1;
}
+ _captureBufSizeSamples = powerOfTwo;
+ _captureBufData = new Float32[_captureBufSizeSamples];
+ }
- if (_paCaptureBuffer == NULL)
- {
- _paCaptureBuffer = new PaUtilRingBuffer;
- PaRingBufferSize bufSize = -1;
- bufSize = PaUtil_InitializeRingBuffer(_paCaptureBuffer,
- sizeof(Float32),
- _captureBufSizeSamples,
- _captureBufData);
- if (bufSize == -1)
- {
- WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice,
- _id, " PaUtil_InitializeRingBuffer() error");
- return -1;
- }
+ if (_paCaptureBuffer == NULL) {
+ _paCaptureBuffer = new PaUtilRingBuffer;
+ PaRingBufferSize bufSize = -1;
+ bufSize =
+ PaUtil_InitializeRingBuffer(_paCaptureBuffer, sizeof(Float32),
+ _captureBufSizeSamples, _captureBufData);
+ if (bufSize == -1) {
+ WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id,
+ " PaUtil_InitializeRingBuffer() error");
+ return -1;
}
+ }
- kern_return_t kernErr = KERN_SUCCESS;
- kernErr = semaphore_create(mach_task_self(), &_renderSemaphore,
- SYNC_POLICY_FIFO, 0);
- if (kernErr != KERN_SUCCESS)
- {
- WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id,
- " semaphore_create() error: %d", kernErr);
- return -1;
- }
+ kern_return_t kernErr = KERN_SUCCESS;
+ kernErr = semaphore_create(mach_task_self(), &_renderSemaphore,
+ SYNC_POLICY_FIFO, 0);
+ if (kernErr != KERN_SUCCESS) {
+ WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id,
+ " semaphore_create() error: %d", kernErr);
+ return -1;
+ }
- kernErr = semaphore_create(mach_task_self(), &_captureSemaphore,
- SYNC_POLICY_FIFO, 0);
- if (kernErr != KERN_SUCCESS)
- {
- WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id,
- " semaphore_create() error: %d", kernErr);
- return -1;
- }
+ kernErr = semaphore_create(mach_task_self(), &_captureSemaphore,
+ SYNC_POLICY_FIFO, 0);
+ if (kernErr != KERN_SUCCESS) {
+ WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id,
+ " semaphore_create() error: %d", kernErr);
+ return -1;
+ }
- // Setting RunLoop to NULL here instructs HAL to manage its own thread for
- // notifications. This was the default behaviour on OS X 10.5 and earlier,
- // but now must be explicitly specified. HAL would otherwise try to use the
- // main thread to issue notifications.
- AudioObjectPropertyAddress propertyAddress = {
- kAudioHardwarePropertyRunLoop,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
- CFRunLoopRef runLoop = NULL;
- UInt32 size = sizeof(CFRunLoopRef);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(kAudioObjectSystemObject,
- &propertyAddress, 0, NULL, size, &runLoop));
-
- // Listen for any device changes.
- propertyAddress.mSelector = kAudioHardwarePropertyDevices;
- WEBRTC_CA_LOG_ERR(AudioObjectAddPropertyListener(kAudioObjectSystemObject,
- &propertyAddress, &objectListenerProc, this));
-
- // Determine if this is a MacBook Pro
- _macBookPro = false;
- _macBookProPanRight = false;
- char buf[128];
- size_t length = sizeof(buf);
- memset(buf, 0, length);
-
- int intErr = sysctlbyname("hw.model", buf, &length, NULL, 0);
- if (intErr != 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " Error in sysctlbyname(): %d", err);
- } else
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " Hardware model: %s", buf);
- if (strncmp(buf, "MacBookPro", 10) == 0)
- {
- _macBookPro = true;
- }
+ // Setting RunLoop to NULL here instructs HAL to manage its own thread for
+ // notifications. This was the default behaviour on OS X 10.5 and earlier,
+ // but now must be explicitly specified. HAL would otherwise try to use the
+ // main thread to issue notifications.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster};
+ CFRunLoopRef runLoop = NULL;
+ UInt32 size = sizeof(CFRunLoopRef);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ kAudioObjectSystemObject, &propertyAddress, 0, NULL, size, &runLoop));
+
+ // Listen for any device changes.
+ propertyAddress.mSelector = kAudioHardwarePropertyDevices;
+ WEBRTC_CA_LOG_ERR(AudioObjectAddPropertyListener(
+ kAudioObjectSystemObject, &propertyAddress, &objectListenerProc, this));
+
+ // Determine if this is a MacBook Pro
+ _macBookPro = false;
+ _macBookProPanRight = false;
+ char buf[128];
+ size_t length = sizeof(buf);
+ memset(buf, 0, length);
+
+ int intErr = sysctlbyname("hw.model", buf, &length, NULL, 0);
+ if (intErr != 0) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " Error in sysctlbyname(): %d", err);
+ } else {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Hardware model: %s",
+ buf);
+ if (strncmp(buf, "MacBookPro", 10) == 0) {
+ _macBookPro = true;
}
+ }
- _playWarning = 0;
- _playError = 0;
- _recWarning = 0;
- _recError = 0;
+ _playWarning = 0;
+ _playError = 0;
+ _recWarning = 0;
+ _recError = 0;
- get_mic_volume_counter_ms_ = 0;
+ get_mic_volume_counter_ms_ = 0;
- _initialized = true;
+ _initialized = true;
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::Terminate()
-{
+int32_t AudioDeviceMac::Terminate() {
+ if (!_initialized) {
+ return 0;
+ }
- if (!_initialized)
- {
- return 0;
- }
+ if (_recording) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " Recording must be stopped");
+ return -1;
+ }
- if (_recording)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " Recording must be stopped");
- return -1;
- }
+ if (_playing) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " Playback must be stopped");
+ return -1;
+ }
- if (_playing)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " Playback must be stopped");
- return -1;
- }
+ _critSect.Enter();
- _critSect.Enter();
+ _mixerManager.Close();
- _mixerManager.Close();
+ OSStatus err = noErr;
+ int retVal = 0;
- OSStatus err = noErr;
- int retVal = 0;
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster};
+ WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(
+ kAudioObjectSystemObject, &propertyAddress, &objectListenerProc, this));
- AudioObjectPropertyAddress propertyAddress = {
- kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
- WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(kAudioObjectSystemObject,
- &propertyAddress, &objectListenerProc, this));
-
- err = AudioHardwareUnload();
- if (err != noErr)
- {
- logCAMsg(kTraceError, kTraceAudioDevice, _id,
- "Error in AudioHardwareUnload()", (const char*) &err);
- retVal = -1;
- }
+ err = AudioHardwareUnload();
+ if (err != noErr) {
+ logCAMsg(kTraceError, kTraceAudioDevice, _id,
+ "Error in AudioHardwareUnload()", (const char*)&err);
+ retVal = -1;
+ }
- _isShutDown = true;
- _initialized = false;
- _outputDeviceIsSpecified = false;
- _inputDeviceIsSpecified = false;
+ _isShutDown = true;
+ _initialized = false;
+ _outputDeviceIsSpecified = false;
+ _inputDeviceIsSpecified = false;
- _critSect.Leave();
+ _critSect.Leave();
- return retVal;
+ return retVal;
}
-bool AudioDeviceMac::Initialized() const
-{
- return (_initialized);
+bool AudioDeviceMac::Initialized() const {
+ return (_initialized);
}
-int32_t AudioDeviceMac::SpeakerIsAvailable(bool& available)
-{
-
- bool wasInitialized = _mixerManager.SpeakerIsInitialized();
+int32_t AudioDeviceMac::SpeakerIsAvailable(bool& available) {
+ bool wasInitialized = _mixerManager.SpeakerIsInitialized();
- // Make an attempt to open up the
- // output mixer corresponding to the currently selected output device.
- //
- if (!wasInitialized && InitSpeaker() == -1)
- {
- available = false;
- return 0;
- }
+ // Make an attempt to open up the
+ // output mixer corresponding to the currently selected output device.
+ //
+ if (!wasInitialized && InitSpeaker() == -1) {
+ available = false;
+ return 0;
+ }
- // Given that InitSpeaker was successful, we know that a valid speaker
- // exists.
- available = true;
+ // Given that InitSpeaker was successful, we know that a valid speaker
+ // exists.
+ available = true;
- // Close the initialized output mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseSpeaker();
- }
+ // Close the initialized output mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseSpeaker();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::InitSpeaker()
-{
-
- CriticalSectionScoped lock(&_critSect);
+int32_t AudioDeviceMac::InitSpeaker() {
+ CriticalSectionScoped lock(&_critSect);
- if (_playing)
- {
- return -1;
- }
+ if (_playing) {
+ return -1;
+ }
- if (InitDevice(_outputDeviceIndex, _outputDeviceID, false) == -1)
- {
- return -1;
- }
+ if (InitDevice(_outputDeviceIndex, _outputDeviceID, false) == -1) {
+ return -1;
+ }
- if (_inputDeviceID == _outputDeviceID)
- {
- _twoDevices = false;
- } else
- {
- _twoDevices = true;
- }
+ if (_inputDeviceID == _outputDeviceID) {
+ _twoDevices = false;
+ } else {
+ _twoDevices = true;
+ }
- if (_mixerManager.OpenSpeaker(_outputDeviceID) == -1)
- {
- return -1;
- }
+ if (_mixerManager.OpenSpeaker(_outputDeviceID) == -1) {
+ return -1;
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::MicrophoneIsAvailable(bool& available)
-{
-
- bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
+int32_t AudioDeviceMac::MicrophoneIsAvailable(bool& available) {
+ bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
- // Make an attempt to open up the
- // input mixer corresponding to the currently selected output device.
- //
- if (!wasInitialized && InitMicrophone() == -1)
- {
- available = false;
- return 0;
- }
+ // Make an attempt to open up the
+ // input mixer corresponding to the currently selected output device.
+ //
+ if (!wasInitialized && InitMicrophone() == -1) {
+ available = false;
+ return 0;
+ }
- // Given that InitMicrophone was successful, we know that a valid microphone
- // exists.
- available = true;
+ // Given that InitMicrophone was successful, we know that a valid microphone
+ // exists.
+ available = true;
- // Close the initialized input mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseMicrophone();
- }
+ // Close the initialized input mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseMicrophone();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::InitMicrophone()
-{
+int32_t AudioDeviceMac::InitMicrophone() {
+ CriticalSectionScoped lock(&_critSect);
- CriticalSectionScoped lock(&_critSect);
-
- if (_recording)
- {
- return -1;
- }
+ if (_recording) {
+ return -1;
+ }
- if (InitDevice(_inputDeviceIndex, _inputDeviceID, true) == -1)
- {
- return -1;
- }
+ if (InitDevice(_inputDeviceIndex, _inputDeviceID, true) == -1) {
+ return -1;
+ }
- if (_inputDeviceID == _outputDeviceID)
- {
- _twoDevices = false;
- } else
- {
- _twoDevices = true;
- }
+ if (_inputDeviceID == _outputDeviceID) {
+ _twoDevices = false;
+ } else {
+ _twoDevices = true;
+ }
- if (_mixerManager.OpenMicrophone(_inputDeviceID) == -1)
- {
- return -1;
- }
+ if (_mixerManager.OpenMicrophone(_inputDeviceID) == -1) {
+ return -1;
+ }
- return 0;
+ return 0;
}
-bool AudioDeviceMac::SpeakerIsInitialized() const
-{
- return (_mixerManager.SpeakerIsInitialized());
+bool AudioDeviceMac::SpeakerIsInitialized() const {
+ return (_mixerManager.SpeakerIsInitialized());
}
-bool AudioDeviceMac::MicrophoneIsInitialized() const
-{
- return (_mixerManager.MicrophoneIsInitialized());
+bool AudioDeviceMac::MicrophoneIsInitialized() const {
+ return (_mixerManager.MicrophoneIsInitialized());
}
-int32_t AudioDeviceMac::SpeakerVolumeIsAvailable(bool& available)
-{
-
- bool wasInitialized = _mixerManager.SpeakerIsInitialized();
+int32_t AudioDeviceMac::SpeakerVolumeIsAvailable(bool& available) {
+ bool wasInitialized = _mixerManager.SpeakerIsInitialized();
- // Make an attempt to open up the
- // output mixer corresponding to the currently selected output device.
- //
- if (!wasInitialized && InitSpeaker() == -1)
- {
- // If we end up here it means that the selected speaker has no volume
- // control.
- available = false;
- return 0;
- }
+ // Make an attempt to open up the
+ // output mixer corresponding to the currently selected output device.
+ //
+ if (!wasInitialized && InitSpeaker() == -1) {
+ // If we end up here it means that the selected speaker has no volume
+ // control.
+ available = false;
+ return 0;
+ }
- // Given that InitSpeaker was successful, we know that a volume control exists
- //
- available = true;
+ // Given that InitSpeaker was successful, we know that a volume control exists
+ //
+ available = true;
- // Close the initialized output mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseSpeaker();
- }
+ // Close the initialized output mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseSpeaker();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::SetSpeakerVolume(uint32_t volume)
-{
-
- return (_mixerManager.SetSpeakerVolume(volume));
+int32_t AudioDeviceMac::SetSpeakerVolume(uint32_t volume) {
+ return (_mixerManager.SetSpeakerVolume(volume));
}
-int32_t AudioDeviceMac::SpeakerVolume(uint32_t& volume) const
-{
-
- uint32_t level(0);
+int32_t AudioDeviceMac::SpeakerVolume(uint32_t& volume) const {
+ uint32_t level(0);
- if (_mixerManager.SpeakerVolume(level) == -1)
- {
- return -1;
- }
+ if (_mixerManager.SpeakerVolume(level) == -1) {
+ return -1;
+ }
- volume = level;
- return 0;
+ volume = level;
+ return 0;
}
int32_t AudioDeviceMac::SetWaveOutVolume(uint16_t volumeLeft,
- uint16_t volumeRight)
-{
-
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " API call not supported on this platform");
- return -1;
+ uint16_t volumeRight) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " API call not supported on this platform");
+ return -1;
}
-int32_t
-AudioDeviceMac::WaveOutVolume(uint16_t& /*volumeLeft*/,
- uint16_t& /*volumeRight*/) const
-{
-
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " API call not supported on this platform");
- return -1;
+int32_t AudioDeviceMac::WaveOutVolume(uint16_t& /*volumeLeft*/,
+ uint16_t& /*volumeRight*/) const {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " API call not supported on this platform");
+ return -1;
}
-int32_t AudioDeviceMac::MaxSpeakerVolume(uint32_t& maxVolume) const
-{
+int32_t AudioDeviceMac::MaxSpeakerVolume(uint32_t& maxVolume) const {
+ uint32_t maxVol(0);
- uint32_t maxVol(0);
-
- if (_mixerManager.MaxSpeakerVolume(maxVol) == -1)
- {
- return -1;
- }
+ if (_mixerManager.MaxSpeakerVolume(maxVol) == -1) {
+ return -1;
+ }
- maxVolume = maxVol;
- return 0;
+ maxVolume = maxVol;
+ return 0;
}
-int32_t AudioDeviceMac::MinSpeakerVolume(uint32_t& minVolume) const
-{
-
- uint32_t minVol(0);
+int32_t AudioDeviceMac::MinSpeakerVolume(uint32_t& minVolume) const {
+ uint32_t minVol(0);
- if (_mixerManager.MinSpeakerVolume(minVol) == -1)
- {
- return -1;
- }
+ if (_mixerManager.MinSpeakerVolume(minVol) == -1) {
+ return -1;
+ }
- minVolume = minVol;
- return 0;
+ minVolume = minVol;
+ return 0;
}
-int32_t
-AudioDeviceMac::SpeakerVolumeStepSize(uint16_t& stepSize) const
-{
-
- uint16_t delta(0);
+int32_t AudioDeviceMac::SpeakerVolumeStepSize(uint16_t& stepSize) const {
+ uint16_t delta(0);
- if (_mixerManager.SpeakerVolumeStepSize(delta) == -1)
- {
- return -1;
- }
+ if (_mixerManager.SpeakerVolumeStepSize(delta) == -1) {
+ return -1;
+ }
- stepSize = delta;
- return 0;
+ stepSize = delta;
+ return 0;
}
-int32_t AudioDeviceMac::SpeakerMuteIsAvailable(bool& available)
-{
-
- bool isAvailable(false);
- bool wasInitialized = _mixerManager.SpeakerIsInitialized();
+int32_t AudioDeviceMac::SpeakerMuteIsAvailable(bool& available) {
+ bool isAvailable(false);
+ bool wasInitialized = _mixerManager.SpeakerIsInitialized();
- // Make an attempt to open up the
- // output mixer corresponding to the currently selected output device.
- //
- if (!wasInitialized && InitSpeaker() == -1)
- {
- // If we end up here it means that the selected speaker has no volume
- // control, hence it is safe to state that there is no mute control
- // already at this stage.
- available = false;
- return 0;
- }
+ // Make an attempt to open up the
+ // output mixer corresponding to the currently selected output device.
+ //
+ if (!wasInitialized && InitSpeaker() == -1) {
+ // If we end up here it means that the selected speaker has no volume
+ // control, hence it is safe to state that there is no mute control
+ // already at this stage.
+ available = false;
+ return 0;
+ }
- // Check if the selected speaker has a mute control
- //
- _mixerManager.SpeakerMuteIsAvailable(isAvailable);
+ // Check if the selected speaker has a mute control
+ //
+ _mixerManager.SpeakerMuteIsAvailable(isAvailable);
- available = isAvailable;
+ available = isAvailable;
- // Close the initialized output mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseSpeaker();
- }
+ // Close the initialized output mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseSpeaker();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::SetSpeakerMute(bool enable)
-{
- return (_mixerManager.SetSpeakerMute(enable));
+int32_t AudioDeviceMac::SetSpeakerMute(bool enable) {
+ return (_mixerManager.SetSpeakerMute(enable));
}
-int32_t AudioDeviceMac::SpeakerMute(bool& enabled) const
-{
+int32_t AudioDeviceMac::SpeakerMute(bool& enabled) const {
+ bool muted(0);
- bool muted(0);
-
- if (_mixerManager.SpeakerMute(muted) == -1)
- {
- return -1;
- }
+ if (_mixerManager.SpeakerMute(muted) == -1) {
+ return -1;
+ }
- enabled = muted;
- return 0;
+ enabled = muted;
+ return 0;
}
-int32_t AudioDeviceMac::MicrophoneMuteIsAvailable(bool& available)
-{
+int32_t AudioDeviceMac::MicrophoneMuteIsAvailable(bool& available) {
+ bool isAvailable(false);
+ bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
- bool isAvailable(false);
- bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
-
- // Make an attempt to open up the
- // input mixer corresponding to the currently selected input device.
- //
- if (!wasInitialized && InitMicrophone() == -1)
- {
- // If we end up here it means that the selected microphone has no volume
- // control, hence it is safe to state that there is no boost control
- // already at this stage.
- available = false;
- return 0;
- }
+ // Make an attempt to open up the
+ // input mixer corresponding to the currently selected input device.
+ //
+ if (!wasInitialized && InitMicrophone() == -1) {
+ // If we end up here it means that the selected microphone has no volume
+ // control, hence it is safe to state that there is no boost control
+ // already at this stage.
+ available = false;
+ return 0;
+ }
- // Check if the selected microphone has a mute control
- //
- _mixerManager.MicrophoneMuteIsAvailable(isAvailable);
- available = isAvailable;
+ // Check if the selected microphone has a mute control
+ //
+ _mixerManager.MicrophoneMuteIsAvailable(isAvailable);
+ available = isAvailable;
- // Close the initialized input mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseMicrophone();
- }
+ // Close the initialized input mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseMicrophone();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::SetMicrophoneMute(bool enable)
-{
- return (_mixerManager.SetMicrophoneMute(enable));
+int32_t AudioDeviceMac::SetMicrophoneMute(bool enable) {
+ return (_mixerManager.SetMicrophoneMute(enable));
}
-int32_t AudioDeviceMac::MicrophoneMute(bool& enabled) const
-{
+int32_t AudioDeviceMac::MicrophoneMute(bool& enabled) const {
+ bool muted(0);
- bool muted(0);
-
- if (_mixerManager.MicrophoneMute(muted) == -1)
- {
- return -1;
- }
+ if (_mixerManager.MicrophoneMute(muted) == -1) {
+ return -1;
+ }
- enabled = muted;
- return 0;
+ enabled = muted;
+ return 0;
}
-int32_t AudioDeviceMac::MicrophoneBoostIsAvailable(bool& available)
-{
-
- bool isAvailable(false);
- bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
+int32_t AudioDeviceMac::MicrophoneBoostIsAvailable(bool& available) {
+ bool isAvailable(false);
+ bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
- // Enumerate all avaliable microphone and make an attempt to open up the
- // input mixer corresponding to the currently selected input device.
- //
- if (!wasInitialized && InitMicrophone() == -1)
- {
- // If we end up here it means that the selected microphone has no volume
- // control, hence it is safe to state that there is no boost control
- // already at this stage.
- available = false;
- return 0;
- }
+ // Enumerate all avaliable microphone and make an attempt to open up the
+ // input mixer corresponding to the currently selected input device.
+ //
+ if (!wasInitialized && InitMicrophone() == -1) {
+ // If we end up here it means that the selected microphone has no volume
+ // control, hence it is safe to state that there is no boost control
+ // already at this stage.
+ available = false;
+ return 0;
+ }
- // Check if the selected microphone has a boost control
- //
- _mixerManager.MicrophoneBoostIsAvailable(isAvailable);
- available = isAvailable;
+ // Check if the selected microphone has a boost control
+ //
+ _mixerManager.MicrophoneBoostIsAvailable(isAvailable);
+ available = isAvailable;
- // Close the initialized input mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseMicrophone();
- }
+ // Close the initialized input mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseMicrophone();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::SetMicrophoneBoost(bool enable)
-{
-
- return (_mixerManager.SetMicrophoneBoost(enable));
+int32_t AudioDeviceMac::SetMicrophoneBoost(bool enable) {
+ return (_mixerManager.SetMicrophoneBoost(enable));
}
-int32_t AudioDeviceMac::MicrophoneBoost(bool& enabled) const
-{
-
- bool onOff(0);
+int32_t AudioDeviceMac::MicrophoneBoost(bool& enabled) const {
+ bool onOff(0);
- if (_mixerManager.MicrophoneBoost(onOff) == -1)
- {
- return -1;
- }
+ if (_mixerManager.MicrophoneBoost(onOff) == -1) {
+ return -1;
+ }
- enabled = onOff;
- return 0;
+ enabled = onOff;
+ return 0;
}
-int32_t AudioDeviceMac::StereoRecordingIsAvailable(bool& available)
-{
-
- bool isAvailable(false);
- bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
-
- if (!wasInitialized && InitMicrophone() == -1)
- {
- // Cannot open the specified device
- available = false;
- return 0;
- }
-
- // Check if the selected microphone can record stereo
- //
- _mixerManager.StereoRecordingIsAvailable(isAvailable);
- available = isAvailable;
-
- // Close the initialized input mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseMicrophone();
- }
+int32_t AudioDeviceMac::StereoRecordingIsAvailable(bool& available) {
+ bool isAvailable(false);
+ bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
+ if (!wasInitialized && InitMicrophone() == -1) {
+ // Cannot open the specified device
+ available = false;
return 0;
-}
+ }
-int32_t AudioDeviceMac::SetStereoRecording(bool enable)
-{
+ // Check if the selected microphone can record stereo
+ //
+ _mixerManager.StereoRecordingIsAvailable(isAvailable);
+ available = isAvailable;
- if (enable)
- _recChannels = 2;
- else
- _recChannels = 1;
+ // Close the initialized input mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseMicrophone();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::StereoRecording(bool& enabled) const
-{
+int32_t AudioDeviceMac::SetStereoRecording(bool enable) {
+ if (enable)
+ _recChannels = 2;
+ else
+ _recChannels = 1;
- if (_recChannels == 2)
- enabled = true;
- else
- enabled = false;
-
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::StereoPlayoutIsAvailable(bool& available)
-{
-
- bool isAvailable(false);
- bool wasInitialized = _mixerManager.SpeakerIsInitialized();
+int32_t AudioDeviceMac::StereoRecording(bool& enabled) const {
+ if (_recChannels == 2)
+ enabled = true;
+ else
+ enabled = false;
- if (!wasInitialized && InitSpeaker() == -1)
- {
- // Cannot open the specified device
- available = false;
- return 0;
- }
-
- // Check if the selected microphone can record stereo
- //
- _mixerManager.StereoPlayoutIsAvailable(isAvailable);
- available = isAvailable;
+ return 0;
+}
- // Close the initialized input mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseSpeaker();
- }
+int32_t AudioDeviceMac::StereoPlayoutIsAvailable(bool& available) {
+ bool isAvailable(false);
+ bool wasInitialized = _mixerManager.SpeakerIsInitialized();
+ if (!wasInitialized && InitSpeaker() == -1) {
+ // Cannot open the specified device
+ available = false;
return 0;
-}
+ }
-int32_t AudioDeviceMac::SetStereoPlayout(bool enable)
-{
+ // Check if the selected microphone can record stereo
+ //
+ _mixerManager.StereoPlayoutIsAvailable(isAvailable);
+ available = isAvailable;
- if (enable)
- _playChannels = 2;
- else
- _playChannels = 1;
+ // Close the initialized input mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseSpeaker();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::StereoPlayout(bool& enabled) const
-{
-
- if (_playChannels == 2)
- enabled = true;
- else
- enabled = false;
+int32_t AudioDeviceMac::SetStereoPlayout(bool enable) {
+ if (enable)
+ _playChannels = 2;
+ else
+ _playChannels = 1;
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::SetAGC(bool enable)
-{
-
- _AGC = enable;
+int32_t AudioDeviceMac::StereoPlayout(bool& enabled) const {
+ if (_playChannels == 2)
+ enabled = true;
+ else
+ enabled = false;
- return 0;
+ return 0;
}
-bool AudioDeviceMac::AGC() const
-{
+int32_t AudioDeviceMac::SetAGC(bool enable) {
+ _AGC = enable;
- return _AGC;
+ return 0;
}
-int32_t AudioDeviceMac::MicrophoneVolumeIsAvailable(bool& available)
-{
+bool AudioDeviceMac::AGC() const {
+ return _AGC;
+}
- bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
+int32_t AudioDeviceMac::MicrophoneVolumeIsAvailable(bool& available) {
+ bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
- // Make an attempt to open up the
- // input mixer corresponding to the currently selected output device.
- //
- if (!wasInitialized && InitMicrophone() == -1)
- {
- // If we end up here it means that the selected microphone has no volume
- // control.
- available = false;
- return 0;
- }
+ // Make an attempt to open up the
+ // input mixer corresponding to the currently selected output device.
+ //
+ if (!wasInitialized && InitMicrophone() == -1) {
+ // If we end up here it means that the selected microphone has no volume
+ // control.
+ available = false;
+ return 0;
+ }
- // Given that InitMicrophone was successful, we know that a volume control
- // exists
- //
- available = true;
+ // Given that InitMicrophone was successful, we know that a volume control
+ // exists
+ //
+ available = true;
- // Close the initialized input mixer
- //
- if (!wasInitialized)
- {
- _mixerManager.CloseMicrophone();
- }
+ // Close the initialized input mixer
+ //
+ if (!wasInitialized) {
+ _mixerManager.CloseMicrophone();
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::SetMicrophoneVolume(uint32_t volume)
-{
-
- return (_mixerManager.SetMicrophoneVolume(volume));
+int32_t AudioDeviceMac::SetMicrophoneVolume(uint32_t volume) {
+ return (_mixerManager.SetMicrophoneVolume(volume));
}
-int32_t AudioDeviceMac::MicrophoneVolume(uint32_t& volume) const
-{
+int32_t AudioDeviceMac::MicrophoneVolume(uint32_t& volume) const {
+ uint32_t level(0);
- uint32_t level(0);
-
- if (_mixerManager.MicrophoneVolume(level) == -1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " failed to retrive current microphone level");
- return -1;
- }
+ if (_mixerManager.MicrophoneVolume(level) == -1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " failed to retrive current microphone level");
+ return -1;
+ }
- volume = level;
- return 0;
+ volume = level;
+ return 0;
}
-int32_t
-AudioDeviceMac::MaxMicrophoneVolume(uint32_t& maxVolume) const
-{
-
- uint32_t maxVol(0);
+int32_t AudioDeviceMac::MaxMicrophoneVolume(uint32_t& maxVolume) const {
+ uint32_t maxVol(0);
- if (_mixerManager.MaxMicrophoneVolume(maxVol) == -1)
- {
- return -1;
- }
+ if (_mixerManager.MaxMicrophoneVolume(maxVol) == -1) {
+ return -1;
+ }
- maxVolume = maxVol;
- return 0;
+ maxVolume = maxVol;
+ return 0;
}
-int32_t
-AudioDeviceMac::MinMicrophoneVolume(uint32_t& minVolume) const
-{
-
- uint32_t minVol(0);
+int32_t AudioDeviceMac::MinMicrophoneVolume(uint32_t& minVolume) const {
+ uint32_t minVol(0);
- if (_mixerManager.MinMicrophoneVolume(minVol) == -1)
- {
- return -1;
- }
+ if (_mixerManager.MinMicrophoneVolume(minVol) == -1) {
+ return -1;
+ }
- minVolume = minVol;
- return 0;
+ minVolume = minVol;
+ return 0;
}
-int32_t
-AudioDeviceMac::MicrophoneVolumeStepSize(uint16_t& stepSize) const
-{
-
- uint16_t delta(0);
+int32_t AudioDeviceMac::MicrophoneVolumeStepSize(uint16_t& stepSize) const {
+ uint16_t delta(0);
- if (_mixerManager.MicrophoneVolumeStepSize(delta) == -1)
- {
- return -1;
- }
+ if (_mixerManager.MicrophoneVolumeStepSize(delta) == -1) {
+ return -1;
+ }
- stepSize = delta;
- return 0;
+ stepSize = delta;
+ return 0;
}
-int16_t AudioDeviceMac::PlayoutDevices()
-{
-
- AudioDeviceID playDevices[MaxNumberDevices];
- return GetNumberDevices(kAudioDevicePropertyScopeOutput, playDevices,
- MaxNumberDevices);
+int16_t AudioDeviceMac::PlayoutDevices() {
+ AudioDeviceID playDevices[MaxNumberDevices];
+ return GetNumberDevices(kAudioDevicePropertyScopeOutput, playDevices,
+ MaxNumberDevices);
}
-int32_t AudioDeviceMac::SetPlayoutDevice(uint16_t index)
-{
- CriticalSectionScoped lock(&_critSect);
+int32_t AudioDeviceMac::SetPlayoutDevice(uint16_t index) {
+ CriticalSectionScoped lock(&_critSect);
- if (_playIsInitialized)
- {
- return -1;
- }
+ if (_playIsInitialized) {
+ return -1;
+ }
- AudioDeviceID playDevices[MaxNumberDevices];
- uint32_t nDevices = GetNumberDevices(kAudioDevicePropertyScopeOutput,
- playDevices, MaxNumberDevices);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " number of availiable waveform-audio output devices is %u",
- nDevices);
-
- if (index > (nDevices - 1))
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " device index is out of range [0,%u]", (nDevices - 1));
- return -1;
- }
+ AudioDeviceID playDevices[MaxNumberDevices];
+ uint32_t nDevices = GetNumberDevices(kAudioDevicePropertyScopeOutput,
+ playDevices, MaxNumberDevices);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " number of availiable waveform-audio output devices is %u",
+ nDevices);
- _outputDeviceIndex = index;
- _outputDeviceIsSpecified = true;
+ if (index > (nDevices - 1)) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " device index is out of range [0,%u]", (nDevices - 1));
+ return -1;
+ }
- return 0;
+ _outputDeviceIndex = index;
+ _outputDeviceIsSpecified = true;
+
+ return 0;
}
int32_t AudioDeviceMac::SetPlayoutDevice(
- AudioDeviceModule::WindowsDeviceType /*device*/)
-{
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "WindowsDeviceType not supported");
- return -1;
+ AudioDeviceModule::WindowsDeviceType /*device*/) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "WindowsDeviceType not supported");
+ return -1;
}
-int32_t AudioDeviceMac::PlayoutDeviceName(
- uint16_t index,
- char name[kAdmMaxDeviceNameSize],
- char guid[kAdmMaxGuidSize])
-{
+int32_t AudioDeviceMac::PlayoutDeviceName(uint16_t index,
+ char name[kAdmMaxDeviceNameSize],
+ char guid[kAdmMaxGuidSize]) {
+ const uint16_t nDevices(PlayoutDevices());
- const uint16_t nDevices(PlayoutDevices());
-
- if ((index > (nDevices - 1)) || (name == NULL))
- {
- return -1;
- }
+ if ((index > (nDevices - 1)) || (name == NULL)) {
+ return -1;
+ }
- memset(name, 0, kAdmMaxDeviceNameSize);
+ memset(name, 0, kAdmMaxDeviceNameSize);
- if (guid != NULL)
- {
- memset(guid, 0, kAdmMaxGuidSize);
- }
+ if (guid != NULL) {
+ memset(guid, 0, kAdmMaxGuidSize);
+ }
- return GetDeviceName(kAudioDevicePropertyScopeOutput, index, name);
+ return GetDeviceName(kAudioDevicePropertyScopeOutput, index, name);
}
-int32_t AudioDeviceMac::RecordingDeviceName(
- uint16_t index,
- char name[kAdmMaxDeviceNameSize],
- char guid[kAdmMaxGuidSize])
-{
-
- const uint16_t nDevices(RecordingDevices());
+int32_t AudioDeviceMac::RecordingDeviceName(uint16_t index,
+ char name[kAdmMaxDeviceNameSize],
+ char guid[kAdmMaxGuidSize]) {
+ const uint16_t nDevices(RecordingDevices());
- if ((index > (nDevices - 1)) || (name == NULL))
- {
- return -1;
- }
+ if ((index > (nDevices - 1)) || (name == NULL)) {
+ return -1;
+ }
- memset(name, 0, kAdmMaxDeviceNameSize);
+ memset(name, 0, kAdmMaxDeviceNameSize);
- if (guid != NULL)
- {
- memset(guid, 0, kAdmMaxGuidSize);
- }
+ if (guid != NULL) {
+ memset(guid, 0, kAdmMaxGuidSize);
+ }
- return GetDeviceName(kAudioDevicePropertyScopeInput, index, name);
+ return GetDeviceName(kAudioDevicePropertyScopeInput, index, name);
}
-int16_t AudioDeviceMac::RecordingDevices()
-{
-
- AudioDeviceID recDevices[MaxNumberDevices];
- return GetNumberDevices(kAudioDevicePropertyScopeInput, recDevices,
- MaxNumberDevices);
+int16_t AudioDeviceMac::RecordingDevices() {
+ AudioDeviceID recDevices[MaxNumberDevices];
+ return GetNumberDevices(kAudioDevicePropertyScopeInput, recDevices,
+ MaxNumberDevices);
}
-int32_t AudioDeviceMac::SetRecordingDevice(uint16_t index)
-{
+int32_t AudioDeviceMac::SetRecordingDevice(uint16_t index) {
+ if (_recIsInitialized) {
+ return -1;
+ }
- if (_recIsInitialized)
- {
- return -1;
- }
+ AudioDeviceID recDevices[MaxNumberDevices];
+ uint32_t nDevices = GetNumberDevices(kAudioDevicePropertyScopeInput,
+ recDevices, MaxNumberDevices);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " number of availiable waveform-audio input devices is %u",
+ nDevices);
- AudioDeviceID recDevices[MaxNumberDevices];
- uint32_t nDevices = GetNumberDevices(kAudioDevicePropertyScopeInput,
- recDevices, MaxNumberDevices);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " number of availiable waveform-audio input devices is %u",
- nDevices);
-
- if (index > (nDevices - 1))
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " device index is out of range [0,%u]", (nDevices - 1));
- return -1;
- }
+ if (index > (nDevices - 1)) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " device index is out of range [0,%u]", (nDevices - 1));
+ return -1;
+ }
- _inputDeviceIndex = index;
- _inputDeviceIsSpecified = true;
+ _inputDeviceIndex = index;
+ _inputDeviceIsSpecified = true;
- return 0;
+ return 0;
}
-
-int32_t
-AudioDeviceMac::SetRecordingDevice(AudioDeviceModule::WindowsDeviceType /*device*/)
-{
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "WindowsDeviceType not supported");
- return -1;
+int32_t AudioDeviceMac::SetRecordingDevice(
+ AudioDeviceModule::WindowsDeviceType /*device*/) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "WindowsDeviceType not supported");
+ return -1;
}
-int32_t AudioDeviceMac::PlayoutIsAvailable(bool& available)
-{
-
- available = true;
+int32_t AudioDeviceMac::PlayoutIsAvailable(bool& available) {
+ available = true;
- // Try to initialize the playout side
- if (InitPlayout() == -1)
- {
- available = false;
- }
+ // Try to initialize the playout side
+ if (InitPlayout() == -1) {
+ available = false;
+ }
- // We destroy the IOProc created by InitPlayout() in implDeviceIOProc().
- // We must actually start playout here in order to have the IOProc
- // deleted by calling StopPlayout().
- if (StartPlayout() == -1)
- {
- available = false;
- }
+ // We destroy the IOProc created by InitPlayout() in implDeviceIOProc().
+ // We must actually start playout here in order to have the IOProc
+ // deleted by calling StopPlayout().
+ if (StartPlayout() == -1) {
+ available = false;
+ }
- // Cancel effect of initialization
- if (StopPlayout() == -1)
- {
- available = false;
- }
+ // Cancel effect of initialization
+ if (StopPlayout() == -1) {
+ available = false;
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::RecordingIsAvailable(bool& available)
-{
-
- available = true;
+int32_t AudioDeviceMac::RecordingIsAvailable(bool& available) {
+ available = true;
- // Try to initialize the recording side
- if (InitRecording() == -1)
- {
- available = false;
- }
+ // Try to initialize the recording side
+ if (InitRecording() == -1) {
+ available = false;
+ }
- // We destroy the IOProc created by InitRecording() in implInDeviceIOProc().
- // We must actually start recording here in order to have the IOProc
- // deleted by calling StopRecording().
- if (StartRecording() == -1)
- {
- available = false;
- }
+ // We destroy the IOProc created by InitRecording() in implInDeviceIOProc().
+ // We must actually start recording here in order to have the IOProc
+ // deleted by calling StopRecording().
+ if (StartRecording() == -1) {
+ available = false;
+ }
- // Cancel effect of initialization
- if (StopRecording() == -1)
- {
- available = false;
- }
+ // Cancel effect of initialization
+ if (StopRecording() == -1) {
+ available = false;
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::InitPlayout()
-{
- CriticalSectionScoped lock(&_critSect);
+int32_t AudioDeviceMac::InitPlayout() {
+ CriticalSectionScoped lock(&_critSect);
- if (_playing)
- {
- return -1;
- }
+ if (_playing) {
+ return -1;
+ }
- if (!_outputDeviceIsSpecified)
- {
- return -1;
- }
+ if (!_outputDeviceIsSpecified) {
+ return -1;
+ }
- if (_playIsInitialized)
- {
- return 0;
- }
+ if (_playIsInitialized) {
+ return 0;
+ }
- // Initialize the speaker (devices might have been added or removed)
- if (InitSpeaker() == -1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " InitSpeaker() failed");
- }
+ // Initialize the speaker (devices might have been added or removed)
+ if (InitSpeaker() == -1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " InitSpeaker() failed");
+ }
- if (!MicrophoneIsInitialized())
- {
- // Make this call to check if we are using
- // one or two devices (_twoDevices)
- bool available = false;
- if (MicrophoneIsAvailable(available) == -1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " MicrophoneIsAvailable() failed");
- }
+ if (!MicrophoneIsInitialized()) {
+ // Make this call to check if we are using
+ // one or two devices (_twoDevices)
+ bool available = false;
+ if (MicrophoneIsAvailable(available) == -1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " MicrophoneIsAvailable() failed");
}
+ }
- PaUtil_FlushRingBuffer(_paRenderBuffer);
-
- OSStatus err = noErr;
- UInt32 size = 0;
- _renderDelayOffsetSamples = 0;
- _renderDelayUs = 0;
- _renderLatencyUs = 0;
- _renderDeviceIsAlive = 1;
- _doStop = false;
+ PaUtil_FlushRingBuffer(_paRenderBuffer);
+
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ _renderDelayOffsetSamples = 0;
+ _renderDelayUs = 0;
+ _renderLatencyUs = 0;
+ _renderDeviceIsAlive = 1;
+ _doStop = false;
+
+ // The internal microphone of a MacBook Pro is located under the left speaker
+ // grille. When the internal speakers are in use, we want to fully stereo
+ // pan to the right.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyDataSource, kAudioDevicePropertyScopeOutput, 0};
+ if (_macBookPro) {
+ _macBookProPanRight = false;
+ Boolean hasProperty =
+ AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ UInt32 dataSource = 0;
+ size = sizeof(dataSource);
+ WEBRTC_CA_LOG_WARN(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &dataSource));
+
+ if (dataSource == 'ispk') {
+ _macBookProPanRight = true;
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "MacBook Pro using internal speakers; stereo"
+ " panning right");
+ } else {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "MacBook Pro not using internal speakers");
+ }
- // The internal microphone of a MacBook Pro is located under the left speaker
- // grille. When the internal speakers are in use, we want to fully stereo
- // pan to the right.
- AudioObjectPropertyAddress
- propertyAddress = { kAudioDevicePropertyDataSource,
- kAudioDevicePropertyScopeOutput, 0 };
- if (_macBookPro)
- {
- _macBookProPanRight = false;
- Boolean hasProperty = AudioObjectHasProperty(_outputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- UInt32 dataSource = 0;
- size = sizeof(dataSource);
- WEBRTC_CA_LOG_WARN(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, &size, &dataSource));
-
- if (dataSource == 'ispk')
- {
- _macBookProPanRight = true;
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice,
- _id,
- "MacBook Pro using internal speakers; stereo"
- " panning right");
- } else
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice,
- _id, "MacBook Pro not using internal speakers");
- }
-
- // Add a listener to determine if the status changes.
- WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener(_outputDeviceID,
- &propertyAddress, &objectListenerProc, this));
- }
+ // Add a listener to determine if the status changes.
+ WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener(
+ _outputDeviceID, &propertyAddress, &objectListenerProc, this));
}
+ }
- // Get current stream description
- propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
- memset(&_outStreamFormat, 0, sizeof(_outStreamFormat));
- size = sizeof(_outStreamFormat);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress, 0, NULL, &size, &_outStreamFormat));
-
- if (_outStreamFormat.mFormatID != kAudioFormatLinearPCM)
- {
- logCAMsg(kTraceError, kTraceAudioDevice, _id,
- "Unacceptable output stream format -> mFormatID",
- (const char *) &_outStreamFormat.mFormatID);
- return -1;
- }
+ // Get current stream description
+ propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
+ memset(&_outStreamFormat, 0, sizeof(_outStreamFormat));
+ size = sizeof(_outStreamFormat);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &_outStreamFormat));
+
+ if (_outStreamFormat.mFormatID != kAudioFormatLinearPCM) {
+ logCAMsg(kTraceError, kTraceAudioDevice, _id,
+ "Unacceptable output stream format -> mFormatID",
+ (const char*)&_outStreamFormat.mFormatID);
+ return -1;
+ }
- if (_outStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "Too many channels on output device (mChannelsPerFrame = %d)",
- _outStreamFormat.mChannelsPerFrame);
- return -1;
- }
+ if (_outStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "Too many channels on output device (mChannelsPerFrame = %d)",
+ _outStreamFormat.mChannelsPerFrame);
+ return -1;
+ }
- if (_outStreamFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "Non-interleaved audio data is not supported.",
- "AudioHardware streams should not have this format.");
- return -1;
- }
+ if (_outStreamFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "Non-interleaved audio data is not supported.",
+ "AudioHardware streams should not have this format.");
+ return -1;
+ }
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "Ouput stream format:");
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "mSampleRate = %f, mChannelsPerFrame = %u",
+ _outStreamFormat.mSampleRate,
+ _outStreamFormat.mChannelsPerFrame);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "mBytesPerPacket = %u, mFramesPerPacket = %u",
+ _outStreamFormat.mBytesPerPacket,
+ _outStreamFormat.mFramesPerPacket);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "mBytesPerFrame = %u, mBitsPerChannel = %u",
+ _outStreamFormat.mBytesPerFrame,
+ _outStreamFormat.mBitsPerChannel);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "mFormatFlags = %u",
+ _outStreamFormat.mFormatFlags);
+ logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID",
+ (const char*)&_outStreamFormat.mFormatID);
+
+ // Our preferred format to work with.
+ if (_outStreamFormat.mChannelsPerFrame < 2) {
+ // Disable stereo playout when we only have one channel on the device.
+ _playChannels = 1;
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "Ouput stream format:");
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "mSampleRate = %f, mChannelsPerFrame = %u",
- _outStreamFormat.mSampleRate,
- _outStreamFormat.mChannelsPerFrame);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "mBytesPerPacket = %u, mFramesPerPacket = %u",
- _outStreamFormat.mBytesPerPacket,
- _outStreamFormat.mFramesPerPacket);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "mBytesPerFrame = %u, mBitsPerChannel = %u",
- _outStreamFormat.mBytesPerFrame,
- _outStreamFormat.mBitsPerChannel);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "mFormatFlags = %u",
- _outStreamFormat.mFormatFlags);
- logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID",
- (const char *) &_outStreamFormat.mFormatID);
-
- // Our preferred format to work with.
- if (_outStreamFormat.mChannelsPerFrame < 2)
- {
- // Disable stereo playout when we only have one channel on the device.
- _playChannels = 1;
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "Stereo playout unavailable on this device");
- }
- WEBRTC_CA_RETURN_ON_ERR(SetDesiredPlayoutFormat());
+ "Stereo playout unavailable on this device");
+ }
+ WEBRTC_CA_RETURN_ON_ERR(SetDesiredPlayoutFormat());
- // Listen for format changes.
- propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectAddPropertyListener(_outputDeviceID,
- &propertyAddress,
- &objectListenerProc,
- this));
-
- // Listen for processor overloads.
- propertyAddress.mSelector = kAudioDeviceProcessorOverload;
- WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener(_outputDeviceID,
- &propertyAddress,
- &objectListenerProc,
- this));
-
- if (_twoDevices || !_recIsInitialized)
- {
- WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID(_outputDeviceID,
- deviceIOProc,
- this,
- &_deviceIOProcID));
- }
+ // Listen for format changes.
+ propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectAddPropertyListener(
+ _outputDeviceID, &propertyAddress, &objectListenerProc, this));
- _playIsInitialized = true;
+ // Listen for processor overloads.
+ propertyAddress.mSelector = kAudioDeviceProcessorOverload;
+ WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener(
+ _outputDeviceID, &propertyAddress, &objectListenerProc, this));
- return 0;
+ if (_twoDevices || !_recIsInitialized) {
+ WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID(
+ _outputDeviceID, deviceIOProc, this, &_deviceIOProcID));
+ }
+
+ _playIsInitialized = true;
+
+ return 0;
}
-int32_t AudioDeviceMac::InitRecording()
-{
+int32_t AudioDeviceMac::InitRecording() {
+ CriticalSectionScoped lock(&_critSect);
- CriticalSectionScoped lock(&_critSect);
+ if (_recording) {
+ return -1;
+ }
- if (_recording)
- {
- return -1;
- }
+ if (!_inputDeviceIsSpecified) {
+ return -1;
+ }
- if (!_inputDeviceIsSpecified)
- {
- return -1;
- }
+ if (_recIsInitialized) {
+ return 0;
+ }
- if (_recIsInitialized)
- {
- return 0;
- }
+ // Initialize the microphone (devices might have been added or removed)
+ if (InitMicrophone() == -1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " InitMicrophone() failed");
+ }
- // Initialize the microphone (devices might have been added or removed)
- if (InitMicrophone() == -1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " InitMicrophone() failed");
+ if (!SpeakerIsInitialized()) {
+ // Make this call to check if we are using
+ // one or two devices (_twoDevices)
+ bool available = false;
+ if (SpeakerIsAvailable(available) == -1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " SpeakerIsAvailable() failed");
}
+ }
- if (!SpeakerIsInitialized())
- {
- // Make this call to check if we are using
- // one or two devices (_twoDevices)
- bool available = false;
- if (SpeakerIsAvailable(available) == -1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " SpeakerIsAvailable() failed");
- }
- }
+ OSStatus err = noErr;
+ UInt32 size = 0;
- OSStatus err = noErr;
- UInt32 size = 0;
-
- PaUtil_FlushRingBuffer(_paCaptureBuffer);
-
- _captureDelayUs = 0;
- _captureLatencyUs = 0;
- _captureDeviceIsAlive = 1;
- _doStopRec = false;
-
- // Get current stream description
- AudioObjectPropertyAddress
- propertyAddress = { kAudioDevicePropertyStreamFormat,
- kAudioDevicePropertyScopeInput, 0 };
- memset(&_inStreamFormat, 0, sizeof(_inStreamFormat));
- size = sizeof(_inStreamFormat);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &_inStreamFormat));
-
- if (_inStreamFormat.mFormatID != kAudioFormatLinearPCM)
- {
- logCAMsg(kTraceError, kTraceAudioDevice, _id,
- "Unacceptable input stream format -> mFormatID",
- (const char *) &_inStreamFormat.mFormatID);
- return -1;
- }
+ PaUtil_FlushRingBuffer(_paCaptureBuffer);
- if (_inStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "Too many channels on input device (mChannelsPerFrame = %d)",
- _inStreamFormat.mChannelsPerFrame);
- return -1;
- }
+ _captureDelayUs = 0;
+ _captureLatencyUs = 0;
+ _captureDeviceIsAlive = 1;
+ _doStopRec = false;
- const int io_block_size_samples = _inStreamFormat.mChannelsPerFrame *
- _inStreamFormat.mSampleRate / 100 * N_BLOCKS_IO;
- if (io_block_size_samples > _captureBufSizeSamples)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "Input IO block size (%d) is larger than ring buffer (%u)",
- io_block_size_samples, _captureBufSizeSamples);
- return -1;
- }
+ // Get current stream description
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeInput, 0};
+ memset(&_inStreamFormat, 0, sizeof(_inStreamFormat));
+ size = sizeof(_inStreamFormat);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &_inStreamFormat));
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " Input stream format:");
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " mSampleRate = %f, mChannelsPerFrame = %u",
- _inStreamFormat.mSampleRate, _inStreamFormat.mChannelsPerFrame);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " mBytesPerPacket = %u, mFramesPerPacket = %u",
- _inStreamFormat.mBytesPerPacket,
- _inStreamFormat.mFramesPerPacket);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " mBytesPerFrame = %u, mBitsPerChannel = %u",
- _inStreamFormat.mBytesPerFrame,
- _inStreamFormat.mBitsPerChannel);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " mFormatFlags = %u",
- _inStreamFormat.mFormatFlags);
- logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID",
- (const char *) &_inStreamFormat.mFormatID);
+ if (_inStreamFormat.mFormatID != kAudioFormatLinearPCM) {
+ logCAMsg(kTraceError, kTraceAudioDevice, _id,
+ "Unacceptable input stream format -> mFormatID",
+ (const char*)&_inStreamFormat.mFormatID);
+ return -1;
+ }
- // Our preferred format to work with
- if (_inStreamFormat.mChannelsPerFrame >= 2 && (_recChannels == 2))
- {
- _inDesiredFormat.mChannelsPerFrame = 2;
- } else
- {
- // Disable stereo recording when we only have one channel on the device.
- _inDesiredFormat.mChannelsPerFrame = 1;
- _recChannels = 1;
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "Stereo recording unavailable on this device");
- }
+ if (_inStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "Too many channels on input device (mChannelsPerFrame = %d)",
+ _inStreamFormat.mChannelsPerFrame);
+ return -1;
+ }
- if (_ptrAudioBuffer)
- {
- // Update audio buffer with the selected parameters
- _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC);
- _ptrAudioBuffer->SetRecordingChannels((uint8_t) _recChannels);
- }
+ const int io_block_size_samples = _inStreamFormat.mChannelsPerFrame *
+ _inStreamFormat.mSampleRate / 100 *
+ N_BLOCKS_IO;
+ if (io_block_size_samples > _captureBufSizeSamples) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "Input IO block size (%d) is larger than ring buffer (%u)",
+ io_block_size_samples, _captureBufSizeSamples);
+ return -1;
+ }
+
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Input stream format:");
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " mSampleRate = %f, mChannelsPerFrame = %u",
+ _inStreamFormat.mSampleRate, _inStreamFormat.mChannelsPerFrame);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " mBytesPerPacket = %u, mFramesPerPacket = %u",
+ _inStreamFormat.mBytesPerPacket,
+ _inStreamFormat.mFramesPerPacket);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " mBytesPerFrame = %u, mBitsPerChannel = %u",
+ _inStreamFormat.mBytesPerFrame, _inStreamFormat.mBitsPerChannel);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " mFormatFlags = %u",
+ _inStreamFormat.mFormatFlags);
+ logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID",
+ (const char*)&_inStreamFormat.mFormatID);
+
+ // Our preferred format to work with
+ if (_inStreamFormat.mChannelsPerFrame >= 2 && (_recChannels == 2)) {
+ _inDesiredFormat.mChannelsPerFrame = 2;
+ } else {
+ // Disable stereo recording when we only have one channel on the device.
+ _inDesiredFormat.mChannelsPerFrame = 1;
+ _recChannels = 1;
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "Stereo recording unavailable on this device");
+ }
+
+ if (_ptrAudioBuffer) {
+ // Update audio buffer with the selected parameters
+ _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC);
+ _ptrAudioBuffer->SetRecordingChannels((uint8_t)_recChannels);
+ }
- _inDesiredFormat.mSampleRate = N_REC_SAMPLES_PER_SEC;
- _inDesiredFormat.mBytesPerPacket = _inDesiredFormat.mChannelsPerFrame
- * sizeof(SInt16);
- _inDesiredFormat.mFramesPerPacket = 1;
- _inDesiredFormat.mBytesPerFrame = _inDesiredFormat.mChannelsPerFrame
- * sizeof(SInt16);
- _inDesiredFormat.mBitsPerChannel = sizeof(SInt16) * 8;
+ _inDesiredFormat.mSampleRate = N_REC_SAMPLES_PER_SEC;
+ _inDesiredFormat.mBytesPerPacket =
+ _inDesiredFormat.mChannelsPerFrame * sizeof(SInt16);
+ _inDesiredFormat.mFramesPerPacket = 1;
+ _inDesiredFormat.mBytesPerFrame =
+ _inDesiredFormat.mChannelsPerFrame * sizeof(SInt16);
+ _inDesiredFormat.mBitsPerChannel = sizeof(SInt16) * 8;
- _inDesiredFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
- | kLinearPCMFormatFlagIsPacked;
+ _inDesiredFormat.mFormatFlags =
+ kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
#ifdef WEBRTC_ARCH_BIG_ENDIAN
- _inDesiredFormat.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
+ _inDesiredFormat.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
#endif
- _inDesiredFormat.mFormatID = kAudioFormatLinearPCM;
-
- WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(&_inStreamFormat, &_inDesiredFormat,
- &_captureConverter));
-
- // First try to set buffer size to desired value (10 ms * N_BLOCKS_IO)
- // TODO(xians): investigate this block.
- UInt32 bufByteCount = (UInt32)((_inStreamFormat.mSampleRate / 1000.0)
- * 10.0 * N_BLOCKS_IO * _inStreamFormat.mChannelsPerFrame
- * sizeof(Float32));
- if (_inStreamFormat.mFramesPerPacket != 0)
- {
- if (bufByteCount % _inStreamFormat.mFramesPerPacket != 0)
- {
- bufByteCount = ((UInt32)(bufByteCount
- / _inStreamFormat.mFramesPerPacket) + 1)
- * _inStreamFormat.mFramesPerPacket;
- }
+ _inDesiredFormat.mFormatID = kAudioFormatLinearPCM;
+
+ WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(&_inStreamFormat, &_inDesiredFormat,
+ &_captureConverter));
+
+ // First try to set buffer size to desired value (10 ms * N_BLOCKS_IO)
+ // TODO(xians): investigate this block.
+ UInt32 bufByteCount =
+ (UInt32)((_inStreamFormat.mSampleRate / 1000.0) * 10.0 * N_BLOCKS_IO *
+ _inStreamFormat.mChannelsPerFrame * sizeof(Float32));
+ if (_inStreamFormat.mFramesPerPacket != 0) {
+ if (bufByteCount % _inStreamFormat.mFramesPerPacket != 0) {
+ bufByteCount =
+ ((UInt32)(bufByteCount / _inStreamFormat.mFramesPerPacket) + 1) *
+ _inStreamFormat.mFramesPerPacket;
}
+ }
- // Ensure the buffer size is within the acceptable range provided by the device.
- propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange;
- AudioValueRange range;
- size = sizeof(range);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &range));
- if (range.mMinimum > bufByteCount)
- {
- bufByteCount = range.mMinimum;
- } else if (range.mMaximum < bufByteCount)
- {
- bufByteCount = range.mMaximum;
- }
+ // Ensure the buffer size is within the acceptable range provided by the
+ // device.
+ propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange;
+ AudioValueRange range;
+ size = sizeof(range);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &range));
+ if (range.mMinimum > bufByteCount) {
+ bufByteCount = range.mMinimum;
+ } else if (range.mMaximum < bufByteCount) {
+ bufByteCount = range.mMaximum;
+ }
- propertyAddress.mSelector = kAudioDevicePropertyBufferSize;
- size = sizeof(bufByteCount);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, size, &bufByteCount));
-
- // Get capture device latency
- propertyAddress.mSelector = kAudioDevicePropertyLatency;
- UInt32 latency = 0;
- size = sizeof(UInt32);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &latency));
- _captureLatencyUs = (UInt32)((1.0e6 * latency)
- / _inStreamFormat.mSampleRate);
-
- // Get capture stream latency
- propertyAddress.mSelector = kAudioDevicePropertyStreams;
- AudioStreamID stream = 0;
- size = sizeof(AudioStreamID);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &stream));
- propertyAddress.mSelector = kAudioStreamPropertyLatency;
- size = sizeof(UInt32);
- latency = 0;
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_inputDeviceID,
- &propertyAddress, 0, NULL, &size, &latency));
- _captureLatencyUs += (UInt32)((1.0e6 * latency)
- / _inStreamFormat.mSampleRate);
-
- // Listen for format changes
- // TODO(xians): should we be using kAudioDevicePropertyDeviceHasChanged?
- propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectAddPropertyListener(_inputDeviceID,
- &propertyAddress, &objectListenerProc, this));
-
- // Listen for processor overloads
- propertyAddress.mSelector = kAudioDeviceProcessorOverload;
- WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener(_inputDeviceID,
- &propertyAddress, &objectListenerProc, this));
-
- if (_twoDevices)
- {
- WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID(_inputDeviceID,
- inDeviceIOProc, this, &_inDeviceIOProcID));
- } else if (!_playIsInitialized)
- {
- WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID(_inputDeviceID,
- deviceIOProc, this, &_deviceIOProcID));
- }
+ propertyAddress.mSelector = kAudioDevicePropertyBufferSize;
+ size = sizeof(bufByteCount);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, size, &bufByteCount));
+
+ // Get capture device latency
+ propertyAddress.mSelector = kAudioDevicePropertyLatency;
+ UInt32 latency = 0;
+ size = sizeof(UInt32);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &latency));
+ _captureLatencyUs = (UInt32)((1.0e6 * latency) / _inStreamFormat.mSampleRate);
+
+ // Get capture stream latency
+ propertyAddress.mSelector = kAudioDevicePropertyStreams;
+ AudioStreamID stream = 0;
+ size = sizeof(AudioStreamID);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &stream));
+ propertyAddress.mSelector = kAudioStreamPropertyLatency;
+ size = sizeof(UInt32);
+ latency = 0;
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _inputDeviceID, &propertyAddress, 0, NULL, &size, &latency));
+ _captureLatencyUs +=
+ (UInt32)((1.0e6 * latency) / _inStreamFormat.mSampleRate);
+
+ // Listen for format changes
+ // TODO(xians): should we be using kAudioDevicePropertyDeviceHasChanged?
+ propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectAddPropertyListener(
+ _inputDeviceID, &propertyAddress, &objectListenerProc, this));
+
+ // Listen for processor overloads
+ propertyAddress.mSelector = kAudioDeviceProcessorOverload;
+ WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener(
+ _inputDeviceID, &propertyAddress, &objectListenerProc, this));
+
+ if (_twoDevices) {
+ WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID(
+ _inputDeviceID, inDeviceIOProc, this, &_inDeviceIOProcID));
+ } else if (!_playIsInitialized) {
+ WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID(
+ _inputDeviceID, deviceIOProc, this, &_deviceIOProcID));
+ }
- // Mark recording side as initialized
- _recIsInitialized = true;
+ // Mark recording side as initialized
+ _recIsInitialized = true;
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::StartRecording()
-{
-
- CriticalSectionScoped lock(&_critSect);
+int32_t AudioDeviceMac::StartRecording() {
+ CriticalSectionScoped lock(&_critSect);
- if (!_recIsInitialized)
- {
- return -1;
- }
-
- if (_recording)
- {
- return 0;
- }
+ if (!_recIsInitialized) {
+ return -1;
+ }
- if (!_initialized)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " Recording worker thread has not been started");
- return -1;
- }
+ if (_recording) {
+ return 0;
+ }
- RTC_DCHECK(!capture_worker_thread_.get());
- capture_worker_thread_.reset(
- new rtc::PlatformThread(RunCapture, this, "CaptureWorkerThread"));
- RTC_DCHECK(capture_worker_thread_.get());
- capture_worker_thread_->Start();
- capture_worker_thread_->SetPriority(rtc::kRealtimePriority);
+ if (!_initialized) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " Recording worker thread has not been started");
+ return -1;
+ }
- OSStatus err = noErr;
- if (_twoDevices)
- {
- WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _inDeviceIOProcID));
- } else if (!_playing)
- {
- WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _deviceIOProcID));
- }
+ RTC_DCHECK(!capture_worker_thread_.get());
+ capture_worker_thread_.reset(
+ new rtc::PlatformThread(RunCapture, this, "CaptureWorkerThread"));
+ RTC_DCHECK(capture_worker_thread_.get());
+ capture_worker_thread_->Start();
+ capture_worker_thread_->SetPriority(rtc::kRealtimePriority);
+
+ OSStatus err = noErr;
+ if (_twoDevices) {
+ WEBRTC_CA_RETURN_ON_ERR(
+ AudioDeviceStart(_inputDeviceID, _inDeviceIOProcID));
+ } else if (!_playing) {
+ WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _deviceIOProcID));
+ }
- _recording = true;
+ _recording = true;
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::StopRecording()
-{
-
- CriticalSectionScoped lock(&_critSect);
+int32_t AudioDeviceMac::StopRecording() {
+ CriticalSectionScoped lock(&_critSect);
- if (!_recIsInitialized)
- {
- return 0;
- }
-
- OSStatus err = noErr;
+ if (!_recIsInitialized) {
+ return 0;
+ }
- // Stop device
- int32_t captureDeviceIsAlive = AtomicGet32(&_captureDeviceIsAlive);
- if (_twoDevices)
- {
- if (_recording && captureDeviceIsAlive == 1)
- {
- _recording = false;
- _doStopRec = true; // Signal to io proc to stop audio device
- _critSect.Leave(); // Cannot be under lock, risk of deadlock
- if (kEventTimeout == _stopEventRec.Wait(2000))
- {
- CriticalSectionScoped critScoped(&_critSect);
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Timed out stopping the capture IOProc. "
- "We may have failed to detect a device removal.");
-
- WEBRTC_CA_LOG_WARN(AudioDeviceStop(_inputDeviceID,
- _inDeviceIOProcID));
- WEBRTC_CA_LOG_WARN(
- AudioDeviceDestroyIOProcID(_inputDeviceID,
- _inDeviceIOProcID));
- }
- _critSect.Enter();
- _doStopRec = false;
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
- " Recording stopped");
- }
- }
- else
- {
- // We signal a stop for a shared device even when rendering has
- // not yet ended. This is to ensure the IOProc will return early as
- // intended (by checking |_recording|) before accessing
- // resources we free below (e.g. the capture converter).
- //
- // In the case of a shared devcie, the IOProc will verify
- // rendering has ended before stopping itself.
- if (_recording && captureDeviceIsAlive == 1)
- {
- _recording = false;
- _doStop = true; // Signal to io proc to stop audio device
- _critSect.Leave(); // Cannot be under lock, risk of deadlock
- if (kEventTimeout == _stopEvent.Wait(2000))
- {
- CriticalSectionScoped critScoped(&_critSect);
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Timed out stopping the shared IOProc. "
- "We may have failed to detect a device removal.");
-
- // We assume rendering on a shared device has stopped as well if
- // the IOProc times out.
- WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID,
- _deviceIOProcID));
- WEBRTC_CA_LOG_WARN(AudioDeviceDestroyIOProcID(_outputDeviceID,
- _deviceIOProcID));
- }
- _critSect.Enter();
- _doStop = false;
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
- " Recording stopped (shared)");
- }
+ OSStatus err = noErr;
+
+ // Stop device
+ int32_t captureDeviceIsAlive = AtomicGet32(&_captureDeviceIsAlive);
+ if (_twoDevices) {
+ if (_recording && captureDeviceIsAlive == 1) {
+ _recording = false;
+ _doStopRec = true; // Signal to io proc to stop audio device
+ _critSect.Leave(); // Cannot be under lock, risk of deadlock
+ if (kEventTimeout == _stopEventRec.Wait(2000)) {
+ CriticalSectionScoped critScoped(&_critSect);
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Timed out stopping the capture IOProc. "
+ "We may have failed to detect a device removal.");
+
+ WEBRTC_CA_LOG_WARN(AudioDeviceStop(_inputDeviceID, _inDeviceIOProcID));
+ WEBRTC_CA_LOG_WARN(
+ AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID));
+ }
+ _critSect.Enter();
+ _doStopRec = false;
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, " Recording stopped");
+ }
+ } else {
+ // We signal a stop for a shared device even when rendering has
+ // not yet ended. This is to ensure the IOProc will return early as
+ // intended (by checking |_recording|) before accessing
+ // resources we free below (e.g. the capture converter).
+ //
+ // In the case of a shared devcie, the IOProc will verify
+ // rendering has ended before stopping itself.
+ if (_recording && captureDeviceIsAlive == 1) {
+ _recording = false;
+ _doStop = true; // Signal to io proc to stop audio device
+ _critSect.Leave(); // Cannot be under lock, risk of deadlock
+ if (kEventTimeout == _stopEvent.Wait(2000)) {
+ CriticalSectionScoped critScoped(&_critSect);
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Timed out stopping the shared IOProc. "
+ "We may have failed to detect a device removal.");
+
+ // We assume rendering on a shared device has stopped as well if
+ // the IOProc times out.
+ WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID));
+ WEBRTC_CA_LOG_WARN(
+ AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
+ }
+ _critSect.Enter();
+ _doStop = false;
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
+ " Recording stopped (shared)");
}
+ }
- // Setting this signal will allow the worker thread to be stopped.
- AtomicSet32(&_captureDeviceIsAlive, 0);
+ // Setting this signal will allow the worker thread to be stopped.
+ AtomicSet32(&_captureDeviceIsAlive, 0);
- if (capture_worker_thread_.get()) {
- _critSect.Leave();
- capture_worker_thread_->Stop();
- capture_worker_thread_.reset();
- _critSect.Enter();
- }
+ if (capture_worker_thread_.get()) {
+ _critSect.Leave();
+ capture_worker_thread_->Stop();
+ capture_worker_thread_.reset();
+ _critSect.Enter();
+ }
- WEBRTC_CA_LOG_WARN(AudioConverterDispose(_captureConverter));
+ WEBRTC_CA_LOG_WARN(AudioConverterDispose(_captureConverter));
- // Remove listeners.
- AudioObjectPropertyAddress
- propertyAddress = { kAudioDevicePropertyStreamFormat,
- kAudioDevicePropertyScopeInput, 0 };
- WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(_inputDeviceID,
- &propertyAddress, &objectListenerProc, this));
+ // Remove listeners.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeInput, 0};
+ WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(
+ _inputDeviceID, &propertyAddress, &objectListenerProc, this));
- propertyAddress.mSelector = kAudioDeviceProcessorOverload;
- WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(_inputDeviceID,
- &propertyAddress, &objectListenerProc, this));
+ propertyAddress.mSelector = kAudioDeviceProcessorOverload;
+ WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(
+ _inputDeviceID, &propertyAddress, &objectListenerProc, this));
- _recIsInitialized = false;
- _recording = false;
+ _recIsInitialized = false;
+ _recording = false;
- return 0;
+ return 0;
}
-bool AudioDeviceMac::RecordingIsInitialized() const
-{
- return (_recIsInitialized);
+bool AudioDeviceMac::RecordingIsInitialized() const {
+ return (_recIsInitialized);
}
-bool AudioDeviceMac::Recording() const
-{
- return (_recording);
+bool AudioDeviceMac::Recording() const {
+ return (_recording);
}
-bool AudioDeviceMac::PlayoutIsInitialized() const
-{
- return (_playIsInitialized);
+bool AudioDeviceMac::PlayoutIsInitialized() const {
+ return (_playIsInitialized);
}
-int32_t AudioDeviceMac::StartPlayout()
-{
+int32_t AudioDeviceMac::StartPlayout() {
+ CriticalSectionScoped lock(&_critSect);
- CriticalSectionScoped lock(&_critSect);
-
- if (!_playIsInitialized)
- {
- return -1;
- }
+ if (!_playIsInitialized) {
+ return -1;
+ }
- if (_playing)
- {
- return 0;
- }
+ if (_playing) {
+ return 0;
+ }
- RTC_DCHECK(!render_worker_thread_.get());
- render_worker_thread_.reset(
- new rtc::PlatformThread(RunRender, this, "RenderWorkerThread"));
- render_worker_thread_->Start();
- render_worker_thread_->SetPriority(rtc::kRealtimePriority);
+ RTC_DCHECK(!render_worker_thread_.get());
+ render_worker_thread_.reset(
+ new rtc::PlatformThread(RunRender, this, "RenderWorkerThread"));
+ render_worker_thread_->Start();
+ render_worker_thread_->SetPriority(rtc::kRealtimePriority);
- if (_twoDevices || !_recording)
- {
- OSStatus err = noErr;
- WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_outputDeviceID, _deviceIOProcID));
- }
- _playing = true;
+ if (_twoDevices || !_recording) {
+ OSStatus err = noErr;
+ WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_outputDeviceID, _deviceIOProcID));
+ }
+ _playing = true;
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::StopPlayout()
-{
+int32_t AudioDeviceMac::StopPlayout() {
+ CriticalSectionScoped lock(&_critSect);
- CriticalSectionScoped lock(&_critSect);
+ if (!_playIsInitialized) {
+ return 0;
+ }
- if (!_playIsInitialized)
- {
- return 0;
+ OSStatus err = noErr;
+
+ int32_t renderDeviceIsAlive = AtomicGet32(&_renderDeviceIsAlive);
+ if (_playing && renderDeviceIsAlive == 1) {
+ // We signal a stop for a shared device even when capturing has not
+ // yet ended. This is to ensure the IOProc will return early as
+ // intended (by checking |_playing|) before accessing resources we
+ // free below (e.g. the render converter).
+ //
+ // In the case of a shared device, the IOProc will verify capturing
+ // has ended before stopping itself.
+ _playing = false;
+ _doStop = true; // Signal to io proc to stop audio device
+ _critSect.Leave(); // Cannot be under lock, risk of deadlock
+ if (kEventTimeout == _stopEvent.Wait(2000)) {
+ CriticalSectionScoped critScoped(&_critSect);
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " Timed out stopping the render IOProc. "
+ "We may have failed to detect a device removal.");
+
+ // We assume capturing on a shared device has stopped as well if the
+ // IOProc times out.
+ WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID));
+ WEBRTC_CA_LOG_WARN(
+ AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
}
+ _critSect.Enter();
+ _doStop = false;
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, "Playout stopped");
+ }
- OSStatus err = noErr;
+ // Setting this signal will allow the worker thread to be stopped.
+ AtomicSet32(&_renderDeviceIsAlive, 0);
+ if (render_worker_thread_.get()) {
+ _critSect.Leave();
+ render_worker_thread_->Stop();
+ render_worker_thread_.reset();
+ _critSect.Enter();
+ }
- int32_t renderDeviceIsAlive = AtomicGet32(&_renderDeviceIsAlive);
- if (_playing && renderDeviceIsAlive == 1)
- {
- // We signal a stop for a shared device even when capturing has not
- // yet ended. This is to ensure the IOProc will return early as
- // intended (by checking |_playing|) before accessing resources we
- // free below (e.g. the render converter).
- //
- // In the case of a shared device, the IOProc will verify capturing
- // has ended before stopping itself.
- _playing = false;
- _doStop = true; // Signal to io proc to stop audio device
- _critSect.Leave(); // Cannot be under lock, risk of deadlock
- if (kEventTimeout == _stopEvent.Wait(2000))
- {
- CriticalSectionScoped critScoped(&_critSect);
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " Timed out stopping the render IOProc. "
- "We may have failed to detect a device removal.");
-
- // We assume capturing on a shared device has stopped as well if the
- // IOProc times out.
- WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID,
- _deviceIOProcID));
- WEBRTC_CA_LOG_WARN(AudioDeviceDestroyIOProcID(_outputDeviceID,
- _deviceIOProcID));
- }
- _critSect.Enter();
- _doStop = false;
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
- "Playout stopped");
- }
+ WEBRTC_CA_LOG_WARN(AudioConverterDispose(_renderConverter));
- // Setting this signal will allow the worker thread to be stopped.
- AtomicSet32(&_renderDeviceIsAlive, 0);
- if (render_worker_thread_.get()) {
- _critSect.Leave();
- render_worker_thread_->Stop();
- render_worker_thread_.reset();
- _critSect.Enter();
- }
+ // Remove listeners.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, 0};
+ WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(
+ _outputDeviceID, &propertyAddress, &objectListenerProc, this));
- WEBRTC_CA_LOG_WARN(AudioConverterDispose(_renderConverter));
+ propertyAddress.mSelector = kAudioDeviceProcessorOverload;
+ WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(
+ _outputDeviceID, &propertyAddress, &objectListenerProc, this));
- // Remove listeners.
- AudioObjectPropertyAddress propertyAddress = {
- kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput,
- 0 };
- WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(_outputDeviceID,
- &propertyAddress, &objectListenerProc, this));
-
- propertyAddress.mSelector = kAudioDeviceProcessorOverload;
- WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(_outputDeviceID,
- &propertyAddress, &objectListenerProc, this));
-
- if (_macBookPro)
- {
- Boolean hasProperty = AudioObjectHasProperty(_outputDeviceID,
- &propertyAddress);
- if (hasProperty)
- {
- propertyAddress.mSelector = kAudioDevicePropertyDataSource;
- WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(_outputDeviceID,
- &propertyAddress, &objectListenerProc, this));
- }
+ if (_macBookPro) {
+ Boolean hasProperty =
+ AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
+ if (hasProperty) {
+ propertyAddress.mSelector = kAudioDevicePropertyDataSource;
+ WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(
+ _outputDeviceID, &propertyAddress, &objectListenerProc, this));
}
+ }
- _playIsInitialized = false;
- _playing = false;
+ _playIsInitialized = false;
+ _playing = false;
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::PlayoutDelay(uint16_t& delayMS) const
-{
- int32_t renderDelayUs = AtomicGet32(&_renderDelayUs);
- delayMS = static_cast<uint16_t> (1e-3 * (renderDelayUs + _renderLatencyUs) +
- 0.5);
- return 0;
+int32_t AudioDeviceMac::PlayoutDelay(uint16_t& delayMS) const {
+ int32_t renderDelayUs = AtomicGet32(&_renderDelayUs);
+ delayMS =
+ static_cast<uint16_t>(1e-3 * (renderDelayUs + _renderLatencyUs) + 0.5);
+ return 0;
}
-int32_t AudioDeviceMac::RecordingDelay(uint16_t& delayMS) const
-{
- int32_t captureDelayUs = AtomicGet32(&_captureDelayUs);
- delayMS = static_cast<uint16_t> (1e-3 * (captureDelayUs +
- _captureLatencyUs) + 0.5);
- return 0;
+int32_t AudioDeviceMac::RecordingDelay(uint16_t& delayMS) const {
+ int32_t captureDelayUs = AtomicGet32(&_captureDelayUs);
+ delayMS =
+ static_cast<uint16_t>(1e-3 * (captureDelayUs + _captureLatencyUs) + 0.5);
+ return 0;
}
-bool AudioDeviceMac::Playing() const
-{
- return (_playing);
+bool AudioDeviceMac::Playing() const {
+ return (_playing);
}
int32_t AudioDeviceMac::SetPlayoutBuffer(
const AudioDeviceModule::BufferType type,
- uint16_t sizeMS)
-{
-
- if (type != AudioDeviceModule::kFixedBufferSize)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " Adaptive buffer size not supported on this platform");
- return -1;
- }
+ uint16_t sizeMS) {
+ if (type != AudioDeviceModule::kFixedBufferSize) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " Adaptive buffer size not supported on this platform");
+ return -1;
+ }
- _playBufType = type;
- _playBufDelayFixed = sizeMS;
- return 0;
+ _playBufType = type;
+ _playBufDelayFixed = sizeMS;
+ return 0;
}
-int32_t AudioDeviceMac::PlayoutBuffer(
- AudioDeviceModule::BufferType& type,
- uint16_t& sizeMS) const
-{
-
- type = _playBufType;
- sizeMS = _playBufDelayFixed;
+int32_t AudioDeviceMac::PlayoutBuffer(AudioDeviceModule::BufferType& type,
+ uint16_t& sizeMS) const {
+ type = _playBufType;
+ sizeMS = _playBufDelayFixed;
- return 0;
+ return 0;
}
// Not implemented for Mac.
-int32_t AudioDeviceMac::CPULoad(uint16_t& /*load*/) const
-{
-
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " API call not supported on this platform");
+int32_t AudioDeviceMac::CPULoad(uint16_t& /*load*/) const {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " API call not supported on this platform");
- return -1;
+ return -1;
}
-bool AudioDeviceMac::PlayoutWarning() const
-{
- return (_playWarning > 0);
+bool AudioDeviceMac::PlayoutWarning() const {
+ return (_playWarning > 0);
}
-bool AudioDeviceMac::PlayoutError() const
-{
- return (_playError > 0);
+bool AudioDeviceMac::PlayoutError() const {
+ return (_playError > 0);
}
-bool AudioDeviceMac::RecordingWarning() const
-{
- return (_recWarning > 0);
+bool AudioDeviceMac::RecordingWarning() const {
+ return (_recWarning > 0);
}
-bool AudioDeviceMac::RecordingError() const
-{
- return (_recError > 0);
+bool AudioDeviceMac::RecordingError() const {
+ return (_recError > 0);
}
-void AudioDeviceMac::ClearPlayoutWarning()
-{
- _playWarning = 0;
+void AudioDeviceMac::ClearPlayoutWarning() {
+ _playWarning = 0;
}
-void AudioDeviceMac::ClearPlayoutError()
-{
- _playError = 0;
+void AudioDeviceMac::ClearPlayoutError() {
+ _playError = 0;
}
-void AudioDeviceMac::ClearRecordingWarning()
-{
- _recWarning = 0;
+void AudioDeviceMac::ClearRecordingWarning() {
+ _recWarning = 0;
}
-void AudioDeviceMac::ClearRecordingError()
-{
- _recError = 0;
+void AudioDeviceMac::ClearRecordingError() {
+ _recError = 0;
}
// ============================================================================
// Private Methods
// ============================================================================
-int32_t
-AudioDeviceMac::GetNumberDevices(const AudioObjectPropertyScope scope,
- AudioDeviceID scopedDeviceIds[],
- const uint32_t deviceListLength)
-{
- OSStatus err = noErr;
-
- AudioObjectPropertyAddress propertyAddress = {
- kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
- UInt32 size = 0;
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
- &propertyAddress, 0, NULL, &size));
- if (size == 0)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- "No devices");
- return 0;
- }
-
- AudioDeviceID* deviceIds = (AudioDeviceID*) malloc(size);
- UInt32 numberDevices = size / sizeof(AudioDeviceID);
- AudioBufferList* bufferList = NULL;
- UInt32 numberScopedDevices = 0;
+int32_t AudioDeviceMac::GetNumberDevices(const AudioObjectPropertyScope scope,
+ AudioDeviceID scopedDeviceIds[],
+ const uint32_t deviceListLength) {
+ OSStatus err = noErr;
+
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster};
+ UInt32 size = 0;
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyDataSize(
+ kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size));
+ if (size == 0) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "No devices");
+ return 0;
+ }
- // First check if there is a default device and list it
- UInt32 hardwareProperty = 0;
- if (scope == kAudioDevicePropertyScopeOutput)
- {
- hardwareProperty = kAudioHardwarePropertyDefaultOutputDevice;
- } else
- {
- hardwareProperty = kAudioHardwarePropertyDefaultInputDevice;
- }
+ AudioDeviceID* deviceIds = (AudioDeviceID*)malloc(size);
+ UInt32 numberDevices = size / sizeof(AudioDeviceID);
+ AudioBufferList* bufferList = NULL;
+ UInt32 numberScopedDevices = 0;
+
+ // First check if there is a default device and list it
+ UInt32 hardwareProperty = 0;
+ if (scope == kAudioDevicePropertyScopeOutput) {
+ hardwareProperty = kAudioHardwarePropertyDefaultOutputDevice;
+ } else {
+ hardwareProperty = kAudioHardwarePropertyDefaultInputDevice;
+ }
- AudioObjectPropertyAddress
- propertyAddressDefault = { hardwareProperty,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
-
- AudioDeviceID usedID;
- UInt32 uintSize = sizeof(UInt32);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(kAudioObjectSystemObject,
- &propertyAddressDefault, 0, NULL, &uintSize, &usedID));
- if (usedID != kAudioDeviceUnknown)
- {
- scopedDeviceIds[numberScopedDevices] = usedID;
- numberScopedDevices++;
- } else
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- "GetNumberDevices(): Default device unknown");
- }
+ AudioObjectPropertyAddress propertyAddressDefault = {
+ hardwareProperty, kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster};
+
+ AudioDeviceID usedID;
+ UInt32 uintSize = sizeof(UInt32);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(kAudioObjectSystemObject,
+ &propertyAddressDefault, 0,
+ NULL, &uintSize, &usedID));
+ if (usedID != kAudioDeviceUnknown) {
+ scopedDeviceIds[numberScopedDevices] = usedID;
+ numberScopedDevices++;
+ } else {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ "GetNumberDevices(): Default device unknown");
+ }
- // Then list the rest of the devices
- bool listOK = true;
+ // Then list the rest of the devices
+ bool listOK = true;
- WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyData(kAudioObjectSystemObject,
- &propertyAddress, 0, NULL, &size, deviceIds));
- if (err != noErr)
- {
+ WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyData(
+ kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, deviceIds));
+ if (err != noErr) {
+ listOK = false;
+ } else {
+ propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration;
+ propertyAddress.mScope = scope;
+ propertyAddress.mElement = 0;
+ for (UInt32 i = 0; i < numberDevices; i++) {
+ // Check for input channels
+ WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyDataSize(
+ deviceIds[i], &propertyAddress, 0, NULL, &size));
+ if (err == kAudioHardwareBadDeviceError) {
+ // This device doesn't actually exist; continue iterating.
+ continue;
+ } else if (err != noErr) {
listOK = false;
- } else
- {
- propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration;
- propertyAddress.mScope = scope;
- propertyAddress.mElement = 0;
- for (UInt32 i = 0; i < numberDevices; i++)
- {
- // Check for input channels
- WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyDataSize(deviceIds[i],
- &propertyAddress, 0, NULL, &size));
- if (err == kAudioHardwareBadDeviceError)
- {
- // This device doesn't actually exist; continue iterating.
- continue;
- } else if (err != noErr)
- {
- listOK = false;
- break;
- }
-
- bufferList = (AudioBufferList*) malloc(size);
- WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyData(deviceIds[i],
- &propertyAddress, 0, NULL, &size, bufferList));
- if (err != noErr)
- {
- listOK = false;
- break;
- }
-
- if (bufferList->mNumberBuffers > 0)
- {
- if (numberScopedDevices >= deviceListLength)
- {
- WEBRTC_TRACE(kTraceError,
- kTraceAudioDevice, _id,
- "Device list is not long enough");
- listOK = false;
- break;
- }
-
- scopedDeviceIds[numberScopedDevices] = deviceIds[i];
- numberScopedDevices++;
- }
-
- free(bufferList);
- bufferList = NULL;
- } // for
- }
+ break;
+ }
- if (!listOK)
- {
- if (deviceIds)
- {
- free(deviceIds);
- deviceIds = NULL;
+ bufferList = (AudioBufferList*)malloc(size);
+ WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyData(
+ deviceIds[i], &propertyAddress, 0, NULL, &size, bufferList));
+ if (err != noErr) {
+ listOK = false;
+ break;
+ }
+
+ if (bufferList->mNumberBuffers > 0) {
+ if (numberScopedDevices >= deviceListLength) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "Device list is not long enough");
+ listOK = false;
+ break;
}
- if (bufferList)
- {
- free(bufferList);
- bufferList = NULL;
- }
+ scopedDeviceIds[numberScopedDevices] = deviceIds[i];
+ numberScopedDevices++;
+ }
- return -1;
+ free(bufferList);
+ bufferList = NULL;
+ } // for
+ }
+
+ if (!listOK) {
+ if (deviceIds) {
+ free(deviceIds);
+ deviceIds = NULL;
}
- // Happy ending
- if (deviceIds)
- {
- free(deviceIds);
- deviceIds = NULL;
+ if (bufferList) {
+ free(bufferList);
+ bufferList = NULL;
}
- return numberScopedDevices;
+ return -1;
+ }
+
+ // Happy ending
+ if (deviceIds) {
+ free(deviceIds);
+ deviceIds = NULL;
+ }
+
+ return numberScopedDevices;
}
-int32_t
-AudioDeviceMac::GetDeviceName(const AudioObjectPropertyScope scope,
- const uint16_t index,
- char* name)
-{
- OSStatus err = noErr;
- UInt32 len = kAdmMaxDeviceNameSize;
- AudioDeviceID deviceIds[MaxNumberDevices];
-
- int numberDevices = GetNumberDevices(scope, deviceIds, MaxNumberDevices);
- if (numberDevices < 0)
- {
- return -1;
- } else if (numberDevices == 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "No devices");
- return -1;
- }
+int32_t AudioDeviceMac::GetDeviceName(const AudioObjectPropertyScope scope,
+ const uint16_t index,
+ char* name) {
+ OSStatus err = noErr;
+ UInt32 len = kAdmMaxDeviceNameSize;
+ AudioDeviceID deviceIds[MaxNumberDevices];
- // If the number is below the number of devices, assume it's "WEBRTC ID"
- // otherwise assume it's a CoreAudio ID
- AudioDeviceID usedID;
-
- // Check if there is a default device
- bool isDefaultDevice = false;
- if (index == 0)
- {
- UInt32 hardwareProperty = 0;
- if (scope == kAudioDevicePropertyScopeOutput)
- {
- hardwareProperty = kAudioHardwarePropertyDefaultOutputDevice;
- } else
- {
- hardwareProperty = kAudioHardwarePropertyDefaultInputDevice;
- }
- AudioObjectPropertyAddress propertyAddress = { hardwareProperty,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
- UInt32 size = sizeof(UInt32);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(kAudioObjectSystemObject,
- &propertyAddress, 0, NULL, &size, &usedID));
- if (usedID == kAudioDeviceUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- "GetDeviceName(): Default device unknown");
- } else
- {
- isDefaultDevice = true;
- }
- }
+ int numberDevices = GetNumberDevices(scope, deviceIds, MaxNumberDevices);
+ if (numberDevices < 0) {
+ return -1;
+ } else if (numberDevices == 0) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, "No devices");
+ return -1;
+ }
+
+ // If the number is below the number of devices, assume it's "WEBRTC ID"
+ // otherwise assume it's a CoreAudio ID
+ AudioDeviceID usedID;
+ // Check if there is a default device
+ bool isDefaultDevice = false;
+ if (index == 0) {
+ UInt32 hardwareProperty = 0;
+ if (scope == kAudioDevicePropertyScopeOutput) {
+ hardwareProperty = kAudioHardwarePropertyDefaultOutputDevice;
+ } else {
+ hardwareProperty = kAudioHardwarePropertyDefaultInputDevice;
+ }
AudioObjectPropertyAddress propertyAddress = {
- kAudioDevicePropertyDeviceName, scope, 0 };
-
- if (isDefaultDevice)
- {
- char devName[len];
-
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(usedID,
- &propertyAddress, 0, NULL, &len, devName));
-
- sprintf(name, "default (%s)", devName);
- } else
- {
- if (index < numberDevices)
- {
- usedID = deviceIds[index];
- } else
- {
- usedID = index;
- }
+ hardwareProperty, kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster};
+ UInt32 size = sizeof(UInt32);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &usedID));
+ if (usedID == kAudioDeviceUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ "GetDeviceName(): Default device unknown");
+ } else {
+ isDefaultDevice = true;
+ }
+ }
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(usedID,
- &propertyAddress, 0, NULL, &len, name));
+ AudioObjectPropertyAddress propertyAddress = {kAudioDevicePropertyDeviceName,
+ scope, 0};
+
+ if (isDefaultDevice) {
+ char devName[len];
+
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(usedID, &propertyAddress,
+ 0, NULL, &len, devName));
+
+ sprintf(name, "default (%s)", devName);
+ } else {
+ if (index < numberDevices) {
+ usedID = deviceIds[index];
+ } else {
+ usedID = index;
}
- return 0;
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(usedID, &propertyAddress,
+ 0, NULL, &len, name));
+ }
+
+ return 0;
}
int32_t AudioDeviceMac::InitDevice(const uint16_t userDeviceIndex,
AudioDeviceID& deviceId,
- const bool isInput)
-{
- OSStatus err = noErr;
- UInt32 size = 0;
- AudioObjectPropertyScope deviceScope;
- AudioObjectPropertySelector defaultDeviceSelector;
- AudioDeviceID deviceIds[MaxNumberDevices];
-
- if (isInput)
- {
- deviceScope = kAudioDevicePropertyScopeInput;
- defaultDeviceSelector = kAudioHardwarePropertyDefaultInputDevice;
- } else
- {
- deviceScope = kAudioDevicePropertyScopeOutput;
- defaultDeviceSelector = kAudioHardwarePropertyDefaultOutputDevice;
- }
+ const bool isInput) {
+ OSStatus err = noErr;
+ UInt32 size = 0;
+ AudioObjectPropertyScope deviceScope;
+ AudioObjectPropertySelector defaultDeviceSelector;
+ AudioDeviceID deviceIds[MaxNumberDevices];
+
+ if (isInput) {
+ deviceScope = kAudioDevicePropertyScopeInput;
+ defaultDeviceSelector = kAudioHardwarePropertyDefaultInputDevice;
+ } else {
+ deviceScope = kAudioDevicePropertyScopeOutput;
+ defaultDeviceSelector = kAudioHardwarePropertyDefaultOutputDevice;
+ }
- AudioObjectPropertyAddress
- propertyAddress = { defaultDeviceSelector,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
-
- // Get the actual device IDs
- int numberDevices = GetNumberDevices(deviceScope, deviceIds,
- MaxNumberDevices);
- if (numberDevices < 0)
- {
- return -1;
- } else if (numberDevices == 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "InitDevice(): No devices");
- return -1;
- }
+ AudioObjectPropertyAddress propertyAddress = {
+ defaultDeviceSelector, kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster};
- bool isDefaultDevice = false;
- deviceId = kAudioDeviceUnknown;
- if (userDeviceIndex == 0)
- {
- // Try to use default system device
- size = sizeof(AudioDeviceID);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(kAudioObjectSystemObject,
- &propertyAddress, 0, NULL, &size, &deviceId));
- if (deviceId == kAudioDeviceUnknown)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " No default device exists");
- } else
- {
- isDefaultDevice = true;
- }
- }
+ // Get the actual device IDs
+ int numberDevices =
+ GetNumberDevices(deviceScope, deviceIds, MaxNumberDevices);
+ if (numberDevices < 0) {
+ return -1;
+ } else if (numberDevices == 0) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "InitDevice(): No devices");
+ return -1;
+ }
- if (!isDefaultDevice)
- {
- deviceId = deviceIds[userDeviceIndex];
+ bool isDefaultDevice = false;
+ deviceId = kAudioDeviceUnknown;
+ if (userDeviceIndex == 0) {
+ // Try to use default system device
+ size = sizeof(AudioDeviceID);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &deviceId));
+ if (deviceId == kAudioDeviceUnknown) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " No default device exists");
+ } else {
+ isDefaultDevice = true;
}
+ }
- // Obtain device name and manufacturer for logging.
- // Also use this as a test to ensure a user-set device ID is valid.
- char devName[128];
- char devManf[128];
- memset(devName, 0, sizeof(devName));
- memset(devManf, 0, sizeof(devManf));
-
- propertyAddress.mSelector = kAudioDevicePropertyDeviceName;
- propertyAddress.mScope = deviceScope;
- propertyAddress.mElement = 0;
- size = sizeof(devName);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId,
- &propertyAddress, 0, NULL, &size, devName));
-
- propertyAddress.mSelector = kAudioDevicePropertyDeviceManufacturer;
- size = sizeof(devManf);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId,
- &propertyAddress, 0, NULL, &size, devManf));
+ if (!isDefaultDevice) {
+ deviceId = deviceIds[userDeviceIndex];
+ }
- if (isInput)
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " Input device: %s %s", devManf, devName);
- } else
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " Output device: %s %s", devManf, devName);
- }
+ // Obtain device name and manufacturer for logging.
+ // Also use this as a test to ensure a user-set device ID is valid.
+ char devName[128];
+ char devManf[128];
+ memset(devName, 0, sizeof(devName));
+ memset(devManf, 0, sizeof(devManf));
+
+ propertyAddress.mSelector = kAudioDevicePropertyDeviceName;
+ propertyAddress.mScope = deviceScope;
+ propertyAddress.mElement = 0;
+ size = sizeof(devName);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId, &propertyAddress,
+ 0, NULL, &size, devName));
+
+ propertyAddress.mSelector = kAudioDevicePropertyDeviceManufacturer;
+ size = sizeof(devManf);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId, &propertyAddress,
+ 0, NULL, &size, devManf));
+
+ if (isInput) {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Input device: %s %s",
+ devManf, devName);
+ } else {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Output device: %s %s",
+ devManf, devName);
+ }
- return 0;
+ return 0;
}
-OSStatus AudioDeviceMac::SetDesiredPlayoutFormat()
-{
- // Our preferred format to work with.
- _outDesiredFormat.mSampleRate = N_PLAY_SAMPLES_PER_SEC;
- _outDesiredFormat.mChannelsPerFrame = _playChannels;
+OSStatus AudioDeviceMac::SetDesiredPlayoutFormat() {
+ // Our preferred format to work with.
+ _outDesiredFormat.mSampleRate = N_PLAY_SAMPLES_PER_SEC;
+ _outDesiredFormat.mChannelsPerFrame = _playChannels;
- if (_ptrAudioBuffer)
- {
- // Update audio buffer with the selected parameters.
- _ptrAudioBuffer->SetPlayoutSampleRate(N_PLAY_SAMPLES_PER_SEC);
- _ptrAudioBuffer->SetPlayoutChannels((uint8_t) _playChannels);
- }
+ if (_ptrAudioBuffer) {
+ // Update audio buffer with the selected parameters.
+ _ptrAudioBuffer->SetPlayoutSampleRate(N_PLAY_SAMPLES_PER_SEC);
+ _ptrAudioBuffer->SetPlayoutChannels((uint8_t)_playChannels);
+ }
- _renderDelayOffsetSamples = _renderBufSizeSamples - N_BUFFERS_OUT *
- ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * _outDesiredFormat.mChannelsPerFrame;
+ _renderDelayOffsetSamples = _renderBufSizeSamples -
+ N_BUFFERS_OUT * ENGINE_PLAY_BUF_SIZE_IN_SAMPLES *
+ _outDesiredFormat.mChannelsPerFrame;
- _outDesiredFormat.mBytesPerPacket = _outDesiredFormat.mChannelsPerFrame *
- sizeof(SInt16);
- // In uncompressed audio, a packet is one frame.
- _outDesiredFormat.mFramesPerPacket = 1;
- _outDesiredFormat.mBytesPerFrame = _outDesiredFormat.mChannelsPerFrame *
- sizeof(SInt16);
- _outDesiredFormat.mBitsPerChannel = sizeof(SInt16) * 8;
+ _outDesiredFormat.mBytesPerPacket =
+ _outDesiredFormat.mChannelsPerFrame * sizeof(SInt16);
+ // In uncompressed audio, a packet is one frame.
+ _outDesiredFormat.mFramesPerPacket = 1;
+ _outDesiredFormat.mBytesPerFrame =
+ _outDesiredFormat.mChannelsPerFrame * sizeof(SInt16);
+ _outDesiredFormat.mBitsPerChannel = sizeof(SInt16) * 8;
- _outDesiredFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger |
- kLinearPCMFormatFlagIsPacked;
+ _outDesiredFormat.mFormatFlags =
+ kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
#ifdef WEBRTC_ARCH_BIG_ENDIAN
- _outDesiredFormat.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
+ _outDesiredFormat.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
#endif
- _outDesiredFormat.mFormatID = kAudioFormatLinearPCM;
-
- OSStatus err = noErr;
- WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(&_outDesiredFormat,
- &_outStreamFormat,
- &_renderConverter));
-
- // Try to set buffer size to desired value (_playBufDelayFixed).
- UInt32 bufByteCount = static_cast<UInt32> ((_outStreamFormat.mSampleRate /
- 1000.0) *
- _playBufDelayFixed *
- _outStreamFormat.mChannelsPerFrame *
- sizeof(Float32));
- if (_outStreamFormat.mFramesPerPacket != 0)
- {
- if (bufByteCount % _outStreamFormat.mFramesPerPacket != 0)
- {
- bufByteCount = (static_cast<UInt32> (bufByteCount /
- _outStreamFormat.mFramesPerPacket) + 1) *
- _outStreamFormat.mFramesPerPacket;
- }
- }
-
- // Ensure the buffer size is within the range provided by the device.
- AudioObjectPropertyAddress propertyAddress =
- {kAudioDevicePropertyDataSource,
- kAudioDevicePropertyScopeOutput,
- 0};
- propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange;
- AudioValueRange range;
- UInt32 size = sizeof(range);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress,
- 0,
- NULL,
- &size,
- &range));
- if (range.mMinimum > bufByteCount)
- {
- bufByteCount = range.mMinimum;
- } else if (range.mMaximum < bufByteCount)
- {
- bufByteCount = range.mMaximum;
+ _outDesiredFormat.mFormatID = kAudioFormatLinearPCM;
+
+ OSStatus err = noErr;
+ WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(
+ &_outDesiredFormat, &_outStreamFormat, &_renderConverter));
+
+ // Try to set buffer size to desired value (_playBufDelayFixed).
+ UInt32 bufByteCount = static_cast<UInt32>(
+ (_outStreamFormat.mSampleRate / 1000.0) * _playBufDelayFixed *
+ _outStreamFormat.mChannelsPerFrame * sizeof(Float32));
+ if (_outStreamFormat.mFramesPerPacket != 0) {
+ if (bufByteCount % _outStreamFormat.mFramesPerPacket != 0) {
+ bufByteCount = (static_cast<UInt32>(bufByteCount /
+ _outStreamFormat.mFramesPerPacket) +
+ 1) *
+ _outStreamFormat.mFramesPerPacket;
}
+ }
- propertyAddress.mSelector = kAudioDevicePropertyBufferSize;
- size = sizeof(bufByteCount);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_outputDeviceID,
- &propertyAddress,
- 0,
- NULL,
- size,
- &bufByteCount));
-
- // Get render device latency.
- propertyAddress.mSelector = kAudioDevicePropertyLatency;
- UInt32 latency = 0;
- size = sizeof(UInt32);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress,
- 0,
- NULL,
- &size,
- &latency));
- _renderLatencyUs = static_cast<uint32_t> ((1.0e6 * latency) /
- _outStreamFormat.mSampleRate);
-
- // Get render stream latency.
- propertyAddress.mSelector = kAudioDevicePropertyStreams;
- AudioStreamID stream = 0;
- size = sizeof(AudioStreamID);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress,
- 0,
- NULL,
- &size,
- &stream));
- propertyAddress.mSelector = kAudioStreamPropertyLatency;
- size = sizeof(UInt32);
- latency = 0;
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
- &propertyAddress,
- 0,
- NULL,
- &size,
- &latency));
- _renderLatencyUs += static_cast<uint32_t> ((1.0e6 * latency) /
- _outStreamFormat.mSampleRate);
+ // Ensure the buffer size is within the range provided by the device.
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyDataSource, kAudioDevicePropertyScopeOutput, 0};
+ propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange;
+ AudioValueRange range;
+ UInt32 size = sizeof(range);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &range));
+ if (range.mMinimum > bufByteCount) {
+ bufByteCount = range.mMinimum;
+ } else if (range.mMaximum < bufByteCount) {
+ bufByteCount = range.mMaximum;
+ }
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- " initial playout status: _renderDelayOffsetSamples=%d,"
- " _renderDelayUs=%d, _renderLatencyUs=%d",
- _renderDelayOffsetSamples, _renderDelayUs, _renderLatencyUs);
- return 0;
+ propertyAddress.mSelector = kAudioDevicePropertyBufferSize;
+ size = sizeof(bufByteCount);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, size, &bufByteCount));
+
+ // Get render device latency.
+ propertyAddress.mSelector = kAudioDevicePropertyLatency;
+ UInt32 latency = 0;
+ size = sizeof(UInt32);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &latency));
+ _renderLatencyUs =
+ static_cast<uint32_t>((1.0e6 * latency) / _outStreamFormat.mSampleRate);
+
+ // Get render stream latency.
+ propertyAddress.mSelector = kAudioDevicePropertyStreams;
+ AudioStreamID stream = 0;
+ size = sizeof(AudioStreamID);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &stream));
+ propertyAddress.mSelector = kAudioStreamPropertyLatency;
+ size = sizeof(UInt32);
+ latency = 0;
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ _outputDeviceID, &propertyAddress, 0, NULL, &size, &latency));
+ _renderLatencyUs +=
+ static_cast<uint32_t>((1.0e6 * latency) / _outStreamFormat.mSampleRate);
+
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ " initial playout status: _renderDelayOffsetSamples=%d,"
+ " _renderDelayUs=%d, _renderLatencyUs=%d",
+ _renderDelayOffsetSamples, _renderDelayUs, _renderLatencyUs);
+ return 0;
}
OSStatus AudioDeviceMac::objectListenerProc(
AudioObjectID objectId,
UInt32 numberAddresses,
const AudioObjectPropertyAddress addresses[],
- void* clientData)
-{
- AudioDeviceMac *ptrThis = (AudioDeviceMac *) clientData;
- RTC_DCHECK(ptrThis != NULL);
+ void* clientData) {
+ AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData;
+ RTC_DCHECK(ptrThis != NULL);
- ptrThis->implObjectListenerProc(objectId, numberAddresses, addresses);
+ ptrThis->implObjectListenerProc(objectId, numberAddresses, addresses);
- // AudioObjectPropertyListenerProc functions are supposed to return 0
- return 0;
+ // AudioObjectPropertyListenerProc functions are supposed to return 0
+ return 0;
}
OSStatus AudioDeviceMac::implObjectListenerProc(
const AudioObjectID objectId,
const UInt32 numberAddresses,
- const AudioObjectPropertyAddress addresses[])
-{
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
- "AudioDeviceMac::implObjectListenerProc()");
-
- for (UInt32 i = 0; i < numberAddresses; i++)
- {
- if (addresses[i].mSelector == kAudioHardwarePropertyDevices)
- {
- HandleDeviceChange();
- } else if (addresses[i].mSelector == kAudioDevicePropertyStreamFormat)
- {
- HandleStreamFormatChange(objectId, addresses[i]);
- } else if (addresses[i].mSelector == kAudioDevicePropertyDataSource)
- {
- HandleDataSourceChange(objectId, addresses[i]);
- } else if (addresses[i].mSelector == kAudioDeviceProcessorOverload)
- {
- HandleProcessorOverload(addresses[i]);
- }
+ const AudioObjectPropertyAddress addresses[]) {
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
+ "AudioDeviceMac::implObjectListenerProc()");
+
+ for (UInt32 i = 0; i < numberAddresses; i++) {
+ if (addresses[i].mSelector == kAudioHardwarePropertyDevices) {
+ HandleDeviceChange();
+ } else if (addresses[i].mSelector == kAudioDevicePropertyStreamFormat) {
+ HandleStreamFormatChange(objectId, addresses[i]);
+ } else if (addresses[i].mSelector == kAudioDevicePropertyDataSource) {
+ HandleDataSourceChange(objectId, addresses[i]);
+ } else if (addresses[i].mSelector == kAudioDeviceProcessorOverload) {
+ HandleProcessorOverload(addresses[i]);
}
+ }
- return 0;
+ return 0;
}
-int32_t AudioDeviceMac::HandleDeviceChange()
-{
- OSStatus err = noErr;
+int32_t AudioDeviceMac::HandleDeviceChange() {
+ OSStatus err = noErr;
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
- "kAudioHardwarePropertyDevices");
-
- // A device has changed. Check if our registered devices have been removed.
- // Ensure the devices have been initialized, meaning the IDs are valid.
- if (MicrophoneIsInitialized())
- {
- AudioObjectPropertyAddress propertyAddress = {
- kAudioDevicePropertyDeviceIsAlive,
- kAudioDevicePropertyScopeInput, 0 };
- UInt32 deviceIsAlive = 1;
- UInt32 size = sizeof(UInt32);
- err = AudioObjectGetPropertyData(_inputDeviceID, &propertyAddress, 0,
- NULL, &size, &deviceIsAlive);
-
- if (err == kAudioHardwareBadDeviceError || deviceIsAlive == 0)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- "Capture device is not alive (probably removed)");
- AtomicSet32(&_captureDeviceIsAlive, 0);
- _mixerManager.CloseMicrophone();
- if (_recError == 1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice,
- _id, " pending recording error exists");
- }
- _recError = 1; // triggers callback from module process thread
- } else if (err != noErr)
- {
- logCAMsg(kTraceError, kTraceAudioDevice, _id,
- "Error in AudioDeviceGetProperty()", (const char*) &err);
- return -1;
- }
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
+ "kAudioHardwarePropertyDevices");
+
+ // A device has changed. Check if our registered devices have been removed.
+ // Ensure the devices have been initialized, meaning the IDs are valid.
+ if (MicrophoneIsInitialized()) {
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyDeviceIsAlive, kAudioDevicePropertyScopeInput, 0};
+ UInt32 deviceIsAlive = 1;
+ UInt32 size = sizeof(UInt32);
+ err = AudioObjectGetPropertyData(_inputDeviceID, &propertyAddress, 0, NULL,
+ &size, &deviceIsAlive);
+
+ if (err == kAudioHardwareBadDeviceError || deviceIsAlive == 0) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ "Capture device is not alive (probably removed)");
+ AtomicSet32(&_captureDeviceIsAlive, 0);
+ _mixerManager.CloseMicrophone();
+ if (_recError == 1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " pending recording error exists");
+ }
+ _recError = 1; // triggers callback from module process thread
+ } else if (err != noErr) {
+ logCAMsg(kTraceError, kTraceAudioDevice, _id,
+ "Error in AudioDeviceGetProperty()", (const char*)&err);
+ return -1;
}
+ }
- if (SpeakerIsInitialized())
- {
- AudioObjectPropertyAddress propertyAddress = {
- kAudioDevicePropertyDeviceIsAlive,
- kAudioDevicePropertyScopeOutput, 0 };
- UInt32 deviceIsAlive = 1;
- UInt32 size = sizeof(UInt32);
- err = AudioObjectGetPropertyData(_outputDeviceID, &propertyAddress, 0,
- NULL, &size, &deviceIsAlive);
-
- if (err == kAudioHardwareBadDeviceError || deviceIsAlive == 0)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- "Render device is not alive (probably removed)");
- AtomicSet32(&_renderDeviceIsAlive, 0);
- _mixerManager.CloseSpeaker();
- if (_playError == 1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice,
- _id, " pending playout error exists");
- }
- _playError = 1; // triggers callback from module process thread
- } else if (err != noErr)
- {
- logCAMsg(kTraceError, kTraceAudioDevice, _id,
- "Error in AudioDeviceGetProperty()", (const char*) &err);
- return -1;
- }
+ if (SpeakerIsInitialized()) {
+ AudioObjectPropertyAddress propertyAddress = {
+ kAudioDevicePropertyDeviceIsAlive, kAudioDevicePropertyScopeOutput, 0};
+ UInt32 deviceIsAlive = 1;
+ UInt32 size = sizeof(UInt32);
+ err = AudioObjectGetPropertyData(_outputDeviceID, &propertyAddress, 0, NULL,
+ &size, &deviceIsAlive);
+
+ if (err == kAudioHardwareBadDeviceError || deviceIsAlive == 0) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ "Render device is not alive (probably removed)");
+ AtomicSet32(&_renderDeviceIsAlive, 0);
+ _mixerManager.CloseSpeaker();
+ if (_playError == 1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " pending playout error exists");
+ }
+ _playError = 1; // triggers callback from module process thread
+ } else if (err != noErr) {
+ logCAMsg(kTraceError, kTraceAudioDevice, _id,
+ "Error in AudioDeviceGetProperty()", (const char*)&err);
+ return -1;
}
+ }
- return 0;
+ return 0;
}
int32_t AudioDeviceMac::HandleStreamFormatChange(
const AudioObjectID objectId,
- const AudioObjectPropertyAddress propertyAddress)
-{
- OSStatus err = noErr;
+ const AudioObjectPropertyAddress propertyAddress) {
+ OSStatus err = noErr;
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
- "Stream format changed");
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, "Stream format changed");
- if (objectId != _inputDeviceID && objectId != _outputDeviceID)
- {
- return 0;
- }
-
- // Get the new device format
- AudioStreamBasicDescription streamFormat;
- UInt32 size = sizeof(streamFormat);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(objectId,
- &propertyAddress, 0, NULL, &size, &streamFormat));
-
- if (streamFormat.mFormatID != kAudioFormatLinearPCM)
- {
- logCAMsg(kTraceError, kTraceAudioDevice, _id,
- "Unacceptable input stream format -> mFormatID",
- (const char *) &streamFormat.mFormatID);
- return -1;
- }
-
- if (streamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "Too many channels on device (mChannelsPerFrame = %d)",
- streamFormat.mChannelsPerFrame);
- return -1;
- }
+ if (objectId != _inputDeviceID && objectId != _outputDeviceID) {
+ return 0;
+ }
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "Stream format:");
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "mSampleRate = %f, mChannelsPerFrame = %u",
- streamFormat.mSampleRate, streamFormat.mChannelsPerFrame);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "mBytesPerPacket = %u, mFramesPerPacket = %u",
- streamFormat.mBytesPerPacket, streamFormat.mFramesPerPacket);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "mBytesPerFrame = %u, mBitsPerChannel = %u",
- streamFormat.mBytesPerFrame, streamFormat.mBitsPerChannel);
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "mFormatFlags = %u",
- streamFormat.mFormatFlags);
- logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID",
- (const char *) &streamFormat.mFormatID);
-
- if (propertyAddress.mScope == kAudioDevicePropertyScopeInput)
- {
- const int io_block_size_samples = streamFormat.mChannelsPerFrame *
- streamFormat.mSampleRate / 100 * N_BLOCKS_IO;
- if (io_block_size_samples > _captureBufSizeSamples)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- "Input IO block size (%d) is larger than ring buffer (%u)",
- io_block_size_samples, _captureBufSizeSamples);
- return -1;
+ // Get the new device format
+ AudioStreamBasicDescription streamFormat;
+ UInt32 size = sizeof(streamFormat);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ objectId, &propertyAddress, 0, NULL, &size, &streamFormat));
- }
+ if (streamFormat.mFormatID != kAudioFormatLinearPCM) {
+ logCAMsg(kTraceError, kTraceAudioDevice, _id,
+ "Unacceptable input stream format -> mFormatID",
+ (const char*)&streamFormat.mFormatID);
+ return -1;
+ }
- memcpy(&_inStreamFormat, &streamFormat, sizeof(streamFormat));
-
- if (_inStreamFormat.mChannelsPerFrame >= 2 && (_recChannels == 2))
- {
- _inDesiredFormat.mChannelsPerFrame = 2;
- } else
- {
- // Disable stereo recording when we only have one channel on the device.
- _inDesiredFormat.mChannelsPerFrame = 1;
- _recChannels = 1;
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "Stereo recording unavailable on this device");
- }
+ if (streamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "Too many channels on device (mChannelsPerFrame = %d)",
+ streamFormat.mChannelsPerFrame);
+ return -1;
+ }
- if (_ptrAudioBuffer)
- {
- // Update audio buffer with the selected parameters
- _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC);
- _ptrAudioBuffer->SetRecordingChannels((uint8_t) _recChannels);
- }
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "Stream format:");
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "mSampleRate = %f, mChannelsPerFrame = %u",
+ streamFormat.mSampleRate, streamFormat.mChannelsPerFrame);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "mBytesPerPacket = %u, mFramesPerPacket = %u",
+ streamFormat.mBytesPerPacket, streamFormat.mFramesPerPacket);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "mBytesPerFrame = %u, mBitsPerChannel = %u",
+ streamFormat.mBytesPerFrame, streamFormat.mBitsPerChannel);
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "mFormatFlags = %u",
+ streamFormat.mFormatFlags);
+ logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID",
+ (const char*)&streamFormat.mFormatID);
+
+ if (propertyAddress.mScope == kAudioDevicePropertyScopeInput) {
+ const int io_block_size_samples = streamFormat.mChannelsPerFrame *
+ streamFormat.mSampleRate / 100 *
+ N_BLOCKS_IO;
+ if (io_block_size_samples > _captureBufSizeSamples) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "Input IO block size (%d) is larger than ring buffer (%u)",
+ io_block_size_samples, _captureBufSizeSamples);
+ return -1;
+ }
+
+ memcpy(&_inStreamFormat, &streamFormat, sizeof(streamFormat));
+
+ if (_inStreamFormat.mChannelsPerFrame >= 2 && (_recChannels == 2)) {
+ _inDesiredFormat.mChannelsPerFrame = 2;
+ } else {
+ // Disable stereo recording when we only have one channel on the device.
+ _inDesiredFormat.mChannelsPerFrame = 1;
+ _recChannels = 1;
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "Stereo recording unavailable on this device");
+ }
+
+ if (_ptrAudioBuffer) {
+ // Update audio buffer with the selected parameters
+ _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC);
+ _ptrAudioBuffer->SetRecordingChannels((uint8_t)_recChannels);
+ }
+
+ // Recreate the converter with the new format
+ // TODO(xians): make this thread safe
+ WEBRTC_CA_RETURN_ON_ERR(AudioConverterDispose(_captureConverter));
+
+ WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(&streamFormat, &_inDesiredFormat,
+ &_captureConverter));
+ } else {
+ memcpy(&_outStreamFormat, &streamFormat, sizeof(streamFormat));
- // Recreate the converter with the new format
- // TODO(xians): make this thread safe
- WEBRTC_CA_RETURN_ON_ERR(AudioConverterDispose(_captureConverter));
-
- WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(&streamFormat, &_inDesiredFormat,
- &_captureConverter));
- } else
- {
- memcpy(&_outStreamFormat, &streamFormat, sizeof(streamFormat));
-
- // Our preferred format to work with
- if (_outStreamFormat.mChannelsPerFrame < 2)
- {
- _playChannels = 1;
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "Stereo playout unavailable on this device");
- }
- WEBRTC_CA_RETURN_ON_ERR(SetDesiredPlayoutFormat());
+ // Our preferred format to work with
+ if (_outStreamFormat.mChannelsPerFrame < 2) {
+ _playChannels = 1;
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "Stereo playout unavailable on this device");
}
- return 0;
+ WEBRTC_CA_RETURN_ON_ERR(SetDesiredPlayoutFormat());
+ }
+ return 0;
}
int32_t AudioDeviceMac::HandleDataSourceChange(
const AudioObjectID objectId,
- const AudioObjectPropertyAddress propertyAddress)
-{
- OSStatus err = noErr;
+ const AudioObjectPropertyAddress propertyAddress) {
+ OSStatus err = noErr;
- if (_macBookPro && propertyAddress.mScope
- == kAudioDevicePropertyScopeOutput)
- {
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
- "Data source changed");
-
- _macBookProPanRight = false;
- UInt32 dataSource = 0;
- UInt32 size = sizeof(UInt32);
- WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(objectId,
- &propertyAddress, 0, NULL, &size, &dataSource));
- if (dataSource == 'ispk')
- {
- _macBookProPanRight = true;
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "MacBook Pro using internal speakers; stereo panning right");
- } else
- {
- WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
- "MacBook Pro not using internal speakers");
- }
+ if (_macBookPro &&
+ propertyAddress.mScope == kAudioDevicePropertyScopeOutput) {
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, "Data source changed");
+
+ _macBookProPanRight = false;
+ UInt32 dataSource = 0;
+ UInt32 size = sizeof(UInt32);
+ WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
+ objectId, &propertyAddress, 0, NULL, &size, &dataSource));
+ if (dataSource == 'ispk') {
+ _macBookProPanRight = true;
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "MacBook Pro using internal speakers; stereo panning right");
+ } else {
+ WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
+ "MacBook Pro not using internal speakers");
}
+ }
- return 0;
+ return 0;
}
int32_t AudioDeviceMac::HandleProcessorOverload(
- const AudioObjectPropertyAddress propertyAddress)
-{
- // TODO(xians): we probably want to notify the user in some way of the
- // overload. However, the Windows interpretations of these errors seem to
- // be more severe than what ProcessorOverload is thrown for.
- //
- // We don't log the notification, as it's sent from the HAL's IO thread. We
- // don't want to slow it down even further.
- if (propertyAddress.mScope == kAudioDevicePropertyScopeInput)
- {
- //WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "Capture processor
- // overload");
- //_callback->ProblemIsReported(
- // SndCardStreamObserver::ERecordingProblem);
- } else
- {
- //WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- // "Render processor overload");
- //_callback->ProblemIsReported(
- // SndCardStreamObserver::EPlaybackProblem);
- }
+ const AudioObjectPropertyAddress propertyAddress) {
+ // TODO(xians): we probably want to notify the user in some way of the
+ // overload. However, the Windows interpretations of these errors seem to
+ // be more severe than what ProcessorOverload is thrown for.
+ //
+ // We don't log the notification, as it's sent from the HAL's IO thread. We
+ // don't want to slow it down even further.
+ if (propertyAddress.mScope == kAudioDevicePropertyScopeInput) {
+ // WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "Capture processor
+ // overload");
+ //_callback->ProblemIsReported(
+ // SndCardStreamObserver::ERecordingProblem);
+ } else {
+ // WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ // "Render processor overload");
+ //_callback->ProblemIsReported(
+ // SndCardStreamObserver::EPlaybackProblem);
+ }
- return 0;
+ return 0;
}
// ============================================================================
// Thread Methods
// ============================================================================
-OSStatus AudioDeviceMac::deviceIOProc(AudioDeviceID, const AudioTimeStamp*,
+OSStatus AudioDeviceMac::deviceIOProc(AudioDeviceID,
+ const AudioTimeStamp*,
const AudioBufferList* inputData,
const AudioTimeStamp* inputTime,
AudioBufferList* outputData,
const AudioTimeStamp* outputTime,
- void *clientData)
-{
- AudioDeviceMac *ptrThis = (AudioDeviceMac *) clientData;
- RTC_DCHECK(ptrThis != NULL);
+ void* clientData) {
+ AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData;
+ RTC_DCHECK(ptrThis != NULL);
- ptrThis->implDeviceIOProc(inputData, inputTime, outputData, outputTime);
+ ptrThis->implDeviceIOProc(inputData, inputTime, outputData, outputTime);
- // AudioDeviceIOProc functions are supposed to return 0
- return 0;
+ // AudioDeviceIOProc functions are supposed to return 0
+ return 0;
}
OSStatus AudioDeviceMac::outConverterProc(AudioConverterRef,
- UInt32 *numberDataPackets,
- AudioBufferList *data,
- AudioStreamPacketDescription **,
- void *userData)
-{
- AudioDeviceMac *ptrThis = (AudioDeviceMac *) userData;
- RTC_DCHECK(ptrThis != NULL);
+ UInt32* numberDataPackets,
+ AudioBufferList* data,
+ AudioStreamPacketDescription**,
+ void* userData) {
+ AudioDeviceMac* ptrThis = (AudioDeviceMac*)userData;
+ RTC_DCHECK(ptrThis != NULL);
- return ptrThis->implOutConverterProc(numberDataPackets, data);
+ return ptrThis->implOutConverterProc(numberDataPackets, data);
}
-OSStatus AudioDeviceMac::inDeviceIOProc(AudioDeviceID, const AudioTimeStamp*,
+OSStatus AudioDeviceMac::inDeviceIOProc(AudioDeviceID,
+ const AudioTimeStamp*,
const AudioBufferList* inputData,
const AudioTimeStamp* inputTime,
AudioBufferList*,
- const AudioTimeStamp*, void* clientData)
-{
- AudioDeviceMac *ptrThis = (AudioDeviceMac *) clientData;
- RTC_DCHECK(ptrThis != NULL);
+ const AudioTimeStamp*,
+ void* clientData) {
+ AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData;
+ RTC_DCHECK(ptrThis != NULL);
- ptrThis->implInDeviceIOProc(inputData, inputTime);
+ ptrThis->implInDeviceIOProc(inputData, inputTime);
- // AudioDeviceIOProc functions are supposed to return 0
- return 0;
+ // AudioDeviceIOProc functions are supposed to return 0
+ return 0;
}
OSStatus AudioDeviceMac::inConverterProc(
AudioConverterRef,
- UInt32 *numberDataPackets,
- AudioBufferList *data,
- AudioStreamPacketDescription ** /*dataPacketDescription*/,
- void *userData)
-{
- AudioDeviceMac *ptrThis = static_cast<AudioDeviceMac*> (userData);
- RTC_DCHECK(ptrThis != NULL);
-
- return ptrThis->implInConverterProc(numberDataPackets, data);
-}
-
-OSStatus AudioDeviceMac::implDeviceIOProc(const AudioBufferList *inputData,
- const AudioTimeStamp *inputTime,
- AudioBufferList *outputData,
- const AudioTimeStamp *outputTime)
-{
- OSStatus err = noErr;
- UInt64 outputTimeNs = AudioConvertHostTimeToNanos(outputTime->mHostTime);
- UInt64 nowNs = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
-
- if (!_twoDevices && _recording)
- {
- implInDeviceIOProc(inputData, inputTime);
- }
+ UInt32* numberDataPackets,
+ AudioBufferList* data,
+ AudioStreamPacketDescription** /*dataPacketDescription*/,
+ void* userData) {
+ AudioDeviceMac* ptrThis = static_cast<AudioDeviceMac*>(userData);
+ RTC_DCHECK(ptrThis != NULL);
+
+ return ptrThis->implInConverterProc(numberDataPackets, data);
+}
+
+OSStatus AudioDeviceMac::implDeviceIOProc(const AudioBufferList* inputData,
+ const AudioTimeStamp* inputTime,
+ AudioBufferList* outputData,
+ const AudioTimeStamp* outputTime) {
+ OSStatus err = noErr;
+ UInt64 outputTimeNs = AudioConvertHostTimeToNanos(outputTime->mHostTime);
+ UInt64 nowNs = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
+
+ if (!_twoDevices && _recording) {
+ implInDeviceIOProc(inputData, inputTime);
+ }
- // Check if we should close down audio device
- // Double-checked locking optimization to remove locking overhead
- if (_doStop)
- {
- _critSect.Enter();
- if (_doStop)
- {
- if (_twoDevices || (!_recording && !_playing))
- {
- // In the case of a shared device, the single driving ioProc
- // is stopped here
- WEBRTC_CA_LOG_ERR(AudioDeviceStop(_outputDeviceID,
- _deviceIOProcID));
- WEBRTC_CA_LOG_WARN(AudioDeviceDestroyIOProcID(_outputDeviceID,
- _deviceIOProcID));
- if (err == noErr)
- {
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice,
- _id, " Playout or shared device stopped");
- }
- }
-
- _doStop = false;
- _stopEvent.Set();
- _critSect.Leave();
- return 0;
+ // Check if we should close down audio device
+ // Double-checked locking optimization to remove locking overhead
+ if (_doStop) {
+ _critSect.Enter();
+ if (_doStop) {
+ if (_twoDevices || (!_recording && !_playing)) {
+ // In the case of a shared device, the single driving ioProc
+ // is stopped here
+ WEBRTC_CA_LOG_ERR(AudioDeviceStop(_outputDeviceID, _deviceIOProcID));
+ WEBRTC_CA_LOG_WARN(
+ AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
+ if (err == noErr) {
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
+ " Playout or shared device stopped");
}
- _critSect.Leave();
- }
+ }
- if (!_playing)
- {
- // This can be the case when a shared device is capturing but not
- // rendering. We allow the checks above before returning to avoid a
- // timeout when capturing is stopped.
- return 0;
+ _doStop = false;
+ _stopEvent.Set();
+ _critSect.Leave();
+ return 0;
}
+ _critSect.Leave();
+ }
- RTC_DCHECK(_outStreamFormat.mBytesPerFrame != 0);
- UInt32 size = outputData->mBuffers->mDataByteSize
- / _outStreamFormat.mBytesPerFrame;
-
- // TODO(xians): signal an error somehow?
- err = AudioConverterFillComplexBuffer(_renderConverter, outConverterProc,
- this, &size, outputData, NULL);
- if (err != noErr)
- {
- if (err == 1)
- {
- // This is our own error.
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " Error in AudioConverterFillComplexBuffer()");
- return 1;
- } else
- {
- logCAMsg(kTraceError, kTraceAudioDevice, _id,
- "Error in AudioConverterFillComplexBuffer()",
- (const char *) &err);
- return 1;
- }
+ if (!_playing) {
+ // This can be the case when a shared device is capturing but not
+ // rendering. We allow the checks above before returning to avoid a
+ // timeout when capturing is stopped.
+ return 0;
+ }
+
+ RTC_DCHECK(_outStreamFormat.mBytesPerFrame != 0);
+ UInt32 size =
+ outputData->mBuffers->mDataByteSize / _outStreamFormat.mBytesPerFrame;
+
+ // TODO(xians): signal an error somehow?
+ err = AudioConverterFillComplexBuffer(_renderConverter, outConverterProc,
+ this, &size, outputData, NULL);
+ if (err != noErr) {
+ if (err == 1) {
+ // This is our own error.
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " Error in AudioConverterFillComplexBuffer()");
+ return 1;
+ } else {
+ logCAMsg(kTraceError, kTraceAudioDevice, _id,
+ "Error in AudioConverterFillComplexBuffer()", (const char*)&err);
+ return 1;
}
+ }
- PaRingBufferSize bufSizeSamples =
- PaUtil_GetRingBufferReadAvailable(_paRenderBuffer);
+ PaRingBufferSize bufSizeSamples =
+ PaUtil_GetRingBufferReadAvailable(_paRenderBuffer);
- int32_t renderDelayUs = static_cast<int32_t> (1e-3 * (outputTimeNs - nowNs)
- + 0.5);
- renderDelayUs += static_cast<int32_t> ((1.0e6 * bufSizeSamples)
- / _outDesiredFormat.mChannelsPerFrame / _outDesiredFormat.mSampleRate
- + 0.5);
+ int32_t renderDelayUs =
+ static_cast<int32_t>(1e-3 * (outputTimeNs - nowNs) + 0.5);
+ renderDelayUs += static_cast<int32_t>(
+ (1.0e6 * bufSizeSamples) / _outDesiredFormat.mChannelsPerFrame /
+ _outDesiredFormat.mSampleRate +
+ 0.5);
- AtomicSet32(&_renderDelayUs, renderDelayUs);
+ AtomicSet32(&_renderDelayUs, renderDelayUs);
- return 0;
+ return 0;
}
-OSStatus AudioDeviceMac::implOutConverterProc(UInt32 *numberDataPackets,
- AudioBufferList *data)
-{
+OSStatus AudioDeviceMac::implOutConverterProc(UInt32* numberDataPackets,
+ AudioBufferList* data) {
RTC_DCHECK(data->mNumberBuffers == 1);
- PaRingBufferSize numSamples = *numberDataPackets
- * _outDesiredFormat.mChannelsPerFrame;
-
- data->mBuffers->mNumberChannels = _outDesiredFormat.mChannelsPerFrame;
- // Always give the converter as much as it wants, zero padding as required.
- data->mBuffers->mDataByteSize = *numberDataPackets
- * _outDesiredFormat.mBytesPerPacket;
- data->mBuffers->mData = _renderConvertData;
- memset(_renderConvertData, 0, sizeof(_renderConvertData));
-
- PaUtil_ReadRingBuffer(_paRenderBuffer, _renderConvertData, numSamples);
-
- kern_return_t kernErr = semaphore_signal_all(_renderSemaphore);
- if (kernErr != KERN_SUCCESS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " semaphore_signal_all() error: %d", kernErr);
- return 1;
- }
+ PaRingBufferSize numSamples =
+ *numberDataPackets * _outDesiredFormat.mChannelsPerFrame;
- return 0;
+ data->mBuffers->mNumberChannels = _outDesiredFormat.mChannelsPerFrame;
+ // Always give the converter as much as it wants, zero padding as required.
+ data->mBuffers->mDataByteSize =
+ *numberDataPackets * _outDesiredFormat.mBytesPerPacket;
+ data->mBuffers->mData = _renderConvertData;
+ memset(_renderConvertData, 0, sizeof(_renderConvertData));
+
+ PaUtil_ReadRingBuffer(_paRenderBuffer, _renderConvertData, numSamples);
+
+ kern_return_t kernErr = semaphore_signal_all(_renderSemaphore);
+ if (kernErr != KERN_SUCCESS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " semaphore_signal_all() error: %d", kernErr);
+ return 1;
+ }
+
+ return 0;
}
-OSStatus AudioDeviceMac::implInDeviceIOProc(const AudioBufferList *inputData,
- const AudioTimeStamp *inputTime)
-{
- OSStatus err = noErr;
- UInt64 inputTimeNs = AudioConvertHostTimeToNanos(inputTime->mHostTime);
- UInt64 nowNs = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
-
- // Check if we should close down audio device
- // Double-checked locking optimization to remove locking overhead
- if (_doStopRec)
- {
- _critSect.Enter();
- if (_doStopRec)
- {
- // This will be signalled only when a shared device is not in use.
- WEBRTC_CA_LOG_ERR(AudioDeviceStop(_inputDeviceID, _inDeviceIOProcID));
- WEBRTC_CA_LOG_WARN(AudioDeviceDestroyIOProcID(_inputDeviceID,
- _inDeviceIOProcID));
- if (err == noErr)
- {
- WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice,
- _id, " Recording device stopped");
- }
-
- _doStopRec = false;
- _stopEventRec.Set();
- _critSect.Leave();
- return 0;
- }
- _critSect.Leave();
- }
+OSStatus AudioDeviceMac::implInDeviceIOProc(const AudioBufferList* inputData,
+ const AudioTimeStamp* inputTime) {
+ OSStatus err = noErr;
+ UInt64 inputTimeNs = AudioConvertHostTimeToNanos(inputTime->mHostTime);
+ UInt64 nowNs = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
- if (!_recording)
- {
- // Allow above checks to avoid a timeout on stopping capture.
- return 0;
- }
+ // Check if we should close down audio device
+ // Double-checked locking optimization to remove locking overhead
+ if (_doStopRec) {
+ _critSect.Enter();
+ if (_doStopRec) {
+ // This will be signalled only when a shared device is not in use.
+ WEBRTC_CA_LOG_ERR(AudioDeviceStop(_inputDeviceID, _inDeviceIOProcID));
+ WEBRTC_CA_LOG_WARN(
+ AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID));
+ if (err == noErr) {
+ WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
+ " Recording device stopped");
+ }
- PaRingBufferSize bufSizeSamples =
- PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer);
-
- int32_t captureDelayUs = static_cast<int32_t> (1e-3 * (nowNs - inputTimeNs)
- + 0.5);
- captureDelayUs
- += static_cast<int32_t> ((1.0e6 * bufSizeSamples)
- / _inStreamFormat.mChannelsPerFrame / _inStreamFormat.mSampleRate
- + 0.5);
-
- AtomicSet32(&_captureDelayUs, captureDelayUs);
-
- RTC_DCHECK(inputData->mNumberBuffers == 1);
- PaRingBufferSize numSamples = inputData->mBuffers->mDataByteSize
- * _inStreamFormat.mChannelsPerFrame / _inStreamFormat.mBytesPerPacket;
- PaUtil_WriteRingBuffer(_paCaptureBuffer, inputData->mBuffers->mData,
- numSamples);
-
- kern_return_t kernErr = semaphore_signal_all(_captureSemaphore);
- if (kernErr != KERN_SUCCESS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " semaphore_signal_all() error: %d", kernErr);
+ _doStopRec = false;
+ _stopEventRec.Set();
+ _critSect.Leave();
+ return 0;
}
+ _critSect.Leave();
+ }
- return err;
-}
+ if (!_recording) {
+ // Allow above checks to avoid a timeout on stopping capture.
+ return 0;
+ }
-OSStatus AudioDeviceMac::implInConverterProc(UInt32 *numberDataPackets,
- AudioBufferList *data)
-{
- RTC_DCHECK(data->mNumberBuffers == 1);
- PaRingBufferSize numSamples = *numberDataPackets
- * _inStreamFormat.mChannelsPerFrame;
-
- while (PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer) < numSamples)
- {
- mach_timespec_t timeout;
- timeout.tv_sec = 0;
- timeout.tv_nsec = TIMER_PERIOD_MS;
-
- kern_return_t kernErr = semaphore_timedwait(_captureSemaphore, timeout);
- if (kernErr == KERN_OPERATION_TIMED_OUT)
- {
- int32_t signal = AtomicGet32(&_captureDeviceIsAlive);
- if (signal == 0)
- {
- // The capture device is no longer alive; stop the worker thread.
- *numberDataPackets = 0;
- return 1;
- }
- } else if (kernErr != KERN_SUCCESS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " semaphore_wait() error: %d", kernErr);
- }
- }
+ PaRingBufferSize bufSizeSamples =
+ PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer);
- // Pass the read pointer directly to the converter to avoid a memcpy.
- void* dummyPtr;
- PaRingBufferSize dummySize;
- PaUtil_GetRingBufferReadRegions(_paCaptureBuffer, numSamples,
- &data->mBuffers->mData, &numSamples,
- &dummyPtr, &dummySize);
- PaUtil_AdvanceRingBufferReadIndex(_paCaptureBuffer, numSamples);
+ int32_t captureDelayUs =
+ static_cast<int32_t>(1e-3 * (nowNs - inputTimeNs) + 0.5);
+ captureDelayUs += static_cast<int32_t>((1.0e6 * bufSizeSamples) /
+ _inStreamFormat.mChannelsPerFrame /
+ _inStreamFormat.mSampleRate +
+ 0.5);
- data->mBuffers->mNumberChannels = _inStreamFormat.mChannelsPerFrame;
- *numberDataPackets = numSamples / _inStreamFormat.mChannelsPerFrame;
- data->mBuffers->mDataByteSize = *numberDataPackets
- * _inStreamFormat.mBytesPerPacket;
+ AtomicSet32(&_captureDelayUs, captureDelayUs);
- return 0;
+ RTC_DCHECK(inputData->mNumberBuffers == 1);
+ PaRingBufferSize numSamples = inputData->mBuffers->mDataByteSize *
+ _inStreamFormat.mChannelsPerFrame /
+ _inStreamFormat.mBytesPerPacket;
+ PaUtil_WriteRingBuffer(_paCaptureBuffer, inputData->mBuffers->mData,
+ numSamples);
+
+ kern_return_t kernErr = semaphore_signal_all(_captureSemaphore);
+ if (kernErr != KERN_SUCCESS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " semaphore_signal_all() error: %d", kernErr);
+ }
+
+ return err;
}
-bool AudioDeviceMac::RunRender(void* ptrThis)
-{
- return static_cast<AudioDeviceMac*> (ptrThis)->RenderWorkerThread();
-}
-
-bool AudioDeviceMac::RenderWorkerThread()
-{
- PaRingBufferSize numSamples = ENGINE_PLAY_BUF_SIZE_IN_SAMPLES
- * _outDesiredFormat.mChannelsPerFrame;
- while (PaUtil_GetRingBufferWriteAvailable(_paRenderBuffer)
- - _renderDelayOffsetSamples < numSamples)
- {
- mach_timespec_t timeout;
- timeout.tv_sec = 0;
- timeout.tv_nsec = TIMER_PERIOD_MS;
-
- kern_return_t kernErr = semaphore_timedwait(_renderSemaphore, timeout);
- if (kernErr == KERN_OPERATION_TIMED_OUT)
- {
- int32_t signal = AtomicGet32(&_renderDeviceIsAlive);
- if (signal == 0)
- {
- // The render device is no longer alive; stop the worker thread.
- return false;
- }
- } else if (kernErr != KERN_SUCCESS)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " semaphore_timedwait() error: %d", kernErr);
- }
+OSStatus AudioDeviceMac::implInConverterProc(UInt32* numberDataPackets,
+ AudioBufferList* data) {
+ RTC_DCHECK(data->mNumberBuffers == 1);
+ PaRingBufferSize numSamples =
+ *numberDataPackets * _inStreamFormat.mChannelsPerFrame;
+
+ while (PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer) < numSamples) {
+ mach_timespec_t timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = TIMER_PERIOD_MS;
+
+ kern_return_t kernErr = semaphore_timedwait(_captureSemaphore, timeout);
+ if (kernErr == KERN_OPERATION_TIMED_OUT) {
+ int32_t signal = AtomicGet32(&_captureDeviceIsAlive);
+ if (signal == 0) {
+ // The capture device is no longer alive; stop the worker thread.
+ *numberDataPackets = 0;
+ return 1;
+ }
+ } else if (kernErr != KERN_SUCCESS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " semaphore_wait() error: %d", kernErr);
}
+ }
- int8_t playBuffer[4 * ENGINE_PLAY_BUF_SIZE_IN_SAMPLES];
-
- if (!_ptrAudioBuffer)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " capture AudioBuffer is invalid");
+ // Pass the read pointer directly to the converter to avoid a memcpy.
+ void* dummyPtr;
+ PaRingBufferSize dummySize;
+ PaUtil_GetRingBufferReadRegions(_paCaptureBuffer, numSamples,
+ &data->mBuffers->mData, &numSamples,
+ &dummyPtr, &dummySize);
+ PaUtil_AdvanceRingBufferReadIndex(_paCaptureBuffer, numSamples);
+
+ data->mBuffers->mNumberChannels = _inStreamFormat.mChannelsPerFrame;
+ *numberDataPackets = numSamples / _inStreamFormat.mChannelsPerFrame;
+ data->mBuffers->mDataByteSize =
+ *numberDataPackets * _inStreamFormat.mBytesPerPacket;
+
+ return 0;
+}
+
+bool AudioDeviceMac::RunRender(void* ptrThis) {
+ return static_cast<AudioDeviceMac*>(ptrThis)->RenderWorkerThread();
+}
+
+bool AudioDeviceMac::RenderWorkerThread() {
+ PaRingBufferSize numSamples =
+ ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * _outDesiredFormat.mChannelsPerFrame;
+ while (PaUtil_GetRingBufferWriteAvailable(_paRenderBuffer) -
+ _renderDelayOffsetSamples <
+ numSamples) {
+ mach_timespec_t timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = TIMER_PERIOD_MS;
+
+ kern_return_t kernErr = semaphore_timedwait(_renderSemaphore, timeout);
+ if (kernErr == KERN_OPERATION_TIMED_OUT) {
+ int32_t signal = AtomicGet32(&_renderDeviceIsAlive);
+ if (signal == 0) {
+ // The render device is no longer alive; stop the worker thread.
return false;
+ }
+ } else if (kernErr != KERN_SUCCESS) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " semaphore_timedwait() error: %d", kernErr);
}
+ }
- // Ask for new PCM data to be played out using the AudioDeviceBuffer.
- uint32_t nSamples =
- _ptrAudioBuffer->RequestPlayoutData(ENGINE_PLAY_BUF_SIZE_IN_SAMPLES);
+ int8_t playBuffer[4 * ENGINE_PLAY_BUF_SIZE_IN_SAMPLES];
- nSamples = _ptrAudioBuffer->GetPlayoutData(playBuffer);
- if (nSamples != ENGINE_PLAY_BUF_SIZE_IN_SAMPLES)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " invalid number of output samples(%d)", nSamples);
- }
+ if (!_ptrAudioBuffer) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " capture AudioBuffer is invalid");
+ return false;
+ }
- uint32_t nOutSamples = nSamples * _outDesiredFormat.mChannelsPerFrame;
-
- SInt16 *pPlayBuffer = (SInt16 *) &playBuffer;
- if (_macBookProPanRight && (_playChannels == 2))
- {
- // Mix entirely into the right channel and zero the left channel.
- SInt32 sampleInt32 = 0;
- for (uint32_t sampleIdx = 0; sampleIdx < nOutSamples; sampleIdx
- += 2)
- {
- sampleInt32 = pPlayBuffer[sampleIdx];
- sampleInt32 += pPlayBuffer[sampleIdx + 1];
- sampleInt32 /= 2;
-
- if (sampleInt32 > 32767)
- {
- sampleInt32 = 32767;
- } else if (sampleInt32 < -32768)
- {
- sampleInt32 = -32768;
- }
-
- pPlayBuffer[sampleIdx] = 0;
- pPlayBuffer[sampleIdx + 1] = static_cast<SInt16> (sampleInt32);
- }
+ // Ask for new PCM data to be played out using the AudioDeviceBuffer.
+ uint32_t nSamples =
+ _ptrAudioBuffer->RequestPlayoutData(ENGINE_PLAY_BUF_SIZE_IN_SAMPLES);
+
+ nSamples = _ptrAudioBuffer->GetPlayoutData(playBuffer);
+ if (nSamples != ENGINE_PLAY_BUF_SIZE_IN_SAMPLES) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " invalid number of output samples(%d)", nSamples);
+ }
+
+ uint32_t nOutSamples = nSamples * _outDesiredFormat.mChannelsPerFrame;
+
+ SInt16* pPlayBuffer = (SInt16*)&playBuffer;
+ if (_macBookProPanRight && (_playChannels == 2)) {
+ // Mix entirely into the right channel and zero the left channel.
+ SInt32 sampleInt32 = 0;
+ for (uint32_t sampleIdx = 0; sampleIdx < nOutSamples; sampleIdx += 2) {
+ sampleInt32 = pPlayBuffer[sampleIdx];
+ sampleInt32 += pPlayBuffer[sampleIdx + 1];
+ sampleInt32 /= 2;
+
+ if (sampleInt32 > 32767) {
+ sampleInt32 = 32767;
+ } else if (sampleInt32 < -32768) {
+ sampleInt32 = -32768;
+ }
+
+ pPlayBuffer[sampleIdx] = 0;
+ pPlayBuffer[sampleIdx + 1] = static_cast<SInt16>(sampleInt32);
}
+ }
- PaUtil_WriteRingBuffer(_paRenderBuffer, pPlayBuffer, nOutSamples);
+ PaUtil_WriteRingBuffer(_paRenderBuffer, pPlayBuffer, nOutSamples);
- return true;
+ return true;
}
-bool AudioDeviceMac::RunCapture(void* ptrThis)
-{
- return static_cast<AudioDeviceMac*> (ptrThis)->CaptureWorkerThread();
+bool AudioDeviceMac::RunCapture(void* ptrThis) {
+ return static_cast<AudioDeviceMac*>(ptrThis)->CaptureWorkerThread();
}
-bool AudioDeviceMac::CaptureWorkerThread()
-{
- OSStatus err = noErr;
- UInt32 noRecSamples = ENGINE_REC_BUF_SIZE_IN_SAMPLES
- * _inDesiredFormat.mChannelsPerFrame;
- SInt16 recordBuffer[noRecSamples];
- UInt32 size = ENGINE_REC_BUF_SIZE_IN_SAMPLES;
-
- AudioBufferList engineBuffer;
- engineBuffer.mNumberBuffers = 1; // Interleaved channels.
- engineBuffer.mBuffers->mNumberChannels = _inDesiredFormat.mChannelsPerFrame;
- engineBuffer.mBuffers->mDataByteSize = _inDesiredFormat.mBytesPerPacket
- * noRecSamples;
- engineBuffer.mBuffers->mData = recordBuffer;
-
- err = AudioConverterFillComplexBuffer(_captureConverter, inConverterProc,
- this, &size, &engineBuffer, NULL);
- if (err != noErr)
- {
- if (err == 1)
- {
- // This is our own error.
- return false;
- } else
- {
- logCAMsg(kTraceError, kTraceAudioDevice, _id,
- "Error in AudioConverterFillComplexBuffer()",
- (const char *) &err);
- return false;
- }
+bool AudioDeviceMac::CaptureWorkerThread() {
+ OSStatus err = noErr;
+ UInt32 noRecSamples =
+ ENGINE_REC_BUF_SIZE_IN_SAMPLES * _inDesiredFormat.mChannelsPerFrame;
+ SInt16 recordBuffer[noRecSamples];
+ UInt32 size = ENGINE_REC_BUF_SIZE_IN_SAMPLES;
+
+ AudioBufferList engineBuffer;
+ engineBuffer.mNumberBuffers = 1; // Interleaved channels.
+ engineBuffer.mBuffers->mNumberChannels = _inDesiredFormat.mChannelsPerFrame;
+ engineBuffer.mBuffers->mDataByteSize =
+ _inDesiredFormat.mBytesPerPacket * noRecSamples;
+ engineBuffer.mBuffers->mData = recordBuffer;
+
+ err = AudioConverterFillComplexBuffer(_captureConverter, inConverterProc,
+ this, &size, &engineBuffer, NULL);
+ if (err != noErr) {
+ if (err == 1) {
+ // This is our own error.
+ return false;
+ } else {
+ logCAMsg(kTraceError, kTraceAudioDevice, _id,
+ "Error in AudioConverterFillComplexBuffer()", (const char*)&err);
+ return false;
}
+ }
- // TODO(xians): what if the returned size is incorrect?
- if (size == ENGINE_REC_BUF_SIZE_IN_SAMPLES)
- {
- uint32_t currentMicLevel(0);
- uint32_t newMicLevel(0);
- int32_t msecOnPlaySide;
- int32_t msecOnRecordSide;
-
- int32_t captureDelayUs = AtomicGet32(&_captureDelayUs);
- int32_t renderDelayUs = AtomicGet32(&_renderDelayUs);
-
- msecOnPlaySide = static_cast<int32_t> (1e-3 * (renderDelayUs +
- _renderLatencyUs) + 0.5);
- msecOnRecordSide = static_cast<int32_t> (1e-3 * (captureDelayUs +
- _captureLatencyUs) +
- 0.5);
-
- if (!_ptrAudioBuffer)
- {
- WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
- " capture AudioBuffer is invalid");
- return false;
- }
+ // TODO(xians): what if the returned size is incorrect?
+ if (size == ENGINE_REC_BUF_SIZE_IN_SAMPLES) {
+ uint32_t currentMicLevel(0);
+ uint32_t newMicLevel(0);
+ int32_t msecOnPlaySide;
+ int32_t msecOnRecordSide;
- // store the recorded buffer (no action will be taken if the
- // #recorded samples is not a full buffer)
- _ptrAudioBuffer->SetRecordedBuffer((int8_t*) &recordBuffer,
- (uint32_t) size);
-
- if (AGC())
- {
- // Use mod to ensure we check the volume on the first pass.
- if (get_mic_volume_counter_ms_ % kGetMicVolumeIntervalMs == 0) {
- get_mic_volume_counter_ms_ = 0;
- // store current mic level in the audio buffer if AGC is enabled
- if (MicrophoneVolume(currentMicLevel) == 0)
- {
- // this call does not affect the actual microphone volume
- _ptrAudioBuffer->SetCurrentMicLevel(currentMicLevel);
- }
- }
- get_mic_volume_counter_ms_ += kBufferSizeMs;
- }
+ int32_t captureDelayUs = AtomicGet32(&_captureDelayUs);
+ int32_t renderDelayUs = AtomicGet32(&_renderDelayUs);
- _ptrAudioBuffer->SetVQEData(msecOnPlaySide, msecOnRecordSide, 0);
-
- _ptrAudioBuffer->SetTypingStatus(KeyPressed());
-
- // deliver recorded samples at specified sample rate, mic level etc.
- // to the observer using callback
- _ptrAudioBuffer->DeliverRecordedData();
-
- if (AGC())
- {
- newMicLevel = _ptrAudioBuffer->NewMicLevel();
- if (newMicLevel != 0)
- {
- // The VQE will only deliver non-zero microphone levels when
- // a change is needed.
- // Set this new mic level (received from the observer as return
- // value in the callback).
- WEBRTC_TRACE(kTraceStream, kTraceAudioDevice,
- _id, " AGC change of volume: old=%u => new=%u",
- currentMicLevel, newMicLevel);
- if (SetMicrophoneVolume(newMicLevel) == -1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
- " the required modification of the microphone "
- "volume failed");
- }
- }
+ msecOnPlaySide =
+ static_cast<int32_t>(1e-3 * (renderDelayUs + _renderLatencyUs) + 0.5);
+ msecOnRecordSide =
+ static_cast<int32_t>(1e-3 * (captureDelayUs + _captureLatencyUs) + 0.5);
+
+ if (!_ptrAudioBuffer) {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ " capture AudioBuffer is invalid");
+ return false;
+ }
+
+ // store the recorded buffer (no action will be taken if the
+ // #recorded samples is not a full buffer)
+ _ptrAudioBuffer->SetRecordedBuffer((int8_t*)&recordBuffer, (uint32_t)size);
+
+ if (AGC()) {
+ // Use mod to ensure we check the volume on the first pass.
+ if (get_mic_volume_counter_ms_ % kGetMicVolumeIntervalMs == 0) {
+ get_mic_volume_counter_ms_ = 0;
+ // store current mic level in the audio buffer if AGC is enabled
+ if (MicrophoneVolume(currentMicLevel) == 0) {
+ // this call does not affect the actual microphone volume
+ _ptrAudioBuffer->SetCurrentMicLevel(currentMicLevel);
}
+ }
+ get_mic_volume_counter_ms_ += kBufferSizeMs;
+ }
+
+ _ptrAudioBuffer->SetVQEData(msecOnPlaySide, msecOnRecordSide, 0);
+
+ _ptrAudioBuffer->SetTypingStatus(KeyPressed());
+
+ // deliver recorded samples at specified sample rate, mic level etc.
+ // to the observer using callback
+ _ptrAudioBuffer->DeliverRecordedData();
+
+ if (AGC()) {
+ newMicLevel = _ptrAudioBuffer->NewMicLevel();
+ if (newMicLevel != 0) {
+ // The VQE will only deliver non-zero microphone levels when
+ // a change is needed.
+ // Set this new mic level (received from the observer as return
+ // value in the callback).
+ WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id,
+ " AGC change of volume: old=%u => new=%u",
+ currentMicLevel, newMicLevel);
+ if (SetMicrophoneVolume(newMicLevel) == -1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
+ " the required modification of the microphone "
+ "volume failed");
+ }
+ }
}
+ }
- return true;
+ return true;
}
bool AudioDeviceMac::KeyPressed() {
bool key_down = false;
// Loop through all Mac virtual key constant values.
- for (unsigned int key_index = 0;
- key_index < arraysize(prev_key_state_);
- ++key_index) {
- bool keyState = CGEventSourceKeyState(
- kCGEventSourceStateHIDSystemState,
- key_index);
+ for (unsigned int key_index = 0; key_index < arraysize(prev_key_state_);
+ ++key_index) {
+ bool keyState =
+ CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key_index);
// A false -> true change in keymap means a key is pressed.
key_down |= (keyState && !prev_key_state_[key_index]);
// Save current state.
diff --git a/webrtc/modules/audio_device/mac/audio_device_mac.h b/webrtc/modules/audio_device/mac/audio_device_mac.h
index 849e74ce45..ca3a51997d 100644
--- a/webrtc/modules/audio_device/mac/audio_device_mac.h
+++ b/webrtc/modules/audio_device/mac/audio_device_mac.h
@@ -27,15 +27,14 @@ namespace rtc {
class PlatformThread;
} // namespace rtc
-namespace webrtc
-{
+namespace webrtc {
class EventWrapper;
const uint32_t N_REC_SAMPLES_PER_SEC = 48000;
const uint32_t N_PLAY_SAMPLES_PER_SEC = 48000;
-const uint32_t N_REC_CHANNELS = 1; // default is mono recording
-const uint32_t N_PLAY_CHANNELS = 2; // default is stereo playout
+const uint32_t N_REC_CHANNELS = 1; // default is mono recording
+const uint32_t N_PLAY_CHANNELS = 2; // default is stereo playout
const uint32_t N_DEVICE_CHANNELS = 64;
const int kBufferSizeMs = 10;
@@ -46,7 +45,7 @@ const uint32_t ENGINE_PLAY_BUF_SIZE_IN_SAMPLES =
N_PLAY_SAMPLES_PER_SEC * kBufferSizeMs / 1000;
const int N_BLOCKS_IO = 2;
-const int N_BUFFERS_IN = 2; // Must be at least N_BLOCKS_IO.
+const int N_BUFFERS_IN = 2; // Must be at least N_BLOCKS_IO.
const int N_BUFFERS_OUT = 3; // Must be at least N_BLOCKS_IO.
const uint32_t TIMER_PERIOD_MS = 2 * 10 * N_BLOCKS_IO * 1000000;
@@ -58,328 +57,325 @@ const uint32_t PLAY_BUF_SIZE_IN_SAMPLES =
const int kGetMicVolumeIntervalMs = 1000;
-class AudioDeviceMac: public AudioDeviceGeneric
-{
-public:
- AudioDeviceMac(const int32_t id);
- ~AudioDeviceMac();
-
- // Retrieve the currently utilized audio layer
- virtual int32_t
- ActiveAudioLayer(AudioDeviceModule::AudioLayer& audioLayer) const;
-
- // Main initializaton and termination
- virtual int32_t Init();
- virtual int32_t Terminate();
- virtual bool Initialized() const;
-
- // Device enumeration
- virtual int16_t PlayoutDevices();
- virtual int16_t RecordingDevices();
- virtual int32_t PlayoutDeviceName(
- uint16_t index,
- char name[kAdmMaxDeviceNameSize],
- char guid[kAdmMaxGuidSize]);
- virtual int32_t RecordingDeviceName(
- uint16_t index,
- char name[kAdmMaxDeviceNameSize],
- char guid[kAdmMaxGuidSize]);
-
- // Device selection
- virtual int32_t SetPlayoutDevice(uint16_t index);
- virtual int32_t SetPlayoutDevice(
- AudioDeviceModule::WindowsDeviceType device);
- virtual int32_t SetRecordingDevice(uint16_t index);
- virtual int32_t SetRecordingDevice(
- AudioDeviceModule::WindowsDeviceType device);
-
- // Audio transport initialization
- virtual int32_t PlayoutIsAvailable(bool& available);
- virtual int32_t InitPlayout();
- virtual bool PlayoutIsInitialized() const;
- virtual int32_t RecordingIsAvailable(bool& available);
- virtual int32_t InitRecording();
- virtual bool RecordingIsInitialized() const;
-
- // Audio transport control
- virtual int32_t StartPlayout();
- virtual int32_t StopPlayout();
- virtual bool Playing() const;
- virtual int32_t StartRecording();
- virtual int32_t StopRecording();
- virtual bool Recording() const;
-
- // Microphone Automatic Gain Control (AGC)
- virtual int32_t SetAGC(bool enable);
- virtual bool AGC() const;
-
- // Volume control based on the Windows Wave API (Windows only)
- virtual int32_t SetWaveOutVolume(uint16_t volumeLeft, uint16_t volumeRight);
- virtual int32_t WaveOutVolume(uint16_t& volumeLeft,
- uint16_t& volumeRight) const;
-
- // Audio mixer initialization
- virtual int32_t InitSpeaker();
- virtual bool SpeakerIsInitialized() const;
- virtual int32_t InitMicrophone();
- virtual bool MicrophoneIsInitialized() const;
-
- // Speaker volume controls
- virtual int32_t SpeakerVolumeIsAvailable(bool& available);
- virtual int32_t SetSpeakerVolume(uint32_t volume);
- virtual int32_t SpeakerVolume(uint32_t& volume) const;
- virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;
- virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const;
- virtual int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const;
-
- // Microphone volume controls
- virtual int32_t MicrophoneVolumeIsAvailable(bool& available);
- virtual int32_t SetMicrophoneVolume(uint32_t volume);
- virtual int32_t MicrophoneVolume(uint32_t& volume) const;
- virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;
- virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const;
- virtual int32_t
- MicrophoneVolumeStepSize(uint16_t& stepSize) const;
-
- // Microphone mute control
- virtual int32_t MicrophoneMuteIsAvailable(bool& available);
- virtual int32_t SetMicrophoneMute(bool enable);
- virtual int32_t MicrophoneMute(bool& enabled) const;
-
- // Speaker mute control
- virtual int32_t SpeakerMuteIsAvailable(bool& available);
- virtual int32_t SetSpeakerMute(bool enable);
- virtual int32_t SpeakerMute(bool& enabled) const;
-
- // Microphone boost control
- virtual int32_t MicrophoneBoostIsAvailable(bool& available);
- virtual int32_t SetMicrophoneBoost(bool enable);
- virtual int32_t MicrophoneBoost(bool& enabled) const;
-
- // Stereo support
- virtual int32_t StereoPlayoutIsAvailable(bool& available);
- virtual int32_t SetStereoPlayout(bool enable);
- virtual int32_t StereoPlayout(bool& enabled) const;
- virtual int32_t StereoRecordingIsAvailable(bool& available);
- virtual int32_t SetStereoRecording(bool enable);
- virtual int32_t StereoRecording(bool& enabled) const;
-
- // Delay information and control
- virtual int32_t
- SetPlayoutBuffer(const AudioDeviceModule::BufferType type,
- uint16_t sizeMS);
- virtual int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type,
- uint16_t& sizeMS) const;
- virtual int32_t PlayoutDelay(uint16_t& delayMS) const;
- virtual int32_t RecordingDelay(uint16_t& delayMS) const;
-
- // CPU load
- virtual int32_t CPULoad(uint16_t& load) const;
-
- virtual bool PlayoutWarning() const;
- virtual bool PlayoutError() const;
- virtual bool RecordingWarning() const;
- virtual bool RecordingError() const;
- virtual void ClearPlayoutWarning();
- virtual void ClearPlayoutError();
- virtual void ClearRecordingWarning();
- virtual void ClearRecordingError();
-
- virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
-
-private:
- virtual int32_t MicrophoneIsAvailable(bool& available);
- virtual int32_t SpeakerIsAvailable(bool& available);
-
- static void AtomicSet32(int32_t* theValue, int32_t newValue);
- static int32_t AtomicGet32(int32_t* theValue);
-
- static void logCAMsg(const TraceLevel level,
- const TraceModule module,
- const int32_t id, const char *msg,
- const char *err);
-
- int32_t GetNumberDevices(const AudioObjectPropertyScope scope,
- AudioDeviceID scopedDeviceIds[],
- const uint32_t deviceListLength);
-
- int32_t GetDeviceName(const AudioObjectPropertyScope scope,
- const uint16_t index, char* name);
-
- int32_t InitDevice(uint16_t userDeviceIndex,
- AudioDeviceID& deviceId, bool isInput);
-
- // Always work with our preferred playout format inside VoE.
- // Then convert the output to the OS setting using an AudioConverter.
- OSStatus SetDesiredPlayoutFormat();
-
- static OSStatus
- objectListenerProc(AudioObjectID objectId, UInt32 numberAddresses,
- const AudioObjectPropertyAddress addresses[],
- void* clientData);
-
- OSStatus
- implObjectListenerProc(AudioObjectID objectId, UInt32 numberAddresses,
- const AudioObjectPropertyAddress addresses[]);
-
- int32_t HandleDeviceChange();
-
- int32_t
- HandleStreamFormatChange(AudioObjectID objectId,
+class AudioDeviceMac : public AudioDeviceGeneric {
+ public:
+ AudioDeviceMac(const int32_t id);
+ ~AudioDeviceMac();
+
+ // Retrieve the currently utilized audio layer
+ virtual int32_t ActiveAudioLayer(
+ AudioDeviceModule::AudioLayer& audioLayer) const;
+
+ // Main initializaton and termination
+ virtual int32_t Init();
+ virtual int32_t Terminate();
+ virtual bool Initialized() const;
+
+ // Device enumeration
+ virtual int16_t PlayoutDevices();
+ virtual int16_t RecordingDevices();
+ virtual int32_t PlayoutDeviceName(uint16_t index,
+ char name[kAdmMaxDeviceNameSize],
+ char guid[kAdmMaxGuidSize]);
+ virtual int32_t RecordingDeviceName(uint16_t index,
+ char name[kAdmMaxDeviceNameSize],
+ char guid[kAdmMaxGuidSize]);
+
+ // Device selection
+ virtual int32_t SetPlayoutDevice(uint16_t index);
+ virtual int32_t SetPlayoutDevice(AudioDeviceModule::WindowsDeviceType device);
+ virtual int32_t SetRecordingDevice(uint16_t index);
+ virtual int32_t SetRecordingDevice(
+ AudioDeviceModule::WindowsDeviceType device);
+
+ // Audio transport initialization
+ virtual int32_t PlayoutIsAvailable(bool& available);
+ virtual int32_t InitPlayout();
+ virtual bool PlayoutIsInitialized() const;
+ virtual int32_t RecordingIsAvailable(bool& available);
+ virtual int32_t InitRecording();
+ virtual bool RecordingIsInitialized() const;
+
+ // Audio transport control
+ virtual int32_t StartPlayout();
+ virtual int32_t StopPlayout();
+ virtual bool Playing() const;
+ virtual int32_t StartRecording();
+ virtual int32_t StopRecording();
+ virtual bool Recording() const;
+
+ // Microphone Automatic Gain Control (AGC)
+ virtual int32_t SetAGC(bool enable);
+ virtual bool AGC() const;
+
+ // Volume control based on the Windows Wave API (Windows only)
+ virtual int32_t SetWaveOutVolume(uint16_t volumeLeft, uint16_t volumeRight);
+ virtual int32_t WaveOutVolume(uint16_t& volumeLeft,
+ uint16_t& volumeRight) const;
+
+ // Audio mixer initialization
+ virtual int32_t InitSpeaker();
+ virtual bool SpeakerIsInitialized() const;
+ virtual int32_t InitMicrophone();
+ virtual bool MicrophoneIsInitialized() const;
+
+ // Speaker volume controls
+ virtual int32_t SpeakerVolumeIsAvailable(bool& available);
+ virtual int32_t SetSpeakerVolume(uint32_t volume);
+ virtual int32_t SpeakerVolume(uint32_t& volume) const;
+ virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;
+ virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const;
+ virtual int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const;
+
+ // Microphone volume controls
+ virtual int32_t MicrophoneVolumeIsAvailable(bool& available);
+ virtual int32_t SetMicrophoneVolume(uint32_t volume);
+ virtual int32_t MicrophoneVolume(uint32_t& volume) const;
+ virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;
+ virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const;
+ virtual int32_t MicrophoneVolumeStepSize(uint16_t& stepSize) const;
+
+ // Microphone mute control
+ virtual int32_t MicrophoneMuteIsAvailable(bool& available);
+ virtual int32_t SetMicrophoneMute(bool enable);
+ virtual int32_t MicrophoneMute(bool& enabled) const;
+
+ // Speaker mute control
+ virtual int32_t SpeakerMuteIsAvailable(bool& available);
+ virtual int32_t SetSpeakerMute(bool enable);
+ virtual int32_t SpeakerMute(bool& enabled) const;
+
+ // Microphone boost control
+ virtual int32_t MicrophoneBoostIsAvailable(bool& available);
+ virtual int32_t SetMicrophoneBoost(bool enable);
+ virtual int32_t MicrophoneBoost(bool& enabled) const;
+
+ // Stereo support
+ virtual int32_t StereoPlayoutIsAvailable(bool& available);
+ virtual int32_t SetStereoPlayout(bool enable);
+ virtual int32_t StereoPlayout(bool& enabled) const;
+ virtual int32_t StereoRecordingIsAvailable(bool& available);
+ virtual int32_t SetStereoRecording(bool enable);
+ virtual int32_t StereoRecording(bool& enabled) const;
+
+ // Delay information and control
+ virtual int32_t SetPlayoutBuffer(const AudioDeviceModule::BufferType type,
+ uint16_t sizeMS);
+ virtual int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type,
+ uint16_t& sizeMS) const;
+ virtual int32_t PlayoutDelay(uint16_t& delayMS) const;
+ virtual int32_t RecordingDelay(uint16_t& delayMS) const;
+
+ // CPU load
+ virtual int32_t CPULoad(uint16_t& load) const;
+
+ virtual bool PlayoutWarning() const;
+ virtual bool PlayoutError() const;
+ virtual bool RecordingWarning() const;
+ virtual bool RecordingError() const;
+ virtual void ClearPlayoutWarning();
+ virtual void ClearPlayoutError();
+ virtual void ClearRecordingWarning();
+ virtual void ClearRecordingError();
+
+ virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
+
+ private:
+ virtual int32_t MicrophoneIsAvailable(bool& available);
+ virtual int32_t SpeakerIsAvailable(bool& available);
+
+ static void AtomicSet32(int32_t* theValue, int32_t newValue);
+ static int32_t AtomicGet32(int32_t* theValue);
+
+ static void logCAMsg(const TraceLevel level,
+ const TraceModule module,
+ const int32_t id,
+ const char* msg,
+ const char* err);
+
+ int32_t GetNumberDevices(const AudioObjectPropertyScope scope,
+ AudioDeviceID scopedDeviceIds[],
+ const uint32_t deviceListLength);
+
+ int32_t GetDeviceName(const AudioObjectPropertyScope scope,
+ const uint16_t index,
+ char* name);
+
+ int32_t InitDevice(uint16_t userDeviceIndex,
+ AudioDeviceID& deviceId,
+ bool isInput);
+
+ // Always work with our preferred playout format inside VoE.
+ // Then convert the output to the OS setting using an AudioConverter.
+ OSStatus SetDesiredPlayoutFormat();
+
+ static OSStatus objectListenerProc(
+ AudioObjectID objectId,
+ UInt32 numberAddresses,
+ const AudioObjectPropertyAddress addresses[],
+ void* clientData);
+
+ OSStatus implObjectListenerProc(AudioObjectID objectId,
+ UInt32 numberAddresses,
+ const AudioObjectPropertyAddress addresses[]);
+
+ int32_t HandleDeviceChange();
+
+ int32_t HandleStreamFormatChange(AudioObjectID objectId,
+ AudioObjectPropertyAddress propertyAddress);
+
+ int32_t HandleDataSourceChange(AudioObjectID objectId,
AudioObjectPropertyAddress propertyAddress);
- int32_t
- HandleDataSourceChange(AudioObjectID objectId,
- AudioObjectPropertyAddress propertyAddress);
-
- int32_t
- HandleProcessorOverload(AudioObjectPropertyAddress propertyAddress);
-
- static OSStatus deviceIOProc(AudioDeviceID device,
- const AudioTimeStamp *now,
- const AudioBufferList *inputData,
- const AudioTimeStamp *inputTime,
- AudioBufferList *outputData,
+ int32_t HandleProcessorOverload(AudioObjectPropertyAddress propertyAddress);
+
+ static OSStatus deviceIOProc(AudioDeviceID device,
+ const AudioTimeStamp* now,
+ const AudioBufferList* inputData,
+ const AudioTimeStamp* inputTime,
+ AudioBufferList* outputData,
+ const AudioTimeStamp* outputTime,
+ void* clientData);
+
+ static OSStatus outConverterProc(
+ AudioConverterRef audioConverter,
+ UInt32* numberDataPackets,
+ AudioBufferList* data,
+ AudioStreamPacketDescription** dataPacketDescription,
+ void* userData);
+
+ static OSStatus inDeviceIOProc(AudioDeviceID device,
+ const AudioTimeStamp* now,
+ const AudioBufferList* inputData,
+ const AudioTimeStamp* inputTime,
+ AudioBufferList* outputData,
const AudioTimeStamp* outputTime,
- void *clientData);
-
- static OSStatus
- outConverterProc(AudioConverterRef audioConverter,
- UInt32 *numberDataPackets, AudioBufferList *data,
- AudioStreamPacketDescription **dataPacketDescription,
- void *userData);
-
- static OSStatus inDeviceIOProc(AudioDeviceID device,
- const AudioTimeStamp *now,
- const AudioBufferList *inputData,
- const AudioTimeStamp *inputTime,
- AudioBufferList *outputData,
- const AudioTimeStamp *outputTime,
- void *clientData);
+ void* clientData);
- static OSStatus
- inConverterProc(AudioConverterRef audioConverter,
- UInt32 *numberDataPackets, AudioBufferList *data,
- AudioStreamPacketDescription **dataPacketDescription,
- void *inUserData);
+ static OSStatus inConverterProc(
+ AudioConverterRef audioConverter,
+ UInt32* numberDataPackets,
+ AudioBufferList* data,
+ AudioStreamPacketDescription** dataPacketDescription,
+ void* inUserData);
- OSStatus implDeviceIOProc(const AudioBufferList *inputData,
- const AudioTimeStamp *inputTime,
- AudioBufferList *outputData,
- const AudioTimeStamp *outputTime);
+ OSStatus implDeviceIOProc(const AudioBufferList* inputData,
+ const AudioTimeStamp* inputTime,
+ AudioBufferList* outputData,
+ const AudioTimeStamp* outputTime);
- OSStatus implOutConverterProc(UInt32 *numberDataPackets,
- AudioBufferList *data);
+ OSStatus implOutConverterProc(UInt32* numberDataPackets,
+ AudioBufferList* data);
- OSStatus implInDeviceIOProc(const AudioBufferList *inputData,
- const AudioTimeStamp *inputTime);
+ OSStatus implInDeviceIOProc(const AudioBufferList* inputData,
+ const AudioTimeStamp* inputTime);
- OSStatus implInConverterProc(UInt32 *numberDataPackets,
- AudioBufferList *data);
+ OSStatus implInConverterProc(UInt32* numberDataPackets,
+ AudioBufferList* data);
- static bool RunCapture(void*);
- static bool RunRender(void*);
- bool CaptureWorkerThread();
- bool RenderWorkerThread();
+ static bool RunCapture(void*);
+ static bool RunRender(void*);
+ bool CaptureWorkerThread();
+ bool RenderWorkerThread();
- bool KeyPressed();
+ bool KeyPressed();
- AudioDeviceBuffer* _ptrAudioBuffer;
+ AudioDeviceBuffer* _ptrAudioBuffer;
- CriticalSectionWrapper& _critSect;
+ CriticalSectionWrapper& _critSect;
- EventWrapper& _stopEventRec;
- EventWrapper& _stopEvent;
+ EventWrapper& _stopEventRec;
+ EventWrapper& _stopEvent;
- // TODO(pbos): Replace with direct members, just start/stop, no need to
- // recreate the thread.
- // Only valid/running between calls to StartRecording and StopRecording.
- rtc::scoped_ptr<rtc::PlatformThread> capture_worker_thread_;
+ // TODO(pbos): Replace with direct members, just start/stop, no need to
+ // recreate the thread.
+ // Only valid/running between calls to StartRecording and StopRecording.
+ rtc::scoped_ptr<rtc::PlatformThread> capture_worker_thread_;
- // Only valid/running between calls to StartPlayout and StopPlayout.
- rtc::scoped_ptr<rtc::PlatformThread> render_worker_thread_;
+ // Only valid/running between calls to StartPlayout and StopPlayout.
+ rtc::scoped_ptr<rtc::PlatformThread> render_worker_thread_;
- int32_t _id;
+ int32_t _id;
- AudioMixerManagerMac _mixerManager;
+ AudioMixerManagerMac _mixerManager;
- uint16_t _inputDeviceIndex;
- uint16_t _outputDeviceIndex;
- AudioDeviceID _inputDeviceID;
- AudioDeviceID _outputDeviceID;
+ uint16_t _inputDeviceIndex;
+ uint16_t _outputDeviceIndex;
+ AudioDeviceID _inputDeviceID;
+ AudioDeviceID _outputDeviceID;
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
- AudioDeviceIOProcID _inDeviceIOProcID;
- AudioDeviceIOProcID _deviceIOProcID;
+ AudioDeviceIOProcID _inDeviceIOProcID;
+ AudioDeviceIOProcID _deviceIOProcID;
#endif
- bool _inputDeviceIsSpecified;
- bool _outputDeviceIsSpecified;
+ bool _inputDeviceIsSpecified;
+ bool _outputDeviceIsSpecified;
- uint8_t _recChannels;
- uint8_t _playChannels;
+ uint8_t _recChannels;
+ uint8_t _playChannels;
- Float32* _captureBufData;
- SInt16* _renderBufData;
+ Float32* _captureBufData;
+ SInt16* _renderBufData;
- SInt16 _renderConvertData[PLAY_BUF_SIZE_IN_SAMPLES];
+ SInt16 _renderConvertData[PLAY_BUF_SIZE_IN_SAMPLES];
- AudioDeviceModule::BufferType _playBufType;
+ AudioDeviceModule::BufferType _playBufType;
- bool _initialized;
- bool _isShutDown;
- bool _recording;
- bool _playing;
- bool _recIsInitialized;
- bool _playIsInitialized;
- bool _AGC;
+ bool _initialized;
+ bool _isShutDown;
+ bool _recording;
+ bool _playing;
+ bool _recIsInitialized;
+ bool _playIsInitialized;
+ bool _AGC;
- // Atomically set varaibles
- int32_t _renderDeviceIsAlive;
- int32_t _captureDeviceIsAlive;
+ // Atomically set varaibles
+ int32_t _renderDeviceIsAlive;
+ int32_t _captureDeviceIsAlive;
- bool _twoDevices;
- bool _doStop; // For play if not shared device or play+rec if shared device
- bool _doStopRec; // For rec if not shared device
- bool _macBookPro;
- bool _macBookProPanRight;
+ bool _twoDevices;
+ bool _doStop; // For play if not shared device or play+rec if shared device
+ bool _doStopRec; // For rec if not shared device
+ bool _macBookPro;
+ bool _macBookProPanRight;
- AudioConverterRef _captureConverter;
- AudioConverterRef _renderConverter;
+ AudioConverterRef _captureConverter;
+ AudioConverterRef _renderConverter;
- AudioStreamBasicDescription _outStreamFormat;
- AudioStreamBasicDescription _outDesiredFormat;
- AudioStreamBasicDescription _inStreamFormat;
- AudioStreamBasicDescription _inDesiredFormat;
+ AudioStreamBasicDescription _outStreamFormat;
+ AudioStreamBasicDescription _outDesiredFormat;
+ AudioStreamBasicDescription _inStreamFormat;
+ AudioStreamBasicDescription _inDesiredFormat;
- uint32_t _captureLatencyUs;
- uint32_t _renderLatencyUs;
+ uint32_t _captureLatencyUs;
+ uint32_t _renderLatencyUs;
- // Atomically set variables
- mutable int32_t _captureDelayUs;
- mutable int32_t _renderDelayUs;
+ // Atomically set variables
+ mutable int32_t _captureDelayUs;
+ mutable int32_t _renderDelayUs;
- int32_t _renderDelayOffsetSamples;
+ int32_t _renderDelayOffsetSamples;
- uint16_t _playBufDelayFixed; // fixed playback delay
+ uint16_t _playBufDelayFixed; // fixed playback delay
- uint16_t _playWarning;
- uint16_t _playError;
- uint16_t _recWarning;
- uint16_t _recError;
+ uint16_t _playWarning;
+ uint16_t _playError;
+ uint16_t _recWarning;
+ uint16_t _recError;
- PaUtilRingBuffer* _paCaptureBuffer;
- PaUtilRingBuffer* _paRenderBuffer;
+ PaUtilRingBuffer* _paCaptureBuffer;
+ PaUtilRingBuffer* _paRenderBuffer;
- semaphore_t _renderSemaphore;
- semaphore_t _captureSemaphore;
+ semaphore_t _renderSemaphore;
+ semaphore_t _captureSemaphore;
- int _captureBufSizeSamples;
- int _renderBufSizeSamples;
+ int _captureBufSizeSamples;
+ int _renderBufSizeSamples;
- // Typing detection
- // 0x5c is key "9", after that comes function keys.
- bool prev_key_state_[0x5d];
+ // Typing detection
+ // 0x5c is key "9", after that comes function keys.
+ bool prev_key_state_[0x5d];
- int get_mic_volume_counter_ms_;
+ int get_mic_volume_counter_ms_;
};
} // namespace webrtc
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
}
diff --git a/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h b/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h
index 94d6928921..9cbfe2deb4 100644
--- a/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h
+++ b/webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h
@@ -18,63 +18,62 @@
#include <CoreAudio/CoreAudio.h>
namespace webrtc {
-
-class AudioMixerManagerMac
-{
-public:
- int32_t OpenSpeaker(AudioDeviceID deviceID);
- int32_t OpenMicrophone(AudioDeviceID deviceID);
- int32_t SetSpeakerVolume(uint32_t volume);
- int32_t SpeakerVolume(uint32_t& volume) const;
- int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;
- int32_t MinSpeakerVolume(uint32_t& minVolume) const;
- int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const;
- int32_t SpeakerVolumeIsAvailable(bool& available);
- int32_t SpeakerMuteIsAvailable(bool& available);
- int32_t SetSpeakerMute(bool enable);
- int32_t SpeakerMute(bool& enabled) const;
- int32_t StereoPlayoutIsAvailable(bool& available);
- int32_t StereoRecordingIsAvailable(bool& available);
- int32_t MicrophoneMuteIsAvailable(bool& available);
- int32_t SetMicrophoneMute(bool enable);
- int32_t MicrophoneMute(bool& enabled) const;
- int32_t MicrophoneBoostIsAvailable(bool& available);
- int32_t SetMicrophoneBoost(bool enable);
- int32_t MicrophoneBoost(bool& enabled) const;
- int32_t MicrophoneVolumeIsAvailable(bool& available);
- int32_t SetMicrophoneVolume(uint32_t volume);
- int32_t MicrophoneVolume(uint32_t& volume) const;
- int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;
- int32_t MinMicrophoneVolume(uint32_t& minVolume) const;
- int32_t MicrophoneVolumeStepSize(uint16_t& stepSize) const;
- int32_t Close();
- int32_t CloseSpeaker();
- int32_t CloseMicrophone();
- bool SpeakerIsInitialized() const;
- bool MicrophoneIsInitialized() const;
-public:
- AudioMixerManagerMac(const int32_t id);
- ~AudioMixerManagerMac();
+class AudioMixerManagerMac {
+ public:
+ int32_t OpenSpeaker(AudioDeviceID deviceID);
+ int32_t OpenMicrophone(AudioDeviceID deviceID);
+ int32_t SetSpeakerVolume(uint32_t volume);
+ int32_t SpeakerVolume(uint32_t& volume) const;
+ int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;
+ int32_t MinSpeakerVolume(uint32_t& minVolume) const;
+ int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const;
+ int32_t SpeakerVolumeIsAvailable(bool& available);
+ int32_t SpeakerMuteIsAvailable(bool& available);
+ int32_t SetSpeakerMute(bool enable);
+ int32_t SpeakerMute(bool& enabled) const;
+ int32_t StereoPlayoutIsAvailable(bool& available);
+ int32_t StereoRecordingIsAvailable(bool& available);
+ int32_t MicrophoneMuteIsAvailable(bool& available);
+ int32_t SetMicrophoneMute(bool enable);
+ int32_t MicrophoneMute(bool& enabled) const;
+ int32_t MicrophoneBoostIsAvailable(bool& available);
+ int32_t SetMicrophoneBoost(bool enable);
+ int32_t MicrophoneBoost(bool& enabled) const;
+ int32_t MicrophoneVolumeIsAvailable(bool& available);
+ int32_t SetMicrophoneVolume(uint32_t volume);
+ int32_t MicrophoneVolume(uint32_t& volume) const;
+ int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;
+ int32_t MinMicrophoneVolume(uint32_t& minVolume) const;
+ int32_t MicrophoneVolumeStepSize(uint16_t& stepSize) const;
+ int32_t Close();
+ int32_t CloseSpeaker();
+ int32_t CloseMicrophone();
+ bool SpeakerIsInitialized() const;
+ bool MicrophoneIsInitialized() const;
-private:
- static void logCAMsg(const TraceLevel level,
- const TraceModule module,
- const int32_t id, const char *msg,
- const char *err);
+ public:
+ AudioMixerManagerMac(const int32_t id);
+ ~AudioMixerManagerMac();
-private:
- CriticalSectionWrapper& _critSect;
- int32_t _id;
+ private:
+ static void logCAMsg(const TraceLevel level,
+ const TraceModule module,
+ const int32_t id,
+ const char* msg,
+ const char* err);
- AudioDeviceID _inputDeviceID;
- AudioDeviceID _outputDeviceID;
+ private:
+ CriticalSectionWrapper& _critSect;
+ int32_t _id;
- uint16_t _noInputChannels;
- uint16_t _noOutputChannels;
+ AudioDeviceID _inputDeviceID;
+ AudioDeviceID _outputDeviceID;
+ uint16_t _noInputChannels;
+ uint16_t _noOutputChannels;
};
-
+
} // namespace webrtc
#endif // AUDIO_MIXER_MAC_H