/*
 *  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_mixer_manager_mac.h"

#include <unistd.h>  // getpid()

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)

AudioMixerManagerMac::AudioMixerManagerMac()
    : _inputDeviceID(kAudioObjectUnknown),
      _outputDeviceID(kAudioObjectUnknown),
      _noInputChannels(0),
      _noOutputChannels(0) {
  LOG(LS_INFO) << __FUNCTION__ << " created";
}

AudioMixerManagerMac::~AudioMixerManagerMac() {
  LOG(LS_INFO) << __FUNCTION__ << " destroyed";
  Close();
}

// ============================================================================
//	                                PUBLIC METHODS
// ============================================================================

int32_t AudioMixerManagerMac::Close() {
  LOG(LS_VERBOSE) << __FUNCTION__;

  rtc::CritScope lock(&_critSect);

  CloseSpeaker();
  CloseMicrophone();

  return 0;
}

int32_t AudioMixerManagerMac::CloseSpeaker() {
  LOG(LS_VERBOSE) << __FUNCTION__;

  rtc::CritScope lock(&_critSect);

  _outputDeviceID = kAudioObjectUnknown;
  _noOutputChannels = 0;

  return 0;
}

int32_t AudioMixerManagerMac::CloseMicrophone() {
  LOG(LS_VERBOSE) << __FUNCTION__;

  rtc::CritScope lock(&_critSect);

  _inputDeviceID = kAudioObjectUnknown;
  _noInputChannels = 0;

  return 0;
}

int32_t AudioMixerManagerMac::OpenSpeaker(AudioDeviceID deviceID) {
  LOG(LS_VERBOSE) << "AudioMixerManagerMac::OpenSpeaker(id=" << deviceID << ")";

  rtc::CritScope lock(&_critSect);

  OSStatus err = noErr;
  UInt32 size = 0;
  pid_t hogPid = -1;

  _outputDeviceID = deviceID;

  // Check which process, if any, has hogged the device.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeOutput, 0};

  size = sizeof(hogPid);
  WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
      _outputDeviceID, &propertyAddress, 0, NULL, &size, &hogPid));

  if (hogPid == -1) {
    LOG(LS_VERBOSE) << "No process has hogged the input device";
  }
  // getpid() is apparently "always successful"
  else if (hogPid == getpid()) {
    LOG(LS_VERBOSE) << "Our process has hogged the input device";
  } else {
    LOG(LS_WARNING) << "Another process (pid = " << static_cast<int>(hogPid)
                    << ") has hogged the input device";

    return -1;
  }

  // get number of channels from stream format
  propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;

  // Get the stream format, to be able to read the number of channels.
  AudioStreamBasicDescription streamFormat;
  size = sizeof(AudioStreamBasicDescription);
  memset(&streamFormat, 0, size);
  WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
      _outputDeviceID, &propertyAddress, 0, NULL, &size, &streamFormat));

  _noOutputChannels = streamFormat.mChannelsPerFrame;

  return 0;
}

int32_t AudioMixerManagerMac::OpenMicrophone(AudioDeviceID deviceID) {
  LOG(LS_VERBOSE) << "AudioMixerManagerMac::OpenMicrophone(id=" << deviceID
                  << ")";

  rtc::CritScope lock(&_critSect);

  OSStatus err = noErr;
  UInt32 size = 0;
  pid_t hogPid = -1;

  _inputDeviceID = deviceID;

  // Check which process, if any, has hogged the device.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeInput, 0};
  size = sizeof(hogPid);
  WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
      _inputDeviceID, &propertyAddress, 0, NULL, &size, &hogPid));
  if (hogPid == -1) {
    LOG(LS_VERBOSE) << "No process has hogged the input device";
  }
  // getpid() is apparently "always successful"
  else if (hogPid == getpid()) {
    LOG(LS_VERBOSE) << "Our process has hogged the input device";
  } else {
    LOG(LS_WARNING) << "Another process (pid = " << static_cast<int>(hogPid)
                    << ") has hogged the input device";

    return -1;
  }

  // get number of channels from stream format
  propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;

  // Get the stream format, to be able to read the number of channels.
  AudioStreamBasicDescription streamFormat;
  size = sizeof(AudioStreamBasicDescription);
  memset(&streamFormat, 0, size);
  WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
      _inputDeviceID, &propertyAddress, 0, NULL, &size, &streamFormat));

  _noInputChannels = streamFormat.mChannelsPerFrame;

  return 0;
}

bool AudioMixerManagerMac::SpeakerIsInitialized() const {
  LOG(LS_INFO) << __FUNCTION__;

  return (_outputDeviceID != kAudioObjectUnknown);
}

bool AudioMixerManagerMac::MicrophoneIsInitialized() const {
  LOG(LS_INFO) << __FUNCTION__;

  return (_inputDeviceID != kAudioObjectUnknown);
}

int32_t AudioMixerManagerMac::SetSpeakerVolume(uint32_t volume) {
  LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetSpeakerVolume(volume=" << volume
                  << ")";

  rtc::CritScope lock(&_critSect);

  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;
  UInt32 size = 0;
  bool success = false;

  // volume range is 0.0 - 1.0, convert from 0 -255
  const Float32 vol = (Float32)(volume / 255.0);

  assert(vol <= 1.0 && vol >= 0.0);

  // Does the capture device have a master volume control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0};
  Boolean isSettable = false;
  err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
                                      &isSettable);
  if (err == noErr && isSettable) {
    size = sizeof(vol);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
        _outputDeviceID, &propertyAddress, 0, NULL, size, &vol));

    return 0;
  }

  // Otherwise try to set each channel.
  for (UInt32 i = 1; i <= _noOutputChannels; i++) {
    propertyAddress.mElement = i;
    isSettable = false;
    err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
                                        &isSettable);
    if (err == noErr && isSettable) {
      size = sizeof(vol);
      WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
          _outputDeviceID, &propertyAddress, 0, NULL, size, &vol));
    }
    success = true;
  }

  if (!success) {
    LOG(LS_WARNING) << "Unable to set a volume on any output channel";
    return -1;
  }

  return 0;
}

int32_t AudioMixerManagerMac::SpeakerVolume(uint32_t& volume) const {
  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;
  UInt32 size = 0;
  unsigned int channels = 0;
  Float32 channelVol = 0;
  Float32 vol = 0;

  // Does the device have a master volume control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0};
  Boolean hasProperty =
      AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
  if (hasProperty) {
    size = sizeof(vol);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
        _outputDeviceID, &propertyAddress, 0, NULL, &size, &vol));

    // vol 0.0 to 1.0 -> convert to 0 - 255
    volume = static_cast<uint32_t>(vol * 255 + 0.5);
  } else {
    // Otherwise get the average volume across channels.
    vol = 0;
    for (UInt32 i = 1; i <= _noOutputChannels; i++) {
      channelVol = 0;
      propertyAddress.mElement = i;
      hasProperty = AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
      if (hasProperty) {
        size = sizeof(channelVol);
        WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
            _outputDeviceID, &propertyAddress, 0, NULL, &size, &channelVol));

        vol += channelVol;
        channels++;
      }
    }

    if (channels == 0) {
      LOG(LS_WARNING) << "Unable to get a volume on any channel";
      return -1;
    }

    assert(channels > 0);
    // vol 0.0 to 1.0 -> convert to 0 - 255
    volume = static_cast<uint32_t>(255 * vol / channels + 0.5);
  }

  LOG(LS_VERBOSE) << "AudioMixerManagerMac::SpeakerVolume() => vol=" << vol;

  return 0;
}

int32_t AudioMixerManagerMac::MaxSpeakerVolume(uint32_t& maxVolume) const {
  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  // volume range is 0.0 to 1.0
  // we convert that to 0 - 255
  maxVolume = 255;

  return 0;
}

int32_t AudioMixerManagerMac::MinSpeakerVolume(uint32_t& minVolume) const {
  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  // volume range is 0.0 to 1.0
  // we convert that to 0 - 255
  minVolume = 0;

  return 0;
}

int32_t AudioMixerManagerMac::SpeakerVolumeIsAvailable(bool& available) {
  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;

  // Does the capture device have a master volume control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0};
  Boolean isSettable = false;
  err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
                                      &isSettable);
  if (err == noErr && isSettable) {
    available = true;
    return 0;
  }

  // Otherwise try to set each channel.
  for (UInt32 i = 1; i <= _noOutputChannels; i++) {
    propertyAddress.mElement = i;
    isSettable = false;
    err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
                                        &isSettable);
    if (err != noErr || !isSettable) {
      available = false;
      LOG(LS_WARNING) << "Volume cannot be set for output channel " << i
                      << ", err=" << err;
      return -1;
    }
  }

  available = true;
  return 0;
}

int32_t AudioMixerManagerMac::SpeakerMuteIsAvailable(bool& available) {
  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;

  // Does the capture device have a master mute control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0};
  Boolean isSettable = false;
  err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
                                      &isSettable);
  if (err == noErr && isSettable) {
    available = true;
    return 0;
  }

  // Otherwise try to set each channel.
  for (UInt32 i = 1; i <= _noOutputChannels; i++) {
    propertyAddress.mElement = i;
    isSettable = false;
    err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
                                        &isSettable);
    if (err != noErr || !isSettable) {
      available = false;
      LOG(LS_WARNING) << "Mute cannot be set for output channel " << i
                      << ", err=" << err;
      return -1;
    }
  }

  available = true;
  return 0;
}

int32_t AudioMixerManagerMac::SetSpeakerMute(bool enable) {
  LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetSpeakerMute(enable=" << enable
                  << ")";

  rtc::CritScope lock(&_critSect);

  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;
  UInt32 size = 0;
  UInt32 mute = enable ? 1 : 0;
  bool success = false;

  // Does the render device have a master mute control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0};
  Boolean isSettable = false;
  err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
                                      &isSettable);
  if (err == noErr && isSettable) {
    size = sizeof(mute);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
        _outputDeviceID, &propertyAddress, 0, NULL, size, &mute));

    return 0;
  }

  // Otherwise try to set each channel.
  for (UInt32 i = 1; i <= _noOutputChannels; i++) {
    propertyAddress.mElement = i;
    isSettable = false;
    err = AudioObjectIsPropertySettable(_outputDeviceID, &propertyAddress,
                                        &isSettable);
    if (err == noErr && isSettable) {
      size = sizeof(mute);
      WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
          _outputDeviceID, &propertyAddress, 0, NULL, size, &mute));
    }
    success = true;
  }

  if (!success) {
    LOG(LS_WARNING) << "Unable to set mute on any input channel";
    return -1;
  }

  return 0;
}

int32_t AudioMixerManagerMac::SpeakerMute(bool& enabled) const {
  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;
  UInt32 size = 0;
  unsigned int channels = 0;
  UInt32 channelMuted = 0;
  UInt32 muted = 0;

  // Does the device have a master volume control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0};
  Boolean hasProperty =
      AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
  if (hasProperty) {
    size = sizeof(muted);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
        _outputDeviceID, &propertyAddress, 0, NULL, &size, &muted));

    // 1 means muted
    enabled = static_cast<bool>(muted);
  } else {
    // Otherwise check if all channels are muted.
    for (UInt32 i = 1; i <= _noOutputChannels; i++) {
      muted = 0;
      propertyAddress.mElement = i;
      hasProperty = AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
      if (hasProperty) {
        size = sizeof(channelMuted);
        WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
            _outputDeviceID, &propertyAddress, 0, NULL, &size, &channelMuted));

        muted = (muted && channelMuted);
        channels++;
      }
    }

    if (channels == 0) {
      LOG(LS_WARNING) << "Unable to get mute for any channel";
      return -1;
    }

    assert(channels > 0);
    // 1 means muted
    enabled = static_cast<bool>(muted);
  }

  LOG(LS_VERBOSE) << "AudioMixerManagerMac::SpeakerMute() => enabled="
                  << enabled;

  return 0;
}

int32_t AudioMixerManagerMac::StereoPlayoutIsAvailable(bool& available) {
  if (_outputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  available = (_noOutputChannels == 2);
  return 0;
}

int32_t AudioMixerManagerMac::StereoRecordingIsAvailable(bool& available) {
  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  available = (_noInputChannels == 2);
  return 0;
}

int32_t AudioMixerManagerMac::MicrophoneMuteIsAvailable(bool& available) {
  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;

  // Does the capture device have a master mute control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyMute, kAudioDevicePropertyScopeInput, 0};
  Boolean isSettable = false;
  err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
                                      &isSettable);
  if (err == noErr && isSettable) {
    available = true;
    return 0;
  }

  // Otherwise try to set each channel.
  for (UInt32 i = 1; i <= _noInputChannels; i++) {
    propertyAddress.mElement = i;
    isSettable = false;
    err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
                                        &isSettable);
    if (err != noErr || !isSettable) {
      available = false;
      LOG(LS_WARNING) << "Mute cannot be set for output channel " << i
                      << ", err=" << err;
      return -1;
    }
  }

  available = true;
  return 0;
}

int32_t AudioMixerManagerMac::SetMicrophoneMute(bool enable) {
  LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetMicrophoneMute(enable=" << enable
                  << ")";

  rtc::CritScope lock(&_critSect);

  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;
  UInt32 size = 0;
  UInt32 mute = enable ? 1 : 0;
  bool success = false;

  // Does the capture device have a master mute control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyMute, kAudioDevicePropertyScopeInput, 0};
  Boolean isSettable = false;
  err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
                                      &isSettable);
  if (err == noErr && isSettable) {
    size = sizeof(mute);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
        _inputDeviceID, &propertyAddress, 0, NULL, size, &mute));

    return 0;
  }

  // Otherwise try to set each channel.
  for (UInt32 i = 1; i <= _noInputChannels; i++) {
    propertyAddress.mElement = i;
    isSettable = false;
    err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
                                        &isSettable);
    if (err == noErr && isSettable) {
      size = sizeof(mute);
      WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
          _inputDeviceID, &propertyAddress, 0, NULL, size, &mute));
    }
    success = true;
  }

  if (!success) {
    LOG(LS_WARNING) << "Unable to set mute on any input channel";
    return -1;
  }

  return 0;
}

int32_t AudioMixerManagerMac::MicrophoneMute(bool& enabled) const {
  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;
  UInt32 size = 0;
  unsigned int channels = 0;
  UInt32 channelMuted = 0;
  UInt32 muted = 0;

  // Does the device have a master volume control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyMute, kAudioDevicePropertyScopeInput, 0};
  Boolean hasProperty =
      AudioObjectHasProperty(_inputDeviceID, &propertyAddress);
  if (hasProperty) {
    size = sizeof(muted);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
        _inputDeviceID, &propertyAddress, 0, NULL, &size, &muted));

    // 1 means muted
    enabled = static_cast<bool>(muted);
  } else {
    // Otherwise check if all channels are muted.
    for (UInt32 i = 1; i <= _noInputChannels; i++) {
      muted = 0;
      propertyAddress.mElement = i;
      hasProperty = AudioObjectHasProperty(_inputDeviceID, &propertyAddress);
      if (hasProperty) {
        size = sizeof(channelMuted);
        WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
            _inputDeviceID, &propertyAddress, 0, NULL, &size, &channelMuted));

        muted = (muted && channelMuted);
        channels++;
      }
    }

    if (channels == 0) {
      LOG(LS_WARNING) << "Unable to get mute for any channel";
      return -1;
    }

    assert(channels > 0);
    // 1 means muted
    enabled = static_cast<bool>(muted);
  }

  LOG(LS_VERBOSE) << "AudioMixerManagerMac::MicrophoneMute() => enabled="
                  << enabled;

  return 0;
}

int32_t AudioMixerManagerMac::MicrophoneVolumeIsAvailable(bool& available) {
  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;

  // Does the capture device have a master volume control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeInput, 0};
  Boolean isSettable = false;
  err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
                                      &isSettable);
  if (err == noErr && isSettable) {
    available = true;
    return 0;
  }

  // Otherwise try to set each channel.
  for (UInt32 i = 1; i <= _noInputChannels; i++) {
    propertyAddress.mElement = i;
    isSettable = false;
    err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
                                        &isSettable);
    if (err != noErr || !isSettable) {
      available = false;
      LOG(LS_WARNING) << "Volume cannot be set for input channel " << i
                      << ", err=" << err;
      return -1;
    }
  }

  available = true;
  return 0;
}

int32_t AudioMixerManagerMac::SetMicrophoneVolume(uint32_t volume) {
  LOG(LS_VERBOSE) << "AudioMixerManagerMac::SetMicrophoneVolume(volume="
                  << volume << ")";

  rtc::CritScope lock(&_critSect);

  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;
  UInt32 size = 0;
  bool success = false;

  // volume range is 0.0 - 1.0, convert from 0 - 255
  const Float32 vol = (Float32)(volume / 255.0);

  assert(vol <= 1.0 && vol >= 0.0);

  // Does the capture device have a master volume control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeInput, 0};
  Boolean isSettable = false;
  err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
                                      &isSettable);
  if (err == noErr && isSettable) {
    size = sizeof(vol);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
        _inputDeviceID, &propertyAddress, 0, NULL, size, &vol));

    return 0;
  }

  // Otherwise try to set each channel.
  for (UInt32 i = 1; i <= _noInputChannels; i++) {
    propertyAddress.mElement = i;
    isSettable = false;
    err = AudioObjectIsPropertySettable(_inputDeviceID, &propertyAddress,
                                        &isSettable);
    if (err == noErr && isSettable) {
      size = sizeof(vol);
      WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData(
          _inputDeviceID, &propertyAddress, 0, NULL, size, &vol));
    }
    success = true;
  }

  if (!success) {
    LOG(LS_WARNING) << "Unable to set a level on any input channel";
    return -1;
  }

  return 0;
}

int32_t AudioMixerManagerMac::MicrophoneVolume(uint32_t& volume) const {
  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  OSStatus err = noErr;
  UInt32 size = 0;
  unsigned int channels = 0;
  Float32 channelVol = 0;
  Float32 volFloat32 = 0;

  // Does the device have a master volume control?
  // If so, use it exclusively.
  AudioObjectPropertyAddress propertyAddress = {
      kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeInput, 0};
  Boolean hasProperty =
      AudioObjectHasProperty(_inputDeviceID, &propertyAddress);
  if (hasProperty) {
    size = sizeof(volFloat32);
    WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
        _inputDeviceID, &propertyAddress, 0, NULL, &size, &volFloat32));

    // vol 0.0 to 1.0 -> convert to 0 - 255
    volume = static_cast<uint32_t>(volFloat32 * 255 + 0.5);
  } else {
    // Otherwise get the average volume across channels.
    volFloat32 = 0;
    for (UInt32 i = 1; i <= _noInputChannels; i++) {
      channelVol = 0;
      propertyAddress.mElement = i;
      hasProperty = AudioObjectHasProperty(_inputDeviceID, &propertyAddress);
      if (hasProperty) {
        size = sizeof(channelVol);
        WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
            _inputDeviceID, &propertyAddress, 0, NULL, &size, &channelVol));

        volFloat32 += channelVol;
        channels++;
      }
    }

    if (channels == 0) {
      LOG(LS_WARNING) << "Unable to get a level on any channel";
      return -1;
    }

    assert(channels > 0);
    // vol 0.0 to 1.0 -> convert to 0 - 255
    volume = static_cast<uint32_t>(255 * volFloat32 / channels + 0.5);
  }

  LOG(LS_VERBOSE) << "AudioMixerManagerMac::MicrophoneVolume() => vol="
                  << volume;

  return 0;
}

int32_t AudioMixerManagerMac::MaxMicrophoneVolume(uint32_t& maxVolume) const {
  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  // volume range is 0.0 to 1.0
  // we convert that to 0 - 255
  maxVolume = 255;

  return 0;
}

int32_t AudioMixerManagerMac::MinMicrophoneVolume(uint32_t& minVolume) const {
  if (_inputDeviceID == kAudioObjectUnknown) {
    LOG(LS_WARNING) << "device ID has not been set";
    return -1;
  }

  // volume range is 0.0 to 1.0
  // we convert that to 0 - 10
  minVolume = 0;

  return 0;
}

// ============================================================================
//                                 Private Methods
// ============================================================================

// CoreAudio errors are best interpreted as four character strings.
void AudioMixerManagerMac::logCAMsg(const rtc::LoggingSeverity sev,
                              const char* msg,
                              const char* err) {
  RTC_DCHECK(msg != NULL);
  RTC_DCHECK(err != NULL);
  RTC_DCHECK(sev == rtc::LS_ERROR || sev == rtc::LS_WARNING);

#ifdef WEBRTC_ARCH_BIG_ENDIAN
  switch (sev) {
    case rtc::LS_ERROR:
      LOG(LS_ERROR) << msg << ": " << err[0] << err[1] << err[2] << err[3];
      break;
    case rtc::LS_WARNING:
      LOG(LS_WARNING) << 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:
      LOG(LS_ERROR) << msg << ": " << err[3] << err[2] << err[1] << err[0];
      break;
    case rtc::LS_WARNING:
      LOG(LS_WARNING) << msg << ": " << err[3] << err[2] << err[1] << err[0];
      break;
    default:
      break;
  }
#endif
}

}  // namespace webrtc
// EOF
