/*
 *  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 "modules/audio_device/mac/audio_device_mac.h"

#include <ApplicationServices/ApplicationServices.h>
#include <libkern/OSAtomic.h>  // OSAtomicCompareAndSwap()
#include <mach/mach.h>         // mach_task_self()
#include <sys/sysctl.h>        // sysctlbyname()

#include <memory>

#include "modules/audio_device/audio_device_config.h"
#include "modules/third_party/portaudio/pa_ringbuffer.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/system/arch.h"

namespace webrtc {

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

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

#define WEBRTC_CA_LOG_WARN(expr)                                       \
  do {                                                                 \
    err = expr;                                                        \
    if (err != noErr) {                                                \
      logCAMsg(rtc::LS_WARNING, "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 rtc::LoggingSeverity sev,
                              const char* msg,
                              const char* err) {
  RTC_DCHECK(msg != NULL);
  RTC_DCHECK(err != NULL);

#ifdef WEBRTC_ARCH_BIG_ENDIAN
  switch (sev) {
    case rtc::LS_ERROR:
      RTC_LOG(LS_ERROR) << msg << ": " << err[0] << err[1] << err[2] << err[3];
      break;
    case rtc::LS_WARNING:
      RTC_LOG(LS_WARNING) << msg << ": " << err[0] << err[1] << err[2]
                          << err[3];
      break;
    case rtc::LS_VERBOSE:
      RTC_LOG(LS_VERBOSE) << msg << ": " << err[0] << err[1] << err[2]
                          << err[3];
      break;
    default:
      break;
  }
#else
  // We need to flip the characters in this case.
  switch (sev) {
    case rtc::LS_ERROR:
      RTC_LOG(LS_ERROR) << msg << ": " << err[3] << err[2] << err[1] << err[0];
      break;
    case rtc::LS_WARNING:
      RTC_LOG(LS_WARNING) << msg << ": " << err[3] << err[2] << err[1]
                          << err[0];
      break;
    case rtc::LS_VERBOSE:
      RTC_LOG(LS_VERBOSE) << msg << ": " << err[3] << err[2] << err[1]
                          << err[0];
      break;
    default:
      break;
  }
#endif
}

AudioDeviceMac::AudioDeviceMac()
    : _ptrAudioBuffer(NULL),
      _mixerManager(),
      _inputDeviceIndex(0),
      _outputDeviceIndex(0),
      _inputDeviceID(kAudioObjectUnknown),
      _outputDeviceID(kAudioObjectUnknown),
      _inputDeviceIsSpecified(false),
      _outputDeviceIsSpecified(false),
      _recChannels(N_REC_CHANNELS),
      _playChannels(N_PLAY_CHANNELS),
      _captureBufData(NULL),
      _renderBufData(NULL),
      _initialized(false),
      _isShutDown(false),
      _recording(false),
      _playing(false),
      _recIsInitialized(false),
      _playIsInitialized(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),
      _paCaptureBuffer(NULL),
      _paRenderBuffer(NULL),
      _captureBufSizeSamples(0),
      _renderBufSizeSamples(0),
      prev_key_state_() {
  RTC_DLOG(LS_INFO) << __FUNCTION__ << " created";

  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() {
  RTC_DLOG(LS_INFO) << __FUNCTION__ << " destroyed";

  if (!_isShutDown) {
    Terminate();
  }

  RTC_DCHECK(capture_worker_thread_.empty());
  RTC_DCHECK(render_worker_thread_.empty());

  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) {
    RTC_LOG(LS_ERROR) << "semaphore_destroy() error: " << kernErr;
  }

  kernErr = semaphore_destroy(mach_task_self(), _captureSemaphore);
  if (kernErr != KERN_SUCCESS) {
    RTC_LOG(LS_ERROR) << "semaphore_destroy() error: " << kernErr;
  }
}

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

void AudioDeviceMac::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
  MutexLock lock(&mutex_);

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

AudioDeviceGeneric::InitStatus AudioDeviceMac::Init() {
  MutexLock lock(&mutex_);

  if (_initialized) {
    return InitStatus::OK;
  }

  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) {
      RTC_LOG(LS_ERROR) << "PaUtil_InitializeRingBuffer() error";
      return InitStatus::PLAYOUT_ERROR;
    }
  }

  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) {
      RTC_LOG(LS_ERROR) << "PaUtil_InitializeRingBuffer() error";
      return InitStatus::RECORDING_ERROR;
    }
  }

  kern_return_t kernErr = KERN_SUCCESS;
  kernErr = semaphore_create(mach_task_self(), &_renderSemaphore,
                             SYNC_POLICY_FIFO, 0);
  if (kernErr != KERN_SUCCESS) {
    RTC_LOG(LS_ERROR) << "semaphore_create() error: " << kernErr;
    return InitStatus::OTHER_ERROR;
  }

  kernErr = semaphore_create(mach_task_self(), &_captureSemaphore,
                             SYNC_POLICY_FIFO, 0);
  if (kernErr != KERN_SUCCESS) {
    RTC_LOG(LS_ERROR) << "semaphore_create() error: " << kernErr;
    return InitStatus::OTHER_ERROR;
  }

  // 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);
  int aoerr = AudioObjectSetPropertyData(
      kAudioObjectSystemObject, &propertyAddress, 0, NULL, size, &runLoop);
  if (aoerr != noErr) {
    RTC_LOG(LS_ERROR) << "Error in AudioObjectSetPropertyData: "
                      << (const char*)&aoerr;
    return InitStatus::OTHER_ERROR;
  }

  // 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) {
    RTC_LOG(LS_ERROR) << "Error in sysctlbyname(): " << err;
  } else {
    RTC_LOG(LS_VERBOSE) << "Hardware model: " << buf;
    if (strncmp(buf, "MacBookPro", 10) == 0) {
      _macBookPro = true;
    }
  }

  _initialized = true;

  return InitStatus::OK;
}

int32_t AudioDeviceMac::Terminate() {
  if (!_initialized) {
    return 0;
  }

  if (_recording) {
    RTC_LOG(LS_ERROR) << "Recording must be stopped";
    return -1;
  }

  if (_playing) {
    RTC_LOG(LS_ERROR) << "Playback must be stopped";
    return -1;
  }

  MutexLock lock(&mutex_);
  _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(rtc::LS_ERROR, "Error in AudioHardwareUnload()",
             (const char*)&err);
    retVal = -1;
  }

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

  return retVal;
}

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

int32_t AudioDeviceMac::SpeakerIsAvailable(bool& available) {
  MutexLock lock(&mutex_);
  return SpeakerIsAvailableLocked(available);
}

int32_t AudioDeviceMac::SpeakerIsAvailableLocked(bool& available) {
  bool wasInitialized = _mixerManager.SpeakerIsInitialized();

  // Make an attempt to open up the
  // output mixer corresponding to the currently selected output device.
  //
  if (!wasInitialized && InitSpeakerLocked() == -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() {
  MutexLock lock(&mutex_);
  return InitSpeakerLocked();
}

int32_t AudioDeviceMac::InitSpeakerLocked() {
  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) {
  MutexLock lock(&mutex_);
  return MicrophoneIsAvailableLocked(available);
}

int32_t AudioDeviceMac::MicrophoneIsAvailableLocked(bool& available) {
  bool wasInitialized = _mixerManager.MicrophoneIsInitialized();

  // Make an attempt to open up the
  // input mixer corresponding to the currently selected output device.
  //
  if (!wasInitialized && InitMicrophoneLocked() == -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() {
  MutexLock lock(&mutex_);
  return InitMicrophoneLocked();
}

int32_t AudioDeviceMac::InitMicrophoneLocked() {
  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::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::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::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::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) {
    RTC_LOG(LS_WARNING) << "failed to retrieve 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;
}

int16_t AudioDeviceMac::PlayoutDevices() {
  AudioDeviceID playDevices[MaxNumberDevices];
  return GetNumberDevices(kAudioDevicePropertyScopeOutput, playDevices,
                          MaxNumberDevices);
}

int32_t AudioDeviceMac::SetPlayoutDevice(uint16_t index) {
  MutexLock lock(&mutex_);

  if (_playIsInitialized) {
    return -1;
  }

  AudioDeviceID playDevices[MaxNumberDevices];
  uint32_t nDevices = GetNumberDevices(kAudioDevicePropertyScopeOutput,
                                       playDevices, MaxNumberDevices);
  RTC_LOG(LS_VERBOSE) << "number of available waveform-audio output devices is "
                      << nDevices;

  if (index > (nDevices - 1)) {
    RTC_LOG(LS_ERROR) << "device index is out of range [0," << (nDevices - 1)
                      << "]";
    return -1;
  }

  _outputDeviceIndex = index;
  _outputDeviceIsSpecified = true;

  return 0;
}

int32_t AudioDeviceMac::SetPlayoutDevice(
    AudioDeviceModule::WindowsDeviceType /*device*/) {
  RTC_LOG(LS_ERROR) << "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);
  RTC_LOG(LS_VERBOSE) << "number of available waveform-audio input devices is "
                      << nDevices;

  if (index > (nDevices - 1)) {
    RTC_LOG(LS_ERROR) << "device index is out of range [0," << (nDevices - 1)
                      << "]";
    return -1;
  }

  _inputDeviceIndex = index;
  _inputDeviceIsSpecified = true;

  return 0;
}

int32_t AudioDeviceMac::SetRecordingDevice(
    AudioDeviceModule::WindowsDeviceType /*device*/) {
  RTC_LOG(LS_ERROR) << "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() {
  RTC_LOG(LS_INFO) << "InitPlayout";
  MutexLock lock(&mutex_);

  if (_playing) {
    return -1;
  }

  if (!_outputDeviceIsSpecified) {
    return -1;
  }

  if (_playIsInitialized) {
    return 0;
  }

  // Initialize the speaker (devices might have been added or removed)
  if (InitSpeakerLocked() == -1) {
    RTC_LOG(LS_WARNING) << "InitSpeaker() failed";
  }

  if (!MicrophoneIsInitialized()) {
    // Make this call to check if we are using
    // one or two devices (_twoDevices)
    bool available = false;
    if (MicrophoneIsAvailableLocked(available) == -1) {
      RTC_LOG(LS_WARNING) << "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;
        RTC_LOG(LS_VERBOSE)
            << "MacBook Pro using internal speakers; stereo panning right";
      } else {
        RTC_LOG(LS_VERBOSE) << "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(rtc::LS_ERROR, "Unacceptable output stream format -> mFormatID",
             (const char*)&_outStreamFormat.mFormatID);
    return -1;
  }

  if (_outStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) {
    RTC_LOG(LS_ERROR)
        << "Too many channels on output device (mChannelsPerFrame = "
        << _outStreamFormat.mChannelsPerFrame << ")";
    return -1;
  }

  if (_outStreamFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved) {
    RTC_LOG(LS_ERROR) << "Non-interleaved audio data is not supported."
                         "AudioHardware streams should not have this format.";
    return -1;
  }

  RTC_LOG(LS_VERBOSE) << "Ouput stream format:";
  RTC_LOG(LS_VERBOSE) << "mSampleRate = " << _outStreamFormat.mSampleRate
                      << ", mChannelsPerFrame = "
                      << _outStreamFormat.mChannelsPerFrame;
  RTC_LOG(LS_VERBOSE) << "mBytesPerPacket = "
                      << _outStreamFormat.mBytesPerPacket
                      << ", mFramesPerPacket = "
                      << _outStreamFormat.mFramesPerPacket;
  RTC_LOG(LS_VERBOSE) << "mBytesPerFrame = " << _outStreamFormat.mBytesPerFrame
                      << ", mBitsPerChannel = "
                      << _outStreamFormat.mBitsPerChannel;
  RTC_LOG(LS_VERBOSE) << "mFormatFlags = " << _outStreamFormat.mFormatFlags;
  logCAMsg(rtc::LS_VERBOSE, "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;
    RTC_LOG(LS_VERBOSE) << "Stereo playout unavailable on this device";
  }
  WEBRTC_CA_RETURN_ON_ERR(SetDesiredPlayoutFormat());

  // Listen for format changes.
  propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
  WEBRTC_CA_LOG_WARN(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() {
  RTC_LOG(LS_INFO) << "InitRecording";
  MutexLock lock(&mutex_);

  if (_recording) {
    return -1;
  }

  if (!_inputDeviceIsSpecified) {
    return -1;
  }

  if (_recIsInitialized) {
    return 0;
  }

  // Initialize the microphone (devices might have been added or removed)
  if (InitMicrophoneLocked() == -1) {
    RTC_LOG(LS_WARNING) << "InitMicrophone() failed";
  }

  if (!SpeakerIsInitialized()) {
    // Make this call to check if we are using
    // one or two devices (_twoDevices)
    bool available = false;
    if (SpeakerIsAvailableLocked(available) == -1) {
      RTC_LOG(LS_WARNING) << "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(rtc::LS_ERROR, "Unacceptable input stream format -> mFormatID",
             (const char*)&_inStreamFormat.mFormatID);
    return -1;
  }

  if (_inStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) {
    RTC_LOG(LS_ERROR)
        << "Too many channels on input device (mChannelsPerFrame = "
        << _inStreamFormat.mChannelsPerFrame << ")";
    return -1;
  }

  const int io_block_size_samples = _inStreamFormat.mChannelsPerFrame *
                                    _inStreamFormat.mSampleRate / 100 *
                                    N_BLOCKS_IO;
  if (io_block_size_samples > _captureBufSizeSamples) {
    RTC_LOG(LS_ERROR) << "Input IO block size (" << io_block_size_samples
                      << ") is larger than ring buffer ("
                      << _captureBufSizeSamples << ")";
    return -1;
  }

  RTC_LOG(LS_VERBOSE) << "Input stream format:";
  RTC_LOG(LS_VERBOSE) << "mSampleRate = " << _inStreamFormat.mSampleRate
                      << ", mChannelsPerFrame = "
                      << _inStreamFormat.mChannelsPerFrame;
  RTC_LOG(LS_VERBOSE) << "mBytesPerPacket = " << _inStreamFormat.mBytesPerPacket
                      << ", mFramesPerPacket = "
                      << _inStreamFormat.mFramesPerPacket;
  RTC_LOG(LS_VERBOSE) << "mBytesPerFrame = " << _inStreamFormat.mBytesPerFrame
                      << ", mBitsPerChannel = "
                      << _inStreamFormat.mBitsPerChannel;
  RTC_LOG(LS_VERBOSE) << "mFormatFlags = " << _inStreamFormat.mFormatFlags;
  logCAMsg(rtc::LS_VERBOSE, "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;
    RTC_LOG(LS_VERBOSE) << "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_LOG_WARN(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() {
  RTC_LOG(LS_INFO) << "StartRecording";
  MutexLock lock(&mutex_);

  if (!_recIsInitialized) {
    return -1;
  }

  if (_recording) {
    return 0;
  }

  if (!_initialized) {
    RTC_LOG(LS_ERROR) << "Recording worker thread has not been started";
    return -1;
  }

  RTC_DCHECK(capture_worker_thread_.empty());
  capture_worker_thread_ = rtc::PlatformThread::SpawnJoinable(
      [this] {
        while (CaptureWorkerThread()) {
        }
      },
      "CaptureWorkerThread",
      rtc::ThreadAttributes().SetPriority(rtc::ThreadPriority::kRealtime));

  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() {
  RTC_LOG(LS_INFO) << "StopRecording";
  MutexLock lock(&mutex_);

  if (!_recIsInitialized) {
    return 0;
  }

  OSStatus err = noErr;
  int32_t captureDeviceIsAlive = AtomicGet32(&_captureDeviceIsAlive);
  if (_twoDevices && captureDeviceIsAlive == 1) {
    // Recording side uses its own dedicated device and IOProc.
    if (_recording) {
      _recording = false;
      _doStopRec = true;  // Signal to io proc to stop audio device
      mutex_.Unlock();    // Cannot be under lock, risk of deadlock
      if (!_stopEventRec.Wait(2000)) {
        MutexLock lockScoped(&mutex_);
        RTC_LOG(LS_WARNING) << "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));
      }
      mutex_.Lock();
      _doStopRec = false;
      RTC_LOG(LS_INFO) << "Recording stopped (input device)";
    } else if (_recIsInitialized) {
      WEBRTC_CA_LOG_WARN(
          AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID));
      RTC_LOG(LS_INFO) << "Recording uninitialized (input device)";
    }
  } 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
      mutex_.Unlock();    // Cannot be under lock, risk of deadlock
      if (!_stopEvent.Wait(2000)) {
        MutexLock lockScoped(&mutex_);
        RTC_LOG(LS_WARNING) << "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));
      }
      mutex_.Lock();
      _doStop = false;
      RTC_LOG(LS_INFO) << "Recording stopped (shared device)";
    } else if (_recIsInitialized && !_playing && !_playIsInitialized) {
      WEBRTC_CA_LOG_WARN(
          AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
      RTC_LOG(LS_INFO) << "Recording uninitialized (shared device)";
    }
  }

  // Setting this signal will allow the worker thread to be stopped.
  AtomicSet32(&_captureDeviceIsAlive, 0);

  if (!capture_worker_thread_.empty()) {
    mutex_.Unlock();
    capture_worker_thread_.Finalize();
    mutex_.Lock();
  }

  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() {
  RTC_LOG(LS_INFO) << "StartPlayout";
  MutexLock lock(&mutex_);

  if (!_playIsInitialized) {
    return -1;
  }

  if (_playing) {
    return 0;
  }

  RTC_DCHECK(render_worker_thread_.empty());
  render_worker_thread_ = rtc::PlatformThread::SpawnJoinable(
      [this] {
        while (RenderWorkerThread()) {
        }
      },
      "RenderWorkerThread",
      rtc::ThreadAttributes().SetPriority(rtc::ThreadPriority::kRealtime));

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

  return 0;
}

int32_t AudioDeviceMac::StopPlayout() {
  RTC_LOG(LS_INFO) << "StopPlayout";
  MutexLock lock(&mutex_);

  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
    mutex_.Unlock();    // Cannot be under lock, risk of deadlock
    if (!_stopEvent.Wait(2000)) {
      MutexLock lockScoped(&mutex_);
      RTC_LOG(LS_WARNING) << "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));
    }
    mutex_.Lock();
    _doStop = false;
    RTC_LOG(LS_INFO) << "Playout stopped";
  } else if (_twoDevices && _playIsInitialized) {
    WEBRTC_CA_LOG_WARN(
        AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
    RTC_LOG(LS_INFO) << "Playout uninitialized (output device)";
  } else if (!_twoDevices && _playIsInitialized && !_recIsInitialized) {
    WEBRTC_CA_LOG_WARN(
        AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
    RTC_LOG(LS_INFO) << "Playout uninitialized (shared device)";
  }

  // Setting this signal will allow the worker thread to be stopped.
  AtomicSet32(&_renderDeviceIsAlive, 0);
  if (!render_worker_thread_.empty()) {
    mutex_.Unlock();
    render_worker_thread_.Finalize();
    mutex_.Lock();
  }

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

bool AudioDeviceMac::Playing() const {
  return (_playing);
}

// ============================================================================
//                                 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) {
    RTC_LOG(LS_WARNING) << "No devices";
    return 0;
  }

  UInt32 numberDevices = size / sizeof(AudioDeviceID);
  const auto deviceIds = std::make_unique<AudioDeviceID[]>(numberDevices);
  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 {
    RTC_LOG(LS_WARNING) << "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.get()));
  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) {
          RTC_LOG(LS_ERROR) << "Device list is not long enough";
          listOK = false;
          break;
        }

        scopedDeviceIds[numberScopedDevices] = deviceIds[i];
        numberScopedDevices++;
      }

      free(bufferList);
      bufferList = NULL;
    }  // for
  }

  if (!listOK) {
    if (bufferList) {
      free(bufferList);
      bufferList = NULL;
    }
    return -1;
  }

  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) {
    RTC_LOG(LS_ERROR) << "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) {
      RTC_LOG(LS_WARNING) << "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) {
    RTC_LOG(LS_ERROR) << "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) {
      RTC_LOG(LS_WARNING) << "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) {
    RTC_LOG(LS_INFO) << "Input device: " << devManf << " " << devName;
  } else {
    RTC_LOG(LS_INFO) << "Output device: " << 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 set to 20ms.
  const uint16_t kPlayBufDelayFixed = 20;
  UInt32 bufByteCount = static_cast<UInt32>(
      (_outStreamFormat.mSampleRate / 1000.0) * kPlayBufDelayFixed *
      _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);

  RTC_LOG(LS_VERBOSE) << "initial playout status: _renderDelayOffsetSamples="
                      << _renderDelayOffsetSamples
                      << ", _renderDelayUs=" << _renderDelayUs
                      << ", _renderLatencyUs=" << _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[]) {
  RTC_LOG(LS_VERBOSE) << "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;

  RTC_LOG(LS_VERBOSE) << "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) {
      RTC_LOG(LS_WARNING) << "Capture device is not alive (probably removed)";
      AtomicSet32(&_captureDeviceIsAlive, 0);
      _mixerManager.CloseMicrophone();
    } else if (err != noErr) {
      logCAMsg(rtc::LS_ERROR, "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) {
      RTC_LOG(LS_WARNING) << "Render device is not alive (probably removed)";
      AtomicSet32(&_renderDeviceIsAlive, 0);
      _mixerManager.CloseSpeaker();
    } else if (err != noErr) {
      logCAMsg(rtc::LS_ERROR, "Error in AudioDeviceGetProperty()",
               (const char*)&err);
      return -1;
    }
  }

  return 0;
}

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

  RTC_LOG(LS_VERBOSE) << "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(rtc::LS_ERROR, "Unacceptable input stream format -> mFormatID",
             (const char*)&streamFormat.mFormatID);
    return -1;
  }

  if (streamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) {
    RTC_LOG(LS_ERROR) << "Too many channels on device (mChannelsPerFrame = "
                      << streamFormat.mChannelsPerFrame << ")";
    return -1;
  }

  if (_ptrAudioBuffer && streamFormat.mChannelsPerFrame != _recChannels) {
    RTC_LOG(LS_ERROR) << "Changing channels not supported (mChannelsPerFrame = "
                      << streamFormat.mChannelsPerFrame << ")";
    return -1;
  }

  RTC_LOG(LS_VERBOSE) << "Stream format:";
  RTC_LOG(LS_VERBOSE) << "mSampleRate = " << streamFormat.mSampleRate
                      << ", mChannelsPerFrame = "
                      << streamFormat.mChannelsPerFrame;
  RTC_LOG(LS_VERBOSE) << "mBytesPerPacket = " << streamFormat.mBytesPerPacket
                      << ", mFramesPerPacket = "
                      << streamFormat.mFramesPerPacket;
  RTC_LOG(LS_VERBOSE) << "mBytesPerFrame = " << streamFormat.mBytesPerFrame
                      << ", mBitsPerChannel = " << streamFormat.mBitsPerChannel;
  RTC_LOG(LS_VERBOSE) << "mFormatFlags = " << streamFormat.mFormatFlags;
  logCAMsg(rtc::LS_VERBOSE, "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) {
      RTC_LOG(LS_ERROR) << "Input IO block size (" << io_block_size_samples
                        << ") is larger than ring buffer ("
                        << _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;
      RTC_LOG(LS_VERBOSE) << "Stereo recording unavailable on this device";
    }

    // 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;
      RTC_LOG(LS_VERBOSE) << "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) {
    RTC_LOG(LS_VERBOSE) << "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;
      RTC_LOG(LS_VERBOSE)
          << "MacBook Pro using internal speakers; stereo panning right";
    } else {
      RTC_LOG(LS_VERBOSE) << "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) {
    // RTC_LOG(LS_WARNING) << "Capture processor // overload";
    //_callback->ProblemIsReported(
    // SndCardStreamObserver::ERecordingProblem);
  } else {
    // RTC_LOG(LS_WARNING) << "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) {
    MutexLock lock(&mutex_);
    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) {
          RTC_LOG(LS_VERBOSE) << "Playout or shared device stopped";
        }
      }

      _doStop = false;
      _stopEvent.Set();
      return 0;
    }
  }

  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.
      RTC_LOG(LS_ERROR) << "Error in AudioConverterFillComplexBuffer()";
      return 1;
    } else {
      logCAMsg(rtc::LS_ERROR, "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) {
    RTC_LOG(LS_ERROR) << "semaphore_signal_all() error: " << 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) {
    MutexLock lock(&mutex_);
    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) {
        RTC_LOG(LS_VERBOSE) << "Recording device stopped";
      }

      _doStopRec = false;
      _stopEventRec.Set();
      return 0;
    }
  }

  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) {
    RTC_LOG(LS_ERROR) << "semaphore_signal_all() error: " << 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) {
      RTC_LOG(LS_ERROR) << "semaphore_wait() error: " << 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::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) {
      RTC_LOG(LS_ERROR) << "semaphore_timedwait() error: " << kernErr;
    }
  }

  int8_t playBuffer[4 * ENGINE_PLAY_BUF_SIZE_IN_SAMPLES];

  if (!_ptrAudioBuffer) {
    RTC_LOG(LS_ERROR) << "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) {
    RTC_LOG(LS_ERROR) << "invalid number of output samples(" << 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::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(rtc::LS_ERROR, "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) {
    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) {
      RTC_LOG(LS_ERROR) << "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);
    _ptrAudioBuffer->SetVQEData(msecOnPlaySide, msecOnRecordSide);
    _ptrAudioBuffer->SetTypingStatus(KeyPressed());

    // deliver recorded samples at specified sample rate, mic level etc.
    // to the observer using callback
    _ptrAudioBuffer->DeliverRecordedData();
  }

  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
