/*
 *  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 "absl/memory/memory.h"
#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"

#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(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_LOG(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_LOG(LS_INFO) << __FUNCTION__ << " destroyed";

  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) {
    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) {
  rtc::CritScope 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;
}

AudioDeviceGeneric::InitStatus AudioDeviceMac::Init() {
  rtc::CritScope lock(&_critSect);

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

  _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(rtc::LS_ERROR, "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() {
  rtc::CritScope 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() {
  rtc::CritScope 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::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) {
  rtc::CritScope lock(&_critSect);

  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";
  rtc::CritScope 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) {
    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 (MicrophoneIsAvailable(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";
  rtc::CritScope 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) {
    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 (SpeakerIsAvailable(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";
  rtc::CritScope lock(&_critSect);

  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_.get());
  capture_worker_thread_.reset(
      new rtc::PlatformThread(RunCapture, this, "CaptureWorkerThread"));
  RTC_DCHECK(capture_worker_thread_.get());
  capture_worker_thread_->Start();
  capture_worker_thread_->SetPriority(rtc::kRealtimePriority);

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

  _recording = true;

  return 0;
}

int32_t AudioDeviceMac::StopRecording() {
  RTC_LOG(LS_INFO) << "StopRecording";
  rtc::CritScope lock(&_critSect);

  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
      _critSect.Leave();  // Cannot be under lock, risk of deadlock
      if (!_stopEventRec.Wait(2000)) {
        rtc::CritScope critScoped(&_critSect);
        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));
      }
      _critSect.Enter();
      _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
      _critSect.Leave();  // Cannot be under lock, risk of deadlock
      if (!_stopEvent.Wait(2000)) {
        rtc::CritScope critScoped(&_critSect);
        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));
      }
      _critSect.Enter();
      _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_.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() {
  RTC_LOG(LS_INFO) << "StartPlayout";
  rtc::CritScope lock(&_critSect);

  if (!_playIsInitialized) {
    return -1;
  }

  if (_playing) {
    return 0;
  }

  RTC_DCHECK(!render_worker_thread_.get());
  render_worker_thread_.reset(
      new rtc::PlatformThread(RunRender, this, "RenderWorkerThread"));
  render_worker_thread_->Start();
  render_worker_thread_->SetPriority(rtc::kRealtimePriority);

  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";
  rtc::CritScope 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 (!_stopEvent.Wait(2000)) {
      rtc::CritScope critScoped(&_critSect);
      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));
    }
    _critSect.Enter();
    _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_.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;
}

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 = absl::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) {
    _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) {
          RTC_LOG(LS_VERBOSE) << "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.
      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) {
    _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) {
        RTC_LOG(LS_VERBOSE) << "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) {
    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::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) {
      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::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(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
