/*
 *  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/base/arraysize.h"
#include "webrtc/base/checks.h"
#include "webrtc/modules/audio_device/audio_device_config.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 <libkern/OSAtomic.h>   // OSAtomicCompareAndSwap()
#include <mach/mach.h>          // mach_task_self()
#include <sys/sysctl.h>         // sysctlbyname()



namespace webrtc
{

#define WEBRTC_CA_RETURN_ON_ERR(expr)                                   \
    do {                                                                \
        err = expr;                                                     \
        if (err != noErr) {                                             \
            logCAMsg(kTraceError, kTraceAudioDevice, _id,               \
                "Error in " #expr, (const char *)&err);                 \
            return -1;                                                  \
        }                                                               \
    } while(0)

#define WEBRTC_CA_LOG_ERR(expr)                                         \
    do {                                                                \
        err = expr;                                                     \
        if (err != noErr) {                                             \
            logCAMsg(kTraceError, kTraceAudioDevice, _id,               \
                "Error in " #expr, (const char *)&err);                 \
        }                                                               \
    } while(0)

#define WEBRTC_CA_LOG_WARN(expr)                                        \
    do {                                                                \
        err = expr;                                                     \
        if (err != noErr) {                                             \
            logCAMsg(kTraceWarning, kTraceAudioDevice, _id,             \
                "Error in " #expr, (const char *)&err);                 \
        }                                                               \
    } while(0)

enum
{
    MaxNumberDevices = 64
};

void AudioDeviceMac::AtomicSet32(int32_t* theValue, int32_t newValue)
{
    while (1)
    {
        int32_t oldValue = *theValue;
        if (OSAtomicCompareAndSwap32Barrier(oldValue, newValue, theValue)
            == true)
        {
            return;
        }
    }
}

int32_t AudioDeviceMac::AtomicGet32(int32_t* theValue)
{
    while (1)
    {
        int32_t value = *theValue;
        if (OSAtomicCompareAndSwap32Barrier(value, value, theValue) == true)
        {
            return value;
        }
    }
}

// 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)
{
  RTC_DCHECK(msg != NULL);
  RTC_DCHECK(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()),
    _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__);

    RTC_DCHECK(&_stopEvent != NULL);
    RTC_DCHECK(&_stopEventRec != NULL);

    memset(_renderConvertData, 0, sizeof(_renderConvertData));
    memset(&_outStreamFormat, 0, sizeof(AudioStreamBasicDescription));
    memset(&_outDesiredFormat, 0, sizeof(AudioStreamBasicDescription));
    memset(&_inStreamFormat, 0, sizeof(AudioStreamBasicDescription));
    memset(&_inDesiredFormat, 0, sizeof(AudioStreamBasicDescription));
}


AudioDeviceMac::~AudioDeviceMac()
{
    WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id,
                 "%s destroyed", __FUNCTION__);

    if (!_isShutDown)
    {
        Terminate();
    }

    RTC_DCHECK(!capture_worker_thread_.get());
    RTC_DCHECK(!render_worker_thread_.get());

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

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

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

    _critSect.Leave();

    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)
{
    CriticalSectionScoped lock(&_critSect);

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

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

    _playIsInitialized = true;

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

    RTC_DCHECK(!capture_worker_thread_.get());
    capture_worker_thread_ =
        ThreadWrapper::CreateThread(RunCapture, this, "CaptureWorkerThread");
    RTC_DCHECK(capture_worker_thread_.get());
    capture_worker_thread_->Start();
    capture_worker_thread_->SetPriority(kRealtimePriority);

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

    _recording = true;

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

    if (capture_worker_thread_.get()) {
        _critSect.Leave();
        capture_worker_thread_->Stop();
        capture_worker_thread_.reset();
        _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;
    }

    RTC_DCHECK(!render_worker_thread_.get());
    render_worker_thread_ =
        ThreadWrapper::CreateThread(RunRender, this, "RenderWorkerThread");
    render_worker_thread_->Start();
    render_worker_thread_->SetPriority(kRealtimePriority);

    if (_twoDevices || !_recording)
    {
        OSStatus err = noErr;
        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);
    if (render_worker_thread_.get()) {
        _critSect.Leave();
        render_worker_thread_->Stop();
        render_worker_thread_.reset();
        _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::SetDesiredPlayoutFormat()
{
    // Our preferred format to work with.
    _outDesiredFormat.mSampleRate = N_PLAY_SAMPLES_PER_SEC;
    _outDesiredFormat.mChannelsPerFrame = _playChannels;

    if (_ptrAudioBuffer)
    {
        // Update audio buffer with the selected parameters.
        _ptrAudioBuffer->SetPlayoutSampleRate(N_PLAY_SAMPLES_PER_SEC);
        _ptrAudioBuffer->SetPlayoutChannels((uint8_t) _playChannels);
    }

    _renderDelayOffsetSamples = _renderBufSizeSamples - N_BUFFERS_OUT *
        ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * _outDesiredFormat.mChannelsPerFrame;

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

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

    OSStatus err = noErr;
    WEBRTC_CA_RETURN_ON_ERR(AudioConverterNew(&_outDesiredFormat,
                                              &_outStreamFormat,
                                              &_renderConverter));

    // Try to set buffer size to desired value (_playBufDelayFixed).
    UInt32 bufByteCount = static_cast<UInt32> ((_outStreamFormat.mSampleRate /
                          1000.0) *
                          _playBufDelayFixed *
                          _outStreamFormat.mChannelsPerFrame *
                          sizeof(Float32));
    if (_outStreamFormat.mFramesPerPacket != 0)
    {
        if (bufByteCount % _outStreamFormat.mFramesPerPacket != 0)
        {
            bufByteCount = (static_cast<UInt32> (bufByteCount /
                           _outStreamFormat.mFramesPerPacket) + 1) *
                           _outStreamFormat.mFramesPerPacket;
        }
    }

    // Ensure the buffer size is within the range provided by the device.
    AudioObjectPropertyAddress propertyAddress =
        {kAudioDevicePropertyDataSource,
         kAudioDevicePropertyScopeOutput,
         0};
    propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange;
    AudioValueRange range;
    UInt32 size = sizeof(range);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
                                                       &propertyAddress,
                                                       0,
                                                       NULL,
                                                       &size,
                                                       &range));
    if (range.mMinimum > bufByteCount)
    {
        bufByteCount = range.mMinimum;
    } else if (range.mMaximum < bufByteCount)
    {
        bufByteCount = range.mMaximum;
    }

    propertyAddress.mSelector = kAudioDevicePropertyBufferSize;
    size = sizeof(bufByteCount);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(_outputDeviceID,
                                                       &propertyAddress,
                                                       0,
                                                       NULL,
                                                       size,
                                                       &bufByteCount));

    // Get render device latency.
    propertyAddress.mSelector = kAudioDevicePropertyLatency;
    UInt32 latency = 0;
    size = sizeof(UInt32);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
                                                       &propertyAddress,
                                                       0,
                                                       NULL,
                                                       &size,
                                                       &latency));
    _renderLatencyUs = static_cast<uint32_t> ((1.0e6 * latency) /
                       _outStreamFormat.mSampleRate);

    // Get render stream latency.
    propertyAddress.mSelector = kAudioDevicePropertyStreams;
    AudioStreamID stream = 0;
    size = sizeof(AudioStreamID);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
                                                       &propertyAddress,
                                                       0,
                                                       NULL,
                                                       &size,
                                                       &stream));
    propertyAddress.mSelector = kAudioStreamPropertyLatency;
    size = sizeof(UInt32);
    latency = 0;
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(_outputDeviceID,
                                                       &propertyAddress,
                                                       0,
                                                       NULL,
                                                       &size,
                                                       &latency));
    _renderLatencyUs += static_cast<uint32_t> ((1.0e6 * latency) /
                        _outStreamFormat.mSampleRate);

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

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

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

        // Our preferred format to work with
        if (_outStreamFormat.mChannelsPerFrame < 2)
        {
            _playChannels = 1;
            WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
                         "Stereo playout unavailable on this device");
        }
        WEBRTC_CA_RETURN_ON_ERR(SetDesiredPlayoutFormat());
    }
    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;
    RTC_DCHECK(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;
    RTC_DCHECK(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;
    RTC_DCHECK(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);
    RTC_DCHECK(ptrThis != NULL);

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

OSStatus AudioDeviceMac::implDeviceIOProc(const AudioBufferList *inputData,
                                          const AudioTimeStamp *inputTime,
                                          AudioBufferList *outputData,
                                          const AudioTimeStamp *outputTime)
{
    OSStatus err = noErr;
    UInt64 outputTimeNs = AudioConvertHostTimeToNanos(outputTime->mHostTime);
    UInt64 nowNs = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());

    if (!_twoDevices && _recording)
    {
        implInDeviceIOProc(inputData, inputTime);
    }

    // Check if we should close down audio device
    // Double-checked locking optimization to remove locking overhead
    if (_doStop)
    {
        _critSect.Enter();
        if (_doStop)
        {
            if (_twoDevices || (!_recording && !_playing))
            {
               // In the case of a shared device, the single driving ioProc
               // is stopped here
               WEBRTC_CA_LOG_ERR(AudioDeviceStop(_outputDeviceID,
                                                 _deviceIOProcID));
               WEBRTC_CA_LOG_WARN(AudioDeviceDestroyIOProcID(_outputDeviceID,
                                                             _deviceIOProcID));
               if (err == noErr)
               {
                  WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice,
                               _id, " Playout or shared device stopped");
               }
            }

            _doStop = false;
            _stopEvent.Set();
            _critSect.Leave();
            return 0;
        }
        _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;
    }

    RTC_DCHECK(_outStreamFormat.mBytesPerFrame != 0);
    UInt32 size = outputData->mBuffers->mDataByteSize
        / _outStreamFormat.mBytesPerFrame;

    // TODO(xians): signal an error somehow?
    err = AudioConverterFillComplexBuffer(_renderConverter, outConverterProc,
                                          this, &size, outputData, NULL);
    if (err != noErr)
    {
        if (err == 1)
        {
            // This is our own error.
            WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
                         " Error in AudioConverterFillComplexBuffer()");
            return 1;
        } else
        {
            logCAMsg(kTraceError, kTraceAudioDevice, _id,
                     "Error in AudioConverterFillComplexBuffer()",
                     (const char *) &err);
            return 1;
        }
    }

    PaRingBufferSize bufSizeSamples =
        PaUtil_GetRingBufferReadAvailable(_paRenderBuffer);

    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)
{
  RTC_DCHECK(data->mNumberBuffers == 1);
    PaRingBufferSize numSamples = *numberDataPackets
        * _outDesiredFormat.mChannelsPerFrame;

    data->mBuffers->mNumberChannels = _outDesiredFormat.mChannelsPerFrame;
    // Always give the converter as much as it wants, zero padding as required.
    data->mBuffers->mDataByteSize = *numberDataPackets
        * _outDesiredFormat.mBytesPerPacket;
    data->mBuffers->mData = _renderConvertData;
    memset(_renderConvertData, 0, sizeof(_renderConvertData));

    PaUtil_ReadRingBuffer(_paRenderBuffer, _renderConvertData, numSamples);

    kern_return_t kernErr = semaphore_signal_all(_renderSemaphore);
    if (kernErr != KERN_SUCCESS)
    {
        WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
                     " semaphore_signal_all() error: %d", kernErr);
        return 1;
    }

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

    RTC_DCHECK(inputData->mNumberBuffers == 1);
    PaRingBufferSize numSamples = inputData->mBuffers->mDataByteSize
        * _inStreamFormat.mChannelsPerFrame / _inStreamFormat.mBytesPerPacket;
    PaUtil_WriteRingBuffer(_paCaptureBuffer, inputData->mBuffers->mData,
                           numSamples);

    kern_return_t kernErr = semaphore_signal_all(_captureSemaphore);
    if (kernErr != KERN_SUCCESS)
    {
        WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
                     " semaphore_signal_all() error: %d", kernErr);
    }

    return err;
}

OSStatus AudioDeviceMac::implInConverterProc(UInt32 *numberDataPackets,
                                             AudioBufferList *data)
{
  RTC_DCHECK(data->mNumberBuffers == 1);
    PaRingBufferSize numSamples = *numberDataPackets
        * _inStreamFormat.mChannelsPerFrame;

    while (PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer) < numSamples)
    {
        mach_timespec_t timeout;
        timeout.tv_sec = 0;
        timeout.tv_nsec = TIMER_PERIOD_MS;

        kern_return_t kernErr = semaphore_timedwait(_captureSemaphore, timeout);
        if (kernErr == KERN_OPERATION_TIMED_OUT)
        {
            int32_t signal = AtomicGet32(&_captureDeviceIsAlive);
            if (signal == 0)
            {
                // The capture device is no longer alive; stop the worker thread.
                *numberDataPackets = 0;
                return 1;
            }
        } else if (kernErr != KERN_SUCCESS)
        {
            WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
                         " semaphore_wait() error: %d", kernErr);
        }
    }

    // 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 < arraysize(prev_key_state_);
                    ++key_index) {
    bool keyState = CGEventSourceKeyState(
                             kCGEventSourceStateHIDSystemState,
                             key_index);
    // A false -> true change in keymap means a key is pressed.
    key_down |= (keyState && !prev_key_state_[key_index]);
    // Save current state.
    prev_key_state_[key_index] = keyState;
  }
  return key_down;
}
}  // namespace webrtc
