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

#include "webrtc/modules/audio_device/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
