/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/audio_device/audio_device_config.h"
#include "webrtc/modules/audio_device/audio_device_utility.h"
#include "webrtc/modules/audio_device/mac/audio_device_mac.h"

#include "webrtc/modules/audio_device/mac/portaudio/pa_ringbuffer.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"

#include <ApplicationServices/ApplicationServices.h>
#include <assert.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)

#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[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;
        }
    }
}

// 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)
{
    assert(msg != NULL);
    assert(err != NULL);

#ifdef WEBRTC_ARCH_BIG_ENDIAN
    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);
#endif
}

AudioDeviceMac::AudioDeviceMac(const int32_t id) :
    _ptrAudioBuffer(NULL),
    _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
    _stopEventRec(*EventWrapper::Create()),
    _stopEvent(*EventWrapper::Create()),
    _captureWorkerThread(NULL),
    _renderWorkerThread(NULL),
    _captureWorkerThreadId(0),
    _renderWorkerThreadId(0),
    _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_()
{
    WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id,
                 "%s created", __FUNCTION__);

    assert(&_stopEvent != NULL);
    assert(&_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();
    }

    if (_captureWorkerThread)
    {
        delete _captureWorkerThread;
        _captureWorkerThread = NULL;
    }

    if (_renderWorkerThread)
    {
        delete _renderWorkerThread;
        _renderWorkerThread = NULL;
    }

    if (_paRenderBuffer)
    {
        delete _paRenderBuffer;
        _paRenderBuffer = NULL;
    }

    if (_paCaptureBuffer)
    {
        delete _paCaptureBuffer;
        _paCaptureBuffer = NULL;
    }

    if (_renderBufData)
    {
        delete[] _renderBufData;
        _renderBufData = 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);
    }

    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;
}

// ============================================================================
//                                     API
// ============================================================================

void AudioDeviceMac::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer)
{

    CriticalSectionScoped lock(&_critSect);

    _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);
}

int32_t AudioDeviceMac::ActiveAudioLayer(
    AudioDeviceModule::AudioLayer& audioLayer) const
{
    audioLayer = AudioDeviceModule::kPlatformDefaultAudio;
    return 0;
}

int32_t AudioDeviceMac::Init()
{

    CriticalSectionScoped lock(&_critSect);

    if (_initialized)
    {
        return 0;
    }

    OSStatus err = noErr;

    _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];
    }

    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 (_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 (_renderWorkerThread == NULL)
    {
        _renderWorkerThread
            = ThreadWrapper::CreateThread(RunRender, this, kRealtimePriority,
                                          "RenderWorkerThread");
        if (_renderWorkerThread == NULL)
        {
            WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice,
                         _id, " Render CreateThread() error");
            return -1;
        }
    }

    if (_captureWorkerThread == NULL)
    {
        _captureWorkerThread
            = ThreadWrapper::CreateThread(RunCapture, this, kRealtimePriority,
                                          "CaptureWorkerThread");
        if (_captureWorkerThread == NULL)
        {
            WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice,
                         _id, " Capture CreateThread() 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;
    }

    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;
        }
    }

    _playWarning = 0;
    _playError = 0;
    _recWarning = 0;
    _recError = 0;

    _initialized = true;

    return 0;
}

int32_t AudioDeviceMac::Terminate()
{

    if (!_initialized)
    {
        return 0;
    }

    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;
    }

    _critSect.Enter();

    _mixerManager.Close();

    OSStatus err = noErr;
    int retVal = 0;

    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;
    }

    _critSect.Leave();

    _isShutDown = true;
    _initialized = false;
    _outputDeviceIsSpecified = false;
    _inputDeviceIsSpecified = false;

    return retVal;
}

bool AudioDeviceMac::Initialized() const
{
    return (_initialized);
}

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;
    }

    // Given that InitSpeaker was successful, we know that a valid speaker
    // exists.
    available = true;

    // Close the initialized output mixer
    //
    if (!wasInitialized)
    {
        _mixerManager.CloseSpeaker();
    }

    return 0;
}

int32_t AudioDeviceMac::InitSpeaker()
{

    CriticalSectionScoped lock(&_critSect);

    if (_playing)
    {
        return -1;
    }

    if (InitDevice(_outputDeviceIndex, _outputDeviceID, false) == -1)
    {
        return -1;
    }

    if (_inputDeviceID == _outputDeviceID)
    {
        _twoDevices = false;
    } else
    {
        _twoDevices = true;
    }

    if (_mixerManager.OpenSpeaker(_outputDeviceID) == -1)
    {
        return -1;
    }

    return 0;
}

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;
    }

    // Given that InitMicrophone was successful, we know that a valid microphone
    // exists.
    available = true;

    // Close the initialized input mixer
    //
    if (!wasInitialized)
    {
        _mixerManager.CloseMicrophone();
    }

    return 0;
}

int32_t AudioDeviceMac::InitMicrophone()
{

    CriticalSectionScoped lock(&_critSect);

    if (_recording)
    {
        return -1;
    }

    if (InitDevice(_inputDeviceIndex, _inputDeviceID, true) == -1)
    {
        return -1;
    }

    if (_inputDeviceID == _outputDeviceID)
    {
        _twoDevices = false;
    } else
    {
        _twoDevices = true;
    }

    if (_mixerManager.OpenMicrophone(_inputDeviceID) == -1)
    {
        return -1;
    }

    return 0;
}

bool AudioDeviceMac::SpeakerIsInitialized() const
{
    return (_mixerManager.SpeakerIsInitialized());
}

bool AudioDeviceMac::MicrophoneIsInitialized() const
{
    return (_mixerManager.MicrophoneIsInitialized());
}

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;
    }

    // Given that InitSpeaker was successful, we know that a volume control exists
    //
    available = true;

    // Close the initialized output mixer
    //
    if (!wasInitialized)
    {
        _mixerManager.CloseSpeaker();
    }

    return 0;
}

int32_t AudioDeviceMac::SetSpeakerVolume(uint32_t volume)
{

    return (_mixerManager.SetSpeakerVolume(volume));
}

int32_t AudioDeviceMac::SpeakerVolume(uint32_t& volume) const
{

    uint32_t level(0);

    if (_mixerManager.SpeakerVolume(level) == -1)
    {
        return -1;
    }

    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;
}

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
{

    uint32_t maxVol(0);

    if (_mixerManager.MaxSpeakerVolume(maxVol) == -1)
    {
        return -1;
    }

    maxVolume = maxVol;
    return 0;
}

int32_t AudioDeviceMac::MinSpeakerVolume(uint32_t& minVolume) const
{

    uint32_t minVol(0);

    if (_mixerManager.MinSpeakerVolume(minVol) == -1)
    {
        return -1;
    }

    minVolume = minVol;
    return 0;
}

int32_t
AudioDeviceMac::SpeakerVolumeStepSize(uint16_t& stepSize) const
{

    uint16_t delta(0);

    if (_mixerManager.SpeakerVolumeStepSize(delta) == -1)
    {
        return -1;
    }

    stepSize = delta;
    return 0;
}

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;
    }

    // Check if the selected speaker has a mute control
    //
    _mixerManager.SpeakerMuteIsAvailable(isAvailable);

    available = isAvailable;

    // Close the initialized output mixer
    //
    if (!wasInitialized)
    {
        _mixerManager.CloseSpeaker();
    }

    return 0;
}

int32_t AudioDeviceMac::SetSpeakerMute(bool enable)
{
    return (_mixerManager.SetSpeakerMute(enable));
}

int32_t AudioDeviceMac::SpeakerMute(bool& enabled) const
{

    bool muted(0);

    if (_mixerManager.SpeakerMute(muted) == -1)
    {
        return -1;
    }

    enabled = muted;
    return 0;
}

int32_t AudioDeviceMac::MicrophoneMuteIsAvailable(bool& available)
{

    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;
    }

    // Check if the selected microphone has a mute control
    //
    _mixerManager.MicrophoneMuteIsAvailable(isAvailable);
    available = isAvailable;

    // Close the initialized input mixer
    //
    if (!wasInitialized)
    {
        _mixerManager.CloseMicrophone();
    }

    return 0;
}

int32_t AudioDeviceMac::SetMicrophoneMute(bool enable)
{
    return (_mixerManager.SetMicrophoneMute(enable));
}

int32_t AudioDeviceMac::MicrophoneMute(bool& enabled) const
{

    bool muted(0);

    if (_mixerManager.MicrophoneMute(muted) == -1)
    {
        return -1;
    }

    enabled = muted;
    return 0;
}

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;
    }

    // Check if the selected microphone has a boost control
    //
    _mixerManager.MicrophoneBoostIsAvailable(isAvailable);
    available = isAvailable;

    // Close the initialized input mixer
    //
    if (!wasInitialized)
    {
        _mixerManager.CloseMicrophone();
    }

    return 0;
}

int32_t AudioDeviceMac::SetMicrophoneBoost(bool enable)
{

    return (_mixerManager.SetMicrophoneBoost(enable));
}

int32_t AudioDeviceMac::MicrophoneBoost(bool& enabled) const
{

    bool onOff(0);

    if (_mixerManager.MicrophoneBoost(onOff) == -1)
    {
        return -1;
    }

    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();
    }

    return 0;
}

int32_t AudioDeviceMac::SetStereoRecording(bool enable)
{

    if (enable)
        _recChannels = 2;
    else
        _recChannels = 1;

    return 0;
}

int32_t AudioDeviceMac::StereoRecording(bool& enabled) const
{

    if (_recChannels == 2)
        enabled = true;
    else
        enabled = false;

    return 0;
}

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;
    }

    // Check if the selected microphone can record stereo
    //
    _mixerManager.StereoPlayoutIsAvailable(isAvailable);
    available = isAvailable;

    // Close the initialized input mixer
    //
    if (!wasInitialized)
    {
        _mixerManager.CloseSpeaker();
    }

    return 0;
}

int32_t AudioDeviceMac::SetStereoPlayout(bool enable)
{

    if (enable)
        _playChannels = 2;
    else
        _playChannels = 1;

    return 0;
}

int32_t AudioDeviceMac::StereoPlayout(bool& enabled) const
{

    if (_playChannels == 2)
        enabled = true;
    else
        enabled = false;

    return 0;
}

int32_t AudioDeviceMac::SetAGC(bool enable)
{

    _AGC = enable;

    return 0;
}

bool AudioDeviceMac::AGC() const
{

    return _AGC;
}

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;
    }

    // Given that InitMicrophone was successful, we know that a volume control
    // exists
    //
    available = true;

    // Close the initialized input mixer
    //
    if (!wasInitialized)
    {
        _mixerManager.CloseMicrophone();
    }

    return 0;
}

int32_t AudioDeviceMac::SetMicrophoneVolume(uint32_t volume)
{

    return (_mixerManager.SetMicrophoneVolume(volume));
}

int32_t AudioDeviceMac::MicrophoneVolume(uint32_t& volume) const
{

    uint32_t level(0);

    if (_mixerManager.MicrophoneVolume(level) == -1)
    {
        WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
                     "  failed to retrive current microphone level");
        return -1;
    }

    volume = level;
    return 0;
}

int32_t
AudioDeviceMac::MaxMicrophoneVolume(uint32_t& maxVolume) const
{

    uint32_t maxVol(0);

    if (_mixerManager.MaxMicrophoneVolume(maxVol) == -1)
    {
        return -1;
    }

    maxVolume = maxVol;
    return 0;
}

int32_t
AudioDeviceMac::MinMicrophoneVolume(uint32_t& minVolume) const
{

    uint32_t minVol(0);

    if (_mixerManager.MinMicrophoneVolume(minVol) == -1)
    {
        return -1;
    }

    minVolume = minVol;
    return 0;
}

int32_t
AudioDeviceMac::MicrophoneVolumeStepSize(uint16_t& stepSize) const
{

    uint16_t delta(0);

    if (_mixerManager.MicrophoneVolumeStepSize(delta) == -1)
    {
        return -1;
    }

    stepSize = delta;
    return 0;
}

int16_t AudioDeviceMac::PlayoutDevices()
{

    AudioDeviceID playDevices[MaxNumberDevices];
    return GetNumberDevices(kAudioDevicePropertyScopeOutput, playDevices,
                            MaxNumberDevices);
}

int32_t AudioDeviceMac::SetPlayoutDevice(uint16_t index)
{

    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;
    }

    _outputDeviceIndex = index;
    _outputDeviceIsSpecified = true;

    return 0;
}

int32_t AudioDeviceMac::SetPlayoutDevice(
    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])
{

    const uint16_t nDevices(PlayoutDevices());

    if ((index > (nDevices - 1)) || (name == NULL))
    {
        return -1;
    }

    memset(name, 0, kAdmMaxDeviceNameSize);

    if (guid != NULL)
    {
        memset(guid, 0, kAdmMaxGuidSize);
    }

    return GetDeviceName(kAudioDevicePropertyScopeOutput, index, name);
}

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;
    }

    memset(name, 0, kAdmMaxDeviceNameSize);

    if (guid != NULL)
    {
        memset(guid, 0, kAdmMaxGuidSize);
    }

    return GetDeviceName(kAudioDevicePropertyScopeInput, index, name);
}

int16_t AudioDeviceMac::RecordingDevices()
{

    AudioDeviceID recDevices[MaxNumberDevices];
    return GetNumberDevices(kAudioDevicePropertyScopeInput, recDevices,
                            MaxNumberDevices);
}

int32_t AudioDeviceMac::SetRecordingDevice(uint16_t index)
{

    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);

    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;

    return 0;
}


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;

    // 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;
    }

    // Cancel effect of initialization
    if (StopPlayout() == -1)
    {
        available = false;
    }

    return 0;
}

int32_t AudioDeviceMac::RecordingIsAvailable(bool& available)
{

    available = true;

    // 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;
    }

    // Cancel effect of initialization
    if (StopRecording() == -1)
    {
        available = false;
    }

    return 0;
}

int32_t AudioDeviceMac::InitPlayout()
{

    CriticalSectionScoped lock(&_critSect);

    if (_playing)
    {
        return -1;
    }

    if (!_outputDeviceIsSpecified)
    {
        return -1;
    }

    if (_playIsInitialized)
    {
        return 0;
    }

    // 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");
        }
    }

    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");
            }

            // 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;
    }

    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;
    }

    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
    _outDesiredFormat.mSampleRate = N_PLAY_SAMPLES_PER_SEC;
    if (_outStreamFormat.mChannelsPerFrame >= 2 && (_playChannels == 2))
    {
        _outDesiredFormat.mChannelsPerFrame = 2;
    } else
    {
        // Disable stereo playout when we only have one channel on the device.
        _outDesiredFormat.mChannelsPerFrame = 1;
        _playChannels = 1;
        WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
                     "Stereo playout unavailable on this device");
    }

    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;

    _outDesiredFormat.mBytesPerPacket = _outDesiredFormat.mChannelsPerFrame
        * sizeof(SInt16);
    _outDesiredFormat.mFramesPerPacket = 1; // In uncompressed audio,
    // a packet is one frame.
    _outDesiredFormat.mBytesPerFrame = _outDesiredFormat.mChannelsPerFrame
        * sizeof(SInt16);
    _outDesiredFormat.mBitsPerChannel = sizeof(SInt16) * 8;

    _outDesiredFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
        | kLinearPCMFormatFlagIsPacked;
#ifdef WEBRTC_ARCH_BIG_ENDIAN
    _outDesiredFormat.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
#endif
    _outDesiredFormat.mFormatID = kAudioFormatLinearPCM;

    WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(&_outDesiredFormat, &_outStreamFormat,
            &_renderConverter));

    // First try to set buffer size to desired value (_playBufDelayFixed)
    UInt32 bufByteCount = (UInt32)((_outStreamFormat.mSampleRate / 1000.0)
        * _playBufDelayFixed * _outStreamFormat.mChannelsPerFrame
        * sizeof(Float32));
    if (_outStreamFormat.mFramesPerPacket != 0)
    {
        if (bufByteCount % _outStreamFormat.mFramesPerPacket != 0)
        {
            bufByteCount = ((UInt32)(bufByteCount
                / _outStreamFormat.mFramesPerPacket) + 1)
                * _outStreamFormat.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(_outputDeviceID,
            &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(_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 = (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 += (uint32_t) ((1.0e6 * latency)
        / _outStreamFormat.mSampleRate);

    // 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));
    }

    // Mark playout side as initialized
    _playIsInitialized = true;

    WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
                 "  initial playout status: _renderDelayOffsetSamples=%d,"
                 " _renderDelayUs=%d, _renderLatencyUs=%d",
                 _renderDelayOffsetSamples, _renderDelayUs, _renderLatencyUs);

    return 0;
}

int32_t AudioDeviceMac::InitRecording()
{

    CriticalSectionScoped lock(&_critSect);

    if (_recording)
    {
        return -1;
    }

    if (!_inputDeviceIsSpecified)
    {
        return -1;
    }

    if (_recIsInitialized)
    {
        return 0;
    }

    // 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");
        }
    }

    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;
    }

    if (_inStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS)
    {
        WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
            "Too many channels on input device (mChannelsPerFrame = %d)",
            _inStreamFormat.mChannelsPerFrame);
        return -1;
    }

    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.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
        | kLinearPCMFormatFlagIsPacked;
#ifdef WEBRTC_ARCH_BIG_ENDIAN
    _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;
        }
    }

    // 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));
    }

    // Mark recording side as initialized
    _recIsInitialized = true;

    return 0;
}

int32_t AudioDeviceMac::StartRecording()
{

    CriticalSectionScoped lock(&_critSect);

    if (!_recIsInitialized)
    {
        return -1;
    }

    if (_recording)
    {
        return 0;
    }

    if (!_initialized)
    {
        WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
                     " Recording worker thread has not been started");
        return -1;
    }

    OSStatus err = noErr;

    unsigned int threadID(0);
    if (_captureWorkerThread != NULL)
    {
        _captureWorkerThread->Start(threadID);
    }
    _captureWorkerThreadId = threadID;

    if (_twoDevices)
    {
        WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _inDeviceIOProcID));
    } else if (!_playing)
    {
        WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _deviceIOProcID));
    }

    _recording = true;

    return 0;
}

int32_t AudioDeviceMac::StopRecording()
{

    CriticalSectionScoped lock(&_critSect);

    if (!_recIsInitialized)
    {
        return 0;
    }

    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);
    _critSect.Leave();
    if (_captureWorkerThread != NULL)
    {
        if (!_captureWorkerThread->Stop())
        {
            WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
                         " Timed out waiting for the render worker thread to "
                             "stop.");
        }
    }
    _critSect.Enter();

    WEBRTC_CA_LOG_WARN(AudioConverterDispose(_captureConverter));

    // 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));

    _recIsInitialized = false;
    _recording = false;

    return 0;
}

bool AudioDeviceMac::RecordingIsInitialized() const
{
    return (_recIsInitialized);
}

bool AudioDeviceMac::Recording() const
{
    return (_recording);
}

bool AudioDeviceMac::PlayoutIsInitialized() const
{
    return (_playIsInitialized);
}

int32_t AudioDeviceMac::StartPlayout()
{

    CriticalSectionScoped lock(&_critSect);

    if (!_playIsInitialized)
    {
        return -1;
    }

    if (_playing)
    {
        return 0;
    }

    OSStatus err = noErr;

    unsigned int threadID(0);
    if (_renderWorkerThread != NULL)
    {
        _renderWorkerThread->Start(threadID);
    }
    _renderWorkerThreadId = threadID;

    if (_twoDevices || !_recording)
    {
        WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_outputDeviceID, _deviceIOProcID));
    }
    _playing = true;

    return 0;
}

int32_t AudioDeviceMac::StopPlayout()
{

    CriticalSectionScoped lock(&_critSect);

    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");
    }

    // Setting this signal will allow the worker thread to be stopped.
    AtomicSet32(&_renderDeviceIsAlive, 0);
    _critSect.Leave();
    if (_renderWorkerThread != NULL)
    {
        if (!_renderWorkerThread->Stop())
        {
            WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
                         " Timed out waiting for the render worker thread to "
                         "stop.");
        }
    }
    _critSect.Enter();

    WEBRTC_CA_LOG_WARN(AudioConverterDispose(_renderConverter));

    // 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));
        }
    }

    _playIsInitialized = false;
    _playing = false;

    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;
}

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;
    }

    _playBufType = type;
    _playBufDelayFixed = sizeMS;
    return 0;
}

int32_t AudioDeviceMac::PlayoutBuffer(
    AudioDeviceModule::BufferType& type,
    uint16_t& sizeMS) const
{

    type = _playBufType;
    sizeMS = _playBufDelayFixed;

    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");

    return -1;
}

bool AudioDeviceMac::PlayoutWarning() const
{
    return (_playWarning > 0);
}

bool AudioDeviceMac::PlayoutError() const
{
    return (_playError > 0);
}

bool AudioDeviceMac::RecordingWarning() const
{
    return (_recWarning > 0);
}

bool AudioDeviceMac::RecordingError() const
{
    return (_recError > 0);
}

void AudioDeviceMac::ClearPlayoutWarning()
{
    _playWarning = 0;
}

void AudioDeviceMac::ClearPlayoutError()
{
    _playError = 0;
}

void AudioDeviceMac::ClearRecordingWarning()
{
    _recWarning = 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;

    // 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");
    }

    // Then list the rest of the devices
    bool listOK = true;

    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;
                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
    }

    if (!listOK)
    {
        if (deviceIds)
        {
            free(deviceIds);
            deviceIds = NULL;
        }

        if (bufferList)
        {
            free(bufferList);
            bufferList = NULL;
        }

        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;
    }

    // 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;
        }
    }

    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;
        }

        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;
    }

    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;
    }

    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;
        }
    }

    if (!isDefaultDevice)
    {
        deviceId = deviceIds[userDeviceIndex];
    }

    // 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;
}

OSStatus AudioDeviceMac::objectListenerProc(
    AudioObjectID objectId,
    UInt32 numberAddresses,
    const AudioObjectPropertyAddress addresses[],
    void* clientData)
{
    AudioDeviceMac *ptrThis = (AudioDeviceMac *) clientData;
    assert(ptrThis != NULL);

    ptrThis->implObjectListenerProc(objectId, numberAddresses, addresses);

    // 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]);
        }
    }

    return 0;
}

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;
        }
    }

    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;
}

int32_t AudioDeviceMac::HandleStreamFormatChange(
    const AudioObjectID objectId,
    const AudioObjectPropertyAddress propertyAddress)
{
    OSStatus err = noErr;

    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;
    }

    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));

        if (_outStreamFormat.mChannelsPerFrame >= 2 && (_playChannels == 2))
        {
            _outDesiredFormat.mChannelsPerFrame = 2;
        } else
        {
            // Disable stereo playout when we only have one channel on the device.
            _outDesiredFormat.mChannelsPerFrame = 1;
            _playChannels = 1;
            WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
                         "Stereo playout unavailable on this device");
        }

        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;

        // Recreate the converter with the new format
        // TODO(xians): make this thread safe
        WEBRTC_CA_RETURN_ON_ERR(AudioConverterDispose(_renderConverter));

        WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(&_outDesiredFormat, &streamFormat,
                &_renderConverter));
    }

    return 0;
}

int32_t AudioDeviceMac::HandleDataSourceChange(
    const AudioObjectID objectId,
    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");
        }
    }

    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);
    }

    return 0;
}

// ============================================================================
//                                  Thread Methods
// ============================================================================

OSStatus AudioDeviceMac::deviceIOProc(AudioDeviceID, const AudioTimeStamp*,
                                      const AudioBufferList* inputData,
                                      const AudioTimeStamp* inputTime,
                                      AudioBufferList* outputData,
                                      const AudioTimeStamp* outputTime,
                                      void *clientData)
{
    AudioDeviceMac *ptrThis = (AudioDeviceMac *) clientData;
    assert(ptrThis != NULL);

    ptrThis->implDeviceIOProc(inputData, inputTime, outputData, outputTime);

    // AudioDeviceIOProc functions are supposed to return 0
    return 0;
}

OSStatus AudioDeviceMac::outConverterProc(AudioConverterRef,
                                          UInt32 *numberDataPackets,
                                          AudioBufferList *data,
                                          AudioStreamPacketDescription **,
                                          void *userData)
{
    AudioDeviceMac *ptrThis = (AudioDeviceMac *) userData;
    assert(ptrThis != NULL);

    return ptrThis->implOutConverterProc(numberDataPackets, data);
}

OSStatus AudioDeviceMac::inDeviceIOProc(AudioDeviceID, const AudioTimeStamp*,
                                        const AudioBufferList* inputData,
                                        const AudioTimeStamp* inputTime,
                                        AudioBufferList*,
                                        const AudioTimeStamp*, void* clientData)
{
    AudioDeviceMac *ptrThis = (AudioDeviceMac *) clientData;
    assert(ptrThis != NULL);

    ptrThis->implInDeviceIOProc(inputData, inputTime);

    // 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);
    assert(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;
        }
        _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;
    }

    assert(_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);

    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);

    return 0;
}

OSStatus AudioDeviceMac::implOutConverterProc(UInt32 *numberDataPackets,
                                              AudioBufferList *data)
{
    assert(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;
    }

    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();
    }

    if (!_recording)
    {
        // Allow above checks to avoid a timeout on stopping capture.
        return 0;
    }

    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);

    assert(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;
}

OSStatus AudioDeviceMac::implInConverterProc(UInt32 *numberDataPackets,
                                             AudioBufferList *data)
{
    assert(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);
        }
    }

    // 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);
        }
    }

    int8_t playBuffer[4 * ENGINE_PLAY_BUF_SIZE_IN_SAMPLES];

    if (!_ptrAudioBuffer)
    {
        WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
                     "  capture AudioBuffer is invalid");
        return false;
    }

    // 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);

    return true;
}

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;
        }
    }

    // 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;
        }

        // 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())
        {
            // 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);
            }
        }

        _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;
}

bool AudioDeviceMac::KeyPressed() {
  bool key_down = false;
  // Loop through all Mac virtual key constant values.
  for (unsigned int key_index = 0;
                    key_index < ARRAY_SIZE(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.
    prev_key_state_[key_index] = keyState;
  }
  return key_down;
}
}  // namespace webrtc
