/*
 *  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.
 */

#pragma warning(disable : 4995)  // name was marked as #pragma deprecated

#if (_MSC_VER >= 1310) && (_MSC_VER < 1400)
// Reports the major and minor versions of the compiler.
// For example, 1310 for Microsoft Visual C++ .NET 2003. 1310 represents version
// 13 and a 1.0 point release. The Visual C++ 2005 compiler version is 1400.
// Type cl /? at the command line to see the major and minor versions of your
// compiler along with the build number.
#pragma message(">> INFO: Windows Core Audio is not supported in VS 2003")
#endif

#include "modules/audio_device/audio_device_config.h"

#ifdef WEBRTC_WINDOWS_CORE_AUDIO_BUILD

#include "modules/audio_device/win/audio_device_core_win.h"

#include <assert.h>
#include <string.h>

#include <comdef.h>
#include <dmo.h>
#include <functiondiscoverykeys_devpkey.h>
#include <mmsystem.h>
#include <strsafe.h>
#include <uuids.h>
#include <windows.h>

#include <iomanip>

#include "rtc_base/logging.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/string_utils.h"
#include "rtc_base/thread_annotations.h"
#include "system_wrappers/include/sleep.h"

// Macro that calls a COM method returning HRESULT value.
#define EXIT_ON_ERROR(hres) \
  do {                      \
    if (FAILED(hres))       \
      goto Exit;            \
  } while (0)

// Macro that continues to a COM error.
#define CONTINUE_ON_ERROR(hres) \
  do {                          \
    if (FAILED(hres))           \
      goto Next;                \
  } while (0)

// Macro that releases a COM object if not NULL.
#define SAFE_RELEASE(p) \
  do {                  \
    if ((p)) {          \
      (p)->Release();   \
      (p) = NULL;       \
    }                   \
  } while (0)

#define ROUND(x) ((x) >= 0 ? (int)((x) + 0.5) : (int)((x)-0.5))

// REFERENCE_TIME time units per millisecond
#define REFTIMES_PER_MILLISEC 10000

typedef struct tagTHREADNAME_INFO {
  DWORD dwType;      // must be 0x1000
  LPCSTR szName;     // pointer to name (in user addr space)
  DWORD dwThreadID;  // thread ID (-1=caller thread)
  DWORD dwFlags;     // reserved for future use, must be zero
} THREADNAME_INFO;

namespace webrtc {
namespace {

enum { COM_THREADING_MODEL = COINIT_MULTITHREADED };

enum { kAecCaptureStreamIndex = 0, kAecRenderStreamIndex = 1 };

// An implementation of IMediaBuffer, as required for
// IMediaObject::ProcessOutput(). After consuming data provided by
// ProcessOutput(), call SetLength() to update the buffer availability.
//
// Example implementation:
// http://msdn.microsoft.com/en-us/library/dd376684(v=vs.85).aspx
class MediaBufferImpl final : public IMediaBuffer {
 public:
  explicit MediaBufferImpl(DWORD maxLength)
      : _data(new BYTE[maxLength]),
        _length(0),
        _maxLength(maxLength),
        _refCount(0) {}

  // IMediaBuffer methods.
  STDMETHOD(GetBufferAndLength(BYTE** ppBuffer, DWORD* pcbLength)) {
    if (!ppBuffer || !pcbLength) {
      return E_POINTER;
    }

    *ppBuffer = _data;
    *pcbLength = _length;

    return S_OK;
  }

  STDMETHOD(GetMaxLength(DWORD* pcbMaxLength)) {
    if (!pcbMaxLength) {
      return E_POINTER;
    }

    *pcbMaxLength = _maxLength;
    return S_OK;
  }

  STDMETHOD(SetLength(DWORD cbLength)) {
    if (cbLength > _maxLength) {
      return E_INVALIDARG;
    }

    _length = cbLength;
    return S_OK;
  }

  // IUnknown methods.
  STDMETHOD_(ULONG, AddRef()) { return InterlockedIncrement(&_refCount); }

  STDMETHOD(QueryInterface(REFIID riid, void** ppv)) {
    if (!ppv) {
      return E_POINTER;
    } else if (riid != IID_IMediaBuffer && riid != IID_IUnknown) {
      return E_NOINTERFACE;
    }

    *ppv = static_cast<IMediaBuffer*>(this);
    AddRef();
    return S_OK;
  }

  STDMETHOD_(ULONG, Release()) {
    LONG refCount = InterlockedDecrement(&_refCount);
    if (refCount == 0) {
      delete this;
    }

    return refCount;
  }

 private:
  ~MediaBufferImpl() { delete[] _data; }

  BYTE* _data;
  DWORD _length;
  const DWORD _maxLength;
  LONG _refCount;
};
}  // namespace

// ============================================================================
//                              Static Methods
// ============================================================================

// ----------------------------------------------------------------------------
//  CoreAudioIsSupported
// ----------------------------------------------------------------------------

bool AudioDeviceWindowsCore::CoreAudioIsSupported() {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  bool MMDeviceIsAvailable(false);
  bool coreAudioIsSupported(false);

  HRESULT hr(S_OK);
  wchar_t buf[MAXERRORLENGTH];
  wchar_t errorText[MAXERRORLENGTH];

  // 1) Check if Windows version is Vista SP1 or later.
  //
  // CoreAudio is only available on Vista SP1 and later.
  //
  OSVERSIONINFOEX osvi;
  DWORDLONG dwlConditionMask = 0;
  int op = VER_LESS_EQUAL;

  // Initialize the OSVERSIONINFOEX structure.
  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  osvi.dwMajorVersion = 6;
  osvi.dwMinorVersion = 0;
  osvi.wServicePackMajor = 0;
  osvi.wServicePackMinor = 0;
  osvi.wProductType = VER_NT_WORKSTATION;

  // Initialize the condition mask.
  VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
  VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
  VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, op);
  VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMINOR, op);
  VER_SET_CONDITION(dwlConditionMask, VER_PRODUCT_TYPE, VER_EQUAL);

  DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION |
                     VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
                     VER_PRODUCT_TYPE;

  // Perform the test.
  BOOL isVistaRTMorXP = VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask);
  if (isVistaRTMorXP != 0) {
    RTC_LOG(LS_VERBOSE)
        << "*** Windows Core Audio is only supported on Vista SP1 or later"
        << " => will revert to the Wave API ***";
    return false;
  }

  // 2) Initializes the COM library for use by the calling thread.

  // The COM init wrapper sets the thread's concurrency model to MTA,
  // and creates a new apartment for the thread if one is required. The
  // wrapper also ensures that each call to CoInitializeEx is balanced
  // by a corresponding call to CoUninitialize.
  //
  ScopedCOMInitializer comInit(ScopedCOMInitializer::kMTA);
  if (!comInit.succeeded()) {
    // Things will work even if an STA thread is calling this method but we
    // want to ensure that MTA is used and therefore return false here.
    return false;
  }

  // 3) Check if the MMDevice API is available.
  //
  // The Windows Multimedia Device (MMDevice) API enables audio clients to
  // discover audio endpoint devices, determine their capabilities, and create
  // driver instances for those devices.
  // Header file Mmdeviceapi.h defines the interfaces in the MMDevice API.
  // The MMDevice API consists of several interfaces. The first of these is the
  // IMMDeviceEnumerator interface. To access the interfaces in the MMDevice
  // API, a client obtains a reference to the IMMDeviceEnumerator interface of a
  // device-enumerator object by calling the CoCreateInstance function.
  //
  // Through the IMMDeviceEnumerator interface, the client can obtain references
  // to the other interfaces in the MMDevice API. The MMDevice API implements
  // the following interfaces:
  //
  // IMMDevice            Represents an audio device.
  // IMMDeviceCollection  Represents a collection of audio devices.
  // IMMDeviceEnumerator  Provides methods for enumerating audio devices.
  // IMMEndpoint          Represents an audio endpoint device.
  //
  IMMDeviceEnumerator* pIMMD(NULL);
  const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
  const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);

  hr = CoCreateInstance(
      CLSID_MMDeviceEnumerator,  // GUID value of MMDeviceEnumerator coclass
      NULL, CLSCTX_ALL,
      IID_IMMDeviceEnumerator,  // GUID value of the IMMDeviceEnumerator
                                // interface
      (void**)&pIMMD);

  if (FAILED(hr)) {
    RTC_LOG(LS_ERROR) << "AudioDeviceWindowsCore::CoreAudioIsSupported()"
                      << " Failed to create the required COM object (hr=" << hr
                      << ")";
    RTC_LOG(LS_VERBOSE) << "AudioDeviceWindowsCore::CoreAudioIsSupported()"
                        << " CoCreateInstance(MMDeviceEnumerator) failed (hr="
                        << hr << ")";

    const DWORD dwFlags =
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
    const DWORD dwLangID = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);

    // Gets the system's human readable message string for this HRESULT.
    // All error message in English by default.
    DWORD messageLength = ::FormatMessageW(dwFlags, 0, hr, dwLangID, errorText,
                                           MAXERRORLENGTH, NULL);

    assert(messageLength <= MAXERRORLENGTH);

    // Trims tailing white space (FormatMessage() leaves a trailing cr-lf.).
    for (; messageLength && ::isspace(errorText[messageLength - 1]);
         --messageLength) {
      errorText[messageLength - 1] = '\0';
    }

    StringCchPrintfW(buf, MAXERRORLENGTH, L"Error details: ");
    StringCchCatW(buf, MAXERRORLENGTH, errorText);
    RTC_LOG(LS_VERBOSE) << buf;
  } else {
    MMDeviceIsAvailable = true;
    RTC_LOG(LS_VERBOSE)
        << "AudioDeviceWindowsCore::CoreAudioIsSupported()"
        << " CoCreateInstance(MMDeviceEnumerator) succeeded (hr=" << hr << ")";
    SAFE_RELEASE(pIMMD);
  }

  // 4) Verify that we can create and initialize our Core Audio class.
  //
  // Also, perform a limited "API test" to ensure that Core Audio is supported
  // for all devices.
  //
  if (MMDeviceIsAvailable) {
    coreAudioIsSupported = false;

    AudioDeviceWindowsCore* p = new AudioDeviceWindowsCore();
    if (p == NULL) {
      return false;
    }

    int ok(0);
    int temp_ok(0);
    bool available(false);

    if (p->Init() != InitStatus::OK) {
      ok |= -1;
    }

    int16_t numDevsRec = p->RecordingDevices();
    for (uint16_t i = 0; i < numDevsRec; i++) {
      ok |= p->SetRecordingDevice(i);
      temp_ok = p->RecordingIsAvailable(available);
      ok |= temp_ok;
      ok |= (available == false);
      if (available) {
        ok |= p->InitMicrophone();
      }
      if (ok) {
        RTC_LOG(LS_WARNING)
            << "AudioDeviceWindowsCore::CoreAudioIsSupported()"
            << " Failed to use Core Audio Recording for device id=" << i;
      }
    }

    int16_t numDevsPlay = p->PlayoutDevices();
    for (uint16_t i = 0; i < numDevsPlay; i++) {
      ok |= p->SetPlayoutDevice(i);
      temp_ok = p->PlayoutIsAvailable(available);
      ok |= temp_ok;
      ok |= (available == false);
      if (available) {
        ok |= p->InitSpeaker();
      }
      if (ok) {
        RTC_LOG(LS_WARNING)
            << "AudioDeviceWindowsCore::CoreAudioIsSupported()"
            << " Failed to use Core Audio Playout for device id=" << i;
      }
    }

    ok |= p->Terminate();

    if (ok == 0) {
      coreAudioIsSupported = true;
    }

    delete p;
  }

  if (coreAudioIsSupported) {
    RTC_LOG(LS_VERBOSE) << "*** Windows Core Audio is supported ***";
  } else {
    RTC_LOG(LS_VERBOSE) << "*** Windows Core Audio is NOT supported"
                        << " => will revert to the Wave API ***";
  }

  return (coreAudioIsSupported);
}

// ============================================================================
//                            Construction & Destruction
// ============================================================================

// ----------------------------------------------------------------------------
//  AudioDeviceWindowsCore() - ctor
// ----------------------------------------------------------------------------

AudioDeviceWindowsCore::AudioDeviceWindowsCore()
    : _avrtLibrary(NULL),
      _winSupportAvrt(false),
      _comInit(ScopedCOMInitializer::kMTA),
      _ptrAudioBuffer(NULL),
      _ptrEnumerator(NULL),
      _ptrRenderCollection(NULL),
      _ptrCaptureCollection(NULL),
      _ptrDeviceOut(NULL),
      _ptrDeviceIn(NULL),
      _ptrClientOut(NULL),
      _ptrClientIn(NULL),
      _ptrRenderClient(NULL),
      _ptrCaptureClient(NULL),
      _ptrCaptureVolume(NULL),
      _ptrRenderSimpleVolume(NULL),
      _dmo(NULL),
      _mediaBuffer(NULL),
      _builtInAecEnabled(false),
      _hRenderSamplesReadyEvent(NULL),
      _hPlayThread(NULL),
      _hRenderStartedEvent(NULL),
      _hShutdownRenderEvent(NULL),
      _hCaptureSamplesReadyEvent(NULL),
      _hRecThread(NULL),
      _hCaptureStartedEvent(NULL),
      _hShutdownCaptureEvent(NULL),
      _hMmTask(NULL),
      _playAudioFrameSize(0),
      _playSampleRate(0),
      _playBlockSize(0),
      _playChannels(2),
      _sndCardPlayDelay(0),
      _sndCardRecDelay(0),
      _writtenSamples(0),
      _readSamples(0),
      _recAudioFrameSize(0),
      _recSampleRate(0),
      _recBlockSize(0),
      _recChannels(2),
      _initialized(false),
      _recording(false),
      _playing(false),
      _recIsInitialized(false),
      _playIsInitialized(false),
      _speakerIsInitialized(false),
      _microphoneIsInitialized(false),
      _usingInputDeviceIndex(false),
      _usingOutputDeviceIndex(false),
      _inputDevice(AudioDeviceModule::kDefaultCommunicationDevice),
      _outputDevice(AudioDeviceModule::kDefaultCommunicationDevice),
      _inputDeviceIndex(0),
      _outputDeviceIndex(0) {
  RTC_LOG(LS_INFO) << __FUNCTION__ << " created";
  assert(_comInit.succeeded());

  // Try to load the Avrt DLL
  if (!_avrtLibrary) {
    // Get handle to the Avrt DLL module.
    _avrtLibrary = LoadLibrary(TEXT("Avrt.dll"));
    if (_avrtLibrary) {
      // Handle is valid (should only happen if OS larger than vista & win7).
      // Try to get the function addresses.
      RTC_LOG(LS_VERBOSE) << "AudioDeviceWindowsCore::AudioDeviceWindowsCore()"
                          << " The Avrt DLL module is now loaded";

      _PAvRevertMmThreadCharacteristics =
          (PAvRevertMmThreadCharacteristics)GetProcAddress(
              _avrtLibrary, "AvRevertMmThreadCharacteristics");
      _PAvSetMmThreadCharacteristicsA =
          (PAvSetMmThreadCharacteristicsA)GetProcAddress(
              _avrtLibrary, "AvSetMmThreadCharacteristicsA");
      _PAvSetMmThreadPriority = (PAvSetMmThreadPriority)GetProcAddress(
          _avrtLibrary, "AvSetMmThreadPriority");

      if (_PAvRevertMmThreadCharacteristics &&
          _PAvSetMmThreadCharacteristicsA && _PAvSetMmThreadPriority) {
        RTC_LOG(LS_VERBOSE)
            << "AudioDeviceWindowsCore::AudioDeviceWindowsCore()"
            << " AvRevertMmThreadCharacteristics() is OK";
        RTC_LOG(LS_VERBOSE)
            << "AudioDeviceWindowsCore::AudioDeviceWindowsCore()"
            << " AvSetMmThreadCharacteristicsA() is OK";
        RTC_LOG(LS_VERBOSE)
            << "AudioDeviceWindowsCore::AudioDeviceWindowsCore()"
            << " AvSetMmThreadPriority() is OK";
        _winSupportAvrt = true;
      }
    }
  }

  // Create our samples ready events - we want auto reset events that start in
  // the not-signaled state. The state of an auto-reset event object remains
  // signaled until a single waiting thread is released, at which time the
  // system automatically sets the state to nonsignaled. If no threads are
  // waiting, the event object's state remains signaled. (Except for
  // _hShutdownCaptureEvent, which is used to shutdown multiple threads).
  _hRenderSamplesReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  _hCaptureSamplesReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  _hShutdownRenderEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  _hShutdownCaptureEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  _hRenderStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  _hCaptureStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

  _perfCounterFreq.QuadPart = 1;
  _perfCounterFactor = 0.0;

  // list of number of channels to use on recording side
  _recChannelsPrioList[0] = 2;  // stereo is prio 1
  _recChannelsPrioList[1] = 1;  // mono is prio 2
  _recChannelsPrioList[2] = 4;  // quad is prio 3

  // list of number of channels to use on playout side
  _playChannelsPrioList[0] = 2;  // stereo is prio 1
  _playChannelsPrioList[1] = 1;  // mono is prio 2

  HRESULT hr;

  // We know that this API will work since it has already been verified in
  // CoreAudioIsSupported, hence no need to check for errors here as well.

  // Retrive the IMMDeviceEnumerator API (should load the MMDevAPI.dll)
  // TODO(henrika): we should probably move this allocation to Init() instead
  // and deallocate in Terminate() to make the implementation more symmetric.
  CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,
                   __uuidof(IMMDeviceEnumerator),
                   reinterpret_cast<void**>(&_ptrEnumerator));
  assert(NULL != _ptrEnumerator);

  // DMO initialization for built-in WASAPI AEC.
  {
    IMediaObject* ptrDMO = NULL;
    hr = CoCreateInstance(CLSID_CWMAudioAEC, NULL, CLSCTX_INPROC_SERVER,
                          IID_IMediaObject, reinterpret_cast<void**>(&ptrDMO));
    if (FAILED(hr) || ptrDMO == NULL) {
      // Since we check that _dmo is non-NULL in EnableBuiltInAEC(), the
      // feature is prevented from being enabled.
      _builtInAecEnabled = false;
      _TraceCOMError(hr);
    }
    _dmo = ptrDMO;
    SAFE_RELEASE(ptrDMO);
  }
}

// ----------------------------------------------------------------------------
//  AudioDeviceWindowsCore() - dtor
// ----------------------------------------------------------------------------

AudioDeviceWindowsCore::~AudioDeviceWindowsCore() {
  RTC_LOG(LS_INFO) << __FUNCTION__ << " destroyed";

  Terminate();

  // The IMMDeviceEnumerator is created during construction. Must release
  // it here and not in Terminate() since we don't recreate it in Init().
  SAFE_RELEASE(_ptrEnumerator);

  _ptrAudioBuffer = NULL;

  if (NULL != _hRenderSamplesReadyEvent) {
    CloseHandle(_hRenderSamplesReadyEvent);
    _hRenderSamplesReadyEvent = NULL;
  }

  if (NULL != _hCaptureSamplesReadyEvent) {
    CloseHandle(_hCaptureSamplesReadyEvent);
    _hCaptureSamplesReadyEvent = NULL;
  }

  if (NULL != _hRenderStartedEvent) {
    CloseHandle(_hRenderStartedEvent);
    _hRenderStartedEvent = NULL;
  }

  if (NULL != _hCaptureStartedEvent) {
    CloseHandle(_hCaptureStartedEvent);
    _hCaptureStartedEvent = NULL;
  }

  if (NULL != _hShutdownRenderEvent) {
    CloseHandle(_hShutdownRenderEvent);
    _hShutdownRenderEvent = NULL;
  }

  if (NULL != _hShutdownCaptureEvent) {
    CloseHandle(_hShutdownCaptureEvent);
    _hShutdownCaptureEvent = NULL;
  }

  if (_avrtLibrary) {
    BOOL freeOK = FreeLibrary(_avrtLibrary);
    if (!freeOK) {
      RTC_LOG(LS_WARNING)
          << "AudioDeviceWindowsCore::~AudioDeviceWindowsCore()"
          << " failed to free the loaded Avrt DLL module correctly";
    } else {
      RTC_LOG(LS_WARNING) << "AudioDeviceWindowsCore::~AudioDeviceWindowsCore()"
                          << " the Avrt DLL module is now unloaded";
    }
  }
}

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

// ----------------------------------------------------------------------------
//  AttachAudioBuffer
// ----------------------------------------------------------------------------

void AudioDeviceWindowsCore::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
  _ptrAudioBuffer = audioBuffer;

  // Inform the AudioBuffer about default settings for this implementation.
  // Set all values to zero here since the actual settings will be done by
  // InitPlayout and InitRecording later.
  _ptrAudioBuffer->SetRecordingSampleRate(0);
  _ptrAudioBuffer->SetPlayoutSampleRate(0);
  _ptrAudioBuffer->SetRecordingChannels(0);
  _ptrAudioBuffer->SetPlayoutChannels(0);
}

// ----------------------------------------------------------------------------
//  ActiveAudioLayer
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::ActiveAudioLayer(
    AudioDeviceModule::AudioLayer& audioLayer) const {
  audioLayer = AudioDeviceModule::kWindowsCoreAudio;
  return 0;
}

// ----------------------------------------------------------------------------
//  Init
// ----------------------------------------------------------------------------

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

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

  // Enumerate all audio rendering and capturing endpoint devices.
  // Note that, some of these will not be able to select by the user.
  // The complete collection is for internal use only.
  _EnumerateEndpointDevicesAll(eRender);
  _EnumerateEndpointDevicesAll(eCapture);

  _initialized = true;

  return InitStatus::OK;
}

// ----------------------------------------------------------------------------
//  Terminate
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::Terminate() {
  rtc::CritScope lock(&_critSect);

  if (!_initialized) {
    return 0;
  }

  _initialized = false;
  _speakerIsInitialized = false;
  _microphoneIsInitialized = false;
  _playing = false;
  _recording = false;

  SAFE_RELEASE(_ptrRenderCollection);
  SAFE_RELEASE(_ptrCaptureCollection);
  SAFE_RELEASE(_ptrDeviceOut);
  SAFE_RELEASE(_ptrDeviceIn);
  SAFE_RELEASE(_ptrClientOut);
  SAFE_RELEASE(_ptrClientIn);
  SAFE_RELEASE(_ptrRenderClient);
  SAFE_RELEASE(_ptrCaptureClient);
  SAFE_RELEASE(_ptrCaptureVolume);
  SAFE_RELEASE(_ptrRenderSimpleVolume);

  return 0;
}

// ----------------------------------------------------------------------------
//  Initialized
// ----------------------------------------------------------------------------

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

// ----------------------------------------------------------------------------
//  InitSpeaker
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::InitSpeaker() {
  rtc::CritScope lock(&_critSect);

  if (_playing) {
    return -1;
  }

  if (_ptrDeviceOut == NULL) {
    return -1;
  }

  if (_usingOutputDeviceIndex) {
    int16_t nDevices = PlayoutDevices();
    if (_outputDeviceIndex > (nDevices - 1)) {
      RTC_LOG(LS_ERROR) << "current device selection is invalid => unable to"
                        << " initialize";
      return -1;
    }
  }

  int32_t ret(0);

  SAFE_RELEASE(_ptrDeviceOut);
  if (_usingOutputDeviceIndex) {
    // Refresh the selected rendering endpoint device using current index
    ret = _GetListDevice(eRender, _outputDeviceIndex, &_ptrDeviceOut);
  } else {
    ERole role;
    (_outputDevice == AudioDeviceModule::kDefaultDevice)
        ? role = eConsole
        : role = eCommunications;
    // Refresh the selected rendering endpoint device using role
    ret = _GetDefaultDevice(eRender, role, &_ptrDeviceOut);
  }

  if (ret != 0 || (_ptrDeviceOut == NULL)) {
    RTC_LOG(LS_ERROR) << "failed to initialize the rendering enpoint device";
    SAFE_RELEASE(_ptrDeviceOut);
    return -1;
  }

  IAudioSessionManager* pManager = NULL;
  ret = _ptrDeviceOut->Activate(__uuidof(IAudioSessionManager), CLSCTX_ALL,
                                NULL, (void**)&pManager);
  if (ret != 0 || pManager == NULL) {
    RTC_LOG(LS_ERROR) << "failed to initialize the render manager";
    SAFE_RELEASE(pManager);
    return -1;
  }

  SAFE_RELEASE(_ptrRenderSimpleVolume);
  ret = pManager->GetSimpleAudioVolume(NULL, FALSE, &_ptrRenderSimpleVolume);
  if (ret != 0 || _ptrRenderSimpleVolume == NULL) {
    RTC_LOG(LS_ERROR) << "failed to initialize the render simple volume";
    SAFE_RELEASE(pManager);
    SAFE_RELEASE(_ptrRenderSimpleVolume);
    return -1;
  }
  SAFE_RELEASE(pManager);

  _speakerIsInitialized = true;

  return 0;
}

// ----------------------------------------------------------------------------
//  InitMicrophone
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::InitMicrophone() {
  rtc::CritScope lock(&_critSect);

  if (_recording) {
    return -1;
  }

  if (_ptrDeviceIn == NULL) {
    return -1;
  }

  if (_usingInputDeviceIndex) {
    int16_t nDevices = RecordingDevices();
    if (_inputDeviceIndex > (nDevices - 1)) {
      RTC_LOG(LS_ERROR) << "current device selection is invalid => unable to"
                        << " initialize";
      return -1;
    }
  }

  int32_t ret(0);

  SAFE_RELEASE(_ptrDeviceIn);
  if (_usingInputDeviceIndex) {
    // Refresh the selected capture endpoint device using current index
    ret = _GetListDevice(eCapture, _inputDeviceIndex, &_ptrDeviceIn);
  } else {
    ERole role;
    (_inputDevice == AudioDeviceModule::kDefaultDevice)
        ? role = eConsole
        : role = eCommunications;
    // Refresh the selected capture endpoint device using role
    ret = _GetDefaultDevice(eCapture, role, &_ptrDeviceIn);
  }

  if (ret != 0 || (_ptrDeviceIn == NULL)) {
    RTC_LOG(LS_ERROR) << "failed to initialize the capturing enpoint device";
    SAFE_RELEASE(_ptrDeviceIn);
    return -1;
  }

  SAFE_RELEASE(_ptrCaptureVolume);
  ret = _ptrDeviceIn->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                               reinterpret_cast<void**>(&_ptrCaptureVolume));
  if (ret != 0 || _ptrCaptureVolume == NULL) {
    RTC_LOG(LS_ERROR) << "failed to initialize the capture volume";
    SAFE_RELEASE(_ptrCaptureVolume);
    return -1;
  }

  _microphoneIsInitialized = true;

  return 0;
}

// ----------------------------------------------------------------------------
//  SpeakerIsInitialized
// ----------------------------------------------------------------------------

bool AudioDeviceWindowsCore::SpeakerIsInitialized() const {
  return (_speakerIsInitialized);
}

// ----------------------------------------------------------------------------
//  MicrophoneIsInitialized
// ----------------------------------------------------------------------------

bool AudioDeviceWindowsCore::MicrophoneIsInitialized() const {
  return (_microphoneIsInitialized);
}

// ----------------------------------------------------------------------------
//  SpeakerVolumeIsAvailable
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SpeakerVolumeIsAvailable(bool& available) {
  rtc::CritScope lock(&_critSect);

  if (_ptrDeviceOut == NULL) {
    return -1;
  }

  HRESULT hr = S_OK;
  IAudioSessionManager* pManager = NULL;
  ISimpleAudioVolume* pVolume = NULL;

  hr = _ptrDeviceOut->Activate(__uuidof(IAudioSessionManager), CLSCTX_ALL, NULL,
                               (void**)&pManager);
  EXIT_ON_ERROR(hr);

  hr = pManager->GetSimpleAudioVolume(NULL, FALSE, &pVolume);
  EXIT_ON_ERROR(hr);

  float volume(0.0f);
  hr = pVolume->GetMasterVolume(&volume);
  if (FAILED(hr)) {
    available = false;
  }
  available = true;

  SAFE_RELEASE(pManager);
  SAFE_RELEASE(pVolume);

  return 0;

Exit:
  _TraceCOMError(hr);
  SAFE_RELEASE(pManager);
  SAFE_RELEASE(pVolume);
  return -1;
}

// ----------------------------------------------------------------------------
//  SetSpeakerVolume
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetSpeakerVolume(uint32_t volume) {
  {
    rtc::CritScope lock(&_critSect);

    if (!_speakerIsInitialized) {
      return -1;
    }

    if (_ptrDeviceOut == NULL) {
      return -1;
    }
  }

  if (volume < (uint32_t)MIN_CORE_SPEAKER_VOLUME ||
      volume > (uint32_t)MAX_CORE_SPEAKER_VOLUME) {
    return -1;
  }

  HRESULT hr = S_OK;

  // scale input volume to valid range (0.0 to 1.0)
  const float fLevel = (float)volume / MAX_CORE_SPEAKER_VOLUME;
  _volumeMutex.Enter();
  hr = _ptrRenderSimpleVolume->SetMasterVolume(fLevel, NULL);
  _volumeMutex.Leave();
  EXIT_ON_ERROR(hr);

  return 0;

Exit:
  _TraceCOMError(hr);
  return -1;
}

// ----------------------------------------------------------------------------
//  SpeakerVolume
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SpeakerVolume(uint32_t& volume) const {
  {
    rtc::CritScope lock(&_critSect);

    if (!_speakerIsInitialized) {
      return -1;
    }

    if (_ptrDeviceOut == NULL) {
      return -1;
    }
  }

  HRESULT hr = S_OK;
  float fLevel(0.0f);

  _volumeMutex.Enter();
  hr = _ptrRenderSimpleVolume->GetMasterVolume(&fLevel);
  _volumeMutex.Leave();
  EXIT_ON_ERROR(hr);

  // scale input volume range [0.0,1.0] to valid output range
  volume = static_cast<uint32_t>(fLevel * MAX_CORE_SPEAKER_VOLUME);

  return 0;

Exit:
  _TraceCOMError(hr);
  return -1;
}

// ----------------------------------------------------------------------------
//  MaxSpeakerVolume
//
//  The internal range for Core Audio is 0.0 to 1.0, where 0.0 indicates
//  silence and 1.0 indicates full volume (no attenuation).
//  We add our (webrtc-internal) own max level to match the Wave API and
//  how it is used today in VoE.
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::MaxSpeakerVolume(uint32_t& maxVolume) const {
  if (!_speakerIsInitialized) {
    return -1;
  }

  maxVolume = static_cast<uint32_t>(MAX_CORE_SPEAKER_VOLUME);

  return 0;
}

// ----------------------------------------------------------------------------
//  MinSpeakerVolume
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::MinSpeakerVolume(uint32_t& minVolume) const {
  if (!_speakerIsInitialized) {
    return -1;
  }

  minVolume = static_cast<uint32_t>(MIN_CORE_SPEAKER_VOLUME);

  return 0;
}

// ----------------------------------------------------------------------------
//  SpeakerMuteIsAvailable
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SpeakerMuteIsAvailable(bool& available) {
  rtc::CritScope lock(&_critSect);

  if (_ptrDeviceOut == NULL) {
    return -1;
  }

  HRESULT hr = S_OK;
  IAudioEndpointVolume* pVolume = NULL;

  // Query the speaker system mute state.
  hr = _ptrDeviceOut->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                               reinterpret_cast<void**>(&pVolume));
  EXIT_ON_ERROR(hr);

  BOOL mute;
  hr = pVolume->GetMute(&mute);
  if (FAILED(hr))
    available = false;
  else
    available = true;

  SAFE_RELEASE(pVolume);

  return 0;

Exit:
  _TraceCOMError(hr);
  SAFE_RELEASE(pVolume);
  return -1;
}

// ----------------------------------------------------------------------------
//  SetSpeakerMute
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetSpeakerMute(bool enable) {
  rtc::CritScope lock(&_critSect);

  if (!_speakerIsInitialized) {
    return -1;
  }

  if (_ptrDeviceOut == NULL) {
    return -1;
  }

  HRESULT hr = S_OK;
  IAudioEndpointVolume* pVolume = NULL;

  // Set the speaker system mute state.
  hr = _ptrDeviceOut->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                               reinterpret_cast<void**>(&pVolume));
  EXIT_ON_ERROR(hr);

  const BOOL mute(enable);
  hr = pVolume->SetMute(mute, NULL);
  EXIT_ON_ERROR(hr);

  SAFE_RELEASE(pVolume);

  return 0;

Exit:
  _TraceCOMError(hr);
  SAFE_RELEASE(pVolume);
  return -1;
}

// ----------------------------------------------------------------------------
//  SpeakerMute
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SpeakerMute(bool& enabled) const {
  if (!_speakerIsInitialized) {
    return -1;
  }

  if (_ptrDeviceOut == NULL) {
    return -1;
  }

  HRESULT hr = S_OK;
  IAudioEndpointVolume* pVolume = NULL;

  // Query the speaker system mute state.
  hr = _ptrDeviceOut->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                               reinterpret_cast<void**>(&pVolume));
  EXIT_ON_ERROR(hr);

  BOOL mute;
  hr = pVolume->GetMute(&mute);
  EXIT_ON_ERROR(hr);

  enabled = (mute == TRUE) ? true : false;

  SAFE_RELEASE(pVolume);

  return 0;

Exit:
  _TraceCOMError(hr);
  SAFE_RELEASE(pVolume);
  return -1;
}

// ----------------------------------------------------------------------------
//  MicrophoneMuteIsAvailable
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::MicrophoneMuteIsAvailable(bool& available) {
  rtc::CritScope lock(&_critSect);

  if (_ptrDeviceIn == NULL) {
    return -1;
  }

  HRESULT hr = S_OK;
  IAudioEndpointVolume* pVolume = NULL;

  // Query the microphone system mute state.
  hr = _ptrDeviceIn->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                              reinterpret_cast<void**>(&pVolume));
  EXIT_ON_ERROR(hr);

  BOOL mute;
  hr = pVolume->GetMute(&mute);
  if (FAILED(hr))
    available = false;
  else
    available = true;

  SAFE_RELEASE(pVolume);
  return 0;

Exit:
  _TraceCOMError(hr);
  SAFE_RELEASE(pVolume);
  return -1;
}

// ----------------------------------------------------------------------------
//  SetMicrophoneMute
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetMicrophoneMute(bool enable) {
  if (!_microphoneIsInitialized) {
    return -1;
  }

  if (_ptrDeviceIn == NULL) {
    return -1;
  }

  HRESULT hr = S_OK;
  IAudioEndpointVolume* pVolume = NULL;

  // Set the microphone system mute state.
  hr = _ptrDeviceIn->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                              reinterpret_cast<void**>(&pVolume));
  EXIT_ON_ERROR(hr);

  const BOOL mute(enable);
  hr = pVolume->SetMute(mute, NULL);
  EXIT_ON_ERROR(hr);

  SAFE_RELEASE(pVolume);
  return 0;

Exit:
  _TraceCOMError(hr);
  SAFE_RELEASE(pVolume);
  return -1;
}

// ----------------------------------------------------------------------------
//  MicrophoneMute
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::MicrophoneMute(bool& enabled) const {
  if (!_microphoneIsInitialized) {
    return -1;
  }

  HRESULT hr = S_OK;
  IAudioEndpointVolume* pVolume = NULL;

  // Query the microphone system mute state.
  hr = _ptrDeviceIn->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                              reinterpret_cast<void**>(&pVolume));
  EXIT_ON_ERROR(hr);

  BOOL mute;
  hr = pVolume->GetMute(&mute);
  EXIT_ON_ERROR(hr);

  enabled = (mute == TRUE) ? true : false;

  SAFE_RELEASE(pVolume);
  return 0;

Exit:
  _TraceCOMError(hr);
  SAFE_RELEASE(pVolume);
  return -1;
}

// ----------------------------------------------------------------------------
//  StereoRecordingIsAvailable
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::StereoRecordingIsAvailable(bool& available) {
  available = true;
  return 0;
}

// ----------------------------------------------------------------------------
//  SetStereoRecording
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetStereoRecording(bool enable) {
  rtc::CritScope lock(&_critSect);

  if (enable) {
    _recChannelsPrioList[0] = 2;  // try stereo first
    _recChannelsPrioList[1] = 1;
    _recChannels = 2;
  } else {
    _recChannelsPrioList[0] = 1;  // try mono first
    _recChannelsPrioList[1] = 2;
    _recChannels = 1;
  }

  return 0;
}

// ----------------------------------------------------------------------------
//  StereoRecording
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::StereoRecording(bool& enabled) const {
  if (_recChannels == 2)
    enabled = true;
  else
    enabled = false;

  return 0;
}

// ----------------------------------------------------------------------------
//  StereoPlayoutIsAvailable
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::StereoPlayoutIsAvailable(bool& available) {
  available = true;
  return 0;
}

// ----------------------------------------------------------------------------
//  SetStereoPlayout
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetStereoPlayout(bool enable) {
  rtc::CritScope lock(&_critSect);

  if (enable) {
    _playChannelsPrioList[0] = 2;  // try stereo first
    _playChannelsPrioList[1] = 1;
    _playChannels = 2;
  } else {
    _playChannelsPrioList[0] = 1;  // try mono first
    _playChannelsPrioList[1] = 2;
    _playChannels = 1;
  }

  return 0;
}

// ----------------------------------------------------------------------------
//  StereoPlayout
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::StereoPlayout(bool& enabled) const {
  if (_playChannels == 2)
    enabled = true;
  else
    enabled = false;

  return 0;
}

// ----------------------------------------------------------------------------
//  MicrophoneVolumeIsAvailable
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::MicrophoneVolumeIsAvailable(bool& available) {
  rtc::CritScope lock(&_critSect);

  if (_ptrDeviceIn == NULL) {
    return -1;
  }

  HRESULT hr = S_OK;
  IAudioEndpointVolume* pVolume = NULL;

  hr = _ptrDeviceIn->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                              reinterpret_cast<void**>(&pVolume));
  EXIT_ON_ERROR(hr);

  float volume(0.0f);
  hr = pVolume->GetMasterVolumeLevelScalar(&volume);
  if (FAILED(hr)) {
    available = false;
  }
  available = true;

  SAFE_RELEASE(pVolume);
  return 0;

Exit:
  _TraceCOMError(hr);
  SAFE_RELEASE(pVolume);
  return -1;
}

// ----------------------------------------------------------------------------
//  SetMicrophoneVolume
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetMicrophoneVolume(uint32_t volume) {
  RTC_LOG(LS_VERBOSE) << "AudioDeviceWindowsCore::SetMicrophoneVolume(volume="
                      << volume << ")";

  {
    rtc::CritScope lock(&_critSect);

    if (!_microphoneIsInitialized) {
      return -1;
    }

    if (_ptrDeviceIn == NULL) {
      return -1;
    }
  }

  if (volume < static_cast<uint32_t>(MIN_CORE_MICROPHONE_VOLUME) ||
      volume > static_cast<uint32_t>(MAX_CORE_MICROPHONE_VOLUME)) {
    return -1;
  }

  HRESULT hr = S_OK;
  // scale input volume to valid range (0.0 to 1.0)
  const float fLevel = static_cast<float>(volume) / MAX_CORE_MICROPHONE_VOLUME;
  _volumeMutex.Enter();
  _ptrCaptureVolume->SetMasterVolumeLevelScalar(fLevel, NULL);
  _volumeMutex.Leave();
  EXIT_ON_ERROR(hr);

  return 0;

Exit:
  _TraceCOMError(hr);
  return -1;
}

// ----------------------------------------------------------------------------
//  MicrophoneVolume
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::MicrophoneVolume(uint32_t& volume) const {
  {
    rtc::CritScope lock(&_critSect);

    if (!_microphoneIsInitialized) {
      return -1;
    }

    if (_ptrDeviceIn == NULL) {
      return -1;
    }
  }

  HRESULT hr = S_OK;
  float fLevel(0.0f);
  volume = 0;
  _volumeMutex.Enter();
  hr = _ptrCaptureVolume->GetMasterVolumeLevelScalar(&fLevel);
  _volumeMutex.Leave();
  EXIT_ON_ERROR(hr);

  // scale input volume range [0.0,1.0] to valid output range
  volume = static_cast<uint32_t>(fLevel * MAX_CORE_MICROPHONE_VOLUME);

  return 0;

Exit:
  _TraceCOMError(hr);
  return -1;
}

// ----------------------------------------------------------------------------
//  MaxMicrophoneVolume
//
//  The internal range for Core Audio is 0.0 to 1.0, where 0.0 indicates
//  silence and 1.0 indicates full volume (no attenuation).
//  We add our (webrtc-internal) own max level to match the Wave API and
//  how it is used today in VoE.
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::MaxMicrophoneVolume(uint32_t& maxVolume) const {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  if (!_microphoneIsInitialized) {
    return -1;
  }

  maxVolume = static_cast<uint32_t>(MAX_CORE_MICROPHONE_VOLUME);

  return 0;
}

// ----------------------------------------------------------------------------
//  MinMicrophoneVolume
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::MinMicrophoneVolume(uint32_t& minVolume) const {
  if (!_microphoneIsInitialized) {
    return -1;
  }

  minVolume = static_cast<uint32_t>(MIN_CORE_MICROPHONE_VOLUME);

  return 0;
}

// ----------------------------------------------------------------------------
//  PlayoutDevices
// ----------------------------------------------------------------------------

int16_t AudioDeviceWindowsCore::PlayoutDevices() {
  rtc::CritScope lock(&_critSect);

  if (_RefreshDeviceList(eRender) != -1) {
    return (_DeviceListCount(eRender));
  }

  return -1;
}

// ----------------------------------------------------------------------------
//  SetPlayoutDevice I (II)
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetPlayoutDevice(uint16_t index) {
  if (_playIsInitialized) {
    return -1;
  }

  // Get current number of available rendering endpoint devices and refresh the
  // rendering collection.
  UINT nDevices = PlayoutDevices();

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

  rtc::CritScope lock(&_critSect);

  HRESULT hr(S_OK);

  assert(_ptrRenderCollection != NULL);

  //  Select an endpoint rendering device given the specified index
  SAFE_RELEASE(_ptrDeviceOut);
  hr = _ptrRenderCollection->Item(index, &_ptrDeviceOut);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(_ptrDeviceOut);
    return -1;
  }

  WCHAR szDeviceName[MAX_PATH];
  const int bufferLen = sizeof(szDeviceName) / sizeof(szDeviceName)[0];

  // Get the endpoint device's friendly-name
  if (_GetDeviceName(_ptrDeviceOut, szDeviceName, bufferLen) == 0) {
    RTC_LOG(LS_VERBOSE) << "friendly name: \"" << szDeviceName << "\"";
  }

  _usingOutputDeviceIndex = true;
  _outputDeviceIndex = index;

  return 0;
}

// ----------------------------------------------------------------------------
//  SetPlayoutDevice II (II)
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetPlayoutDevice(
    AudioDeviceModule::WindowsDeviceType device) {
  if (_playIsInitialized) {
    return -1;
  }

  ERole role(eCommunications);

  if (device == AudioDeviceModule::kDefaultDevice) {
    role = eConsole;
  } else if (device == AudioDeviceModule::kDefaultCommunicationDevice) {
    role = eCommunications;
  }

  rtc::CritScope lock(&_critSect);

  // Refresh the list of rendering endpoint devices
  _RefreshDeviceList(eRender);

  HRESULT hr(S_OK);

  assert(_ptrEnumerator != NULL);

  //  Select an endpoint rendering device given the specified role
  SAFE_RELEASE(_ptrDeviceOut);
  hr = _ptrEnumerator->GetDefaultAudioEndpoint(eRender, role, &_ptrDeviceOut);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(_ptrDeviceOut);
    return -1;
  }

  WCHAR szDeviceName[MAX_PATH];
  const int bufferLen = sizeof(szDeviceName) / sizeof(szDeviceName)[0];

  // Get the endpoint device's friendly-name
  if (_GetDeviceName(_ptrDeviceOut, szDeviceName, bufferLen) == 0) {
    RTC_LOG(LS_VERBOSE) << "friendly name: \"" << szDeviceName << "\"";
  }

  _usingOutputDeviceIndex = false;
  _outputDevice = device;

  return 0;
}

// ----------------------------------------------------------------------------
//  PlayoutDeviceName
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::PlayoutDeviceName(
    uint16_t index,
    char name[kAdmMaxDeviceNameSize],
    char guid[kAdmMaxGuidSize]) {
  bool defaultCommunicationDevice(false);
  const int16_t nDevices(PlayoutDevices());  // also updates the list of devices

  // Special fix for the case when the user selects '-1' as index (<=> Default
  // Communication Device)
  if (index == (uint16_t)(-1)) {
    defaultCommunicationDevice = true;
    index = 0;
    RTC_LOG(LS_VERBOSE) << "Default Communication endpoint device will be used";
  }

  if ((index > (nDevices - 1)) || (name == NULL)) {
    return -1;
  }

  memset(name, 0, kAdmMaxDeviceNameSize);

  if (guid != NULL) {
    memset(guid, 0, kAdmMaxGuidSize);
  }

  rtc::CritScope lock(&_critSect);

  int32_t ret(-1);
  WCHAR szDeviceName[MAX_PATH];
  const int bufferLen = sizeof(szDeviceName) / sizeof(szDeviceName)[0];

  // Get the endpoint device's friendly-name
  if (defaultCommunicationDevice) {
    ret = _GetDefaultDeviceName(eRender, eCommunications, szDeviceName,
                                bufferLen);
  } else {
    ret = _GetListDeviceName(eRender, index, szDeviceName, bufferLen);
  }

  if (ret == 0) {
    // Convert the endpoint device's friendly-name to UTF-8
    if (WideCharToMultiByte(CP_UTF8, 0, szDeviceName, -1, name,
                            kAdmMaxDeviceNameSize, NULL, NULL) == 0) {
      RTC_LOG(LS_ERROR)
          << "WideCharToMultiByte(CP_UTF8) failed with error code "
          << GetLastError();
    }
  }

  // Get the endpoint ID string (uniquely identifies the device among all audio
  // endpoint devices)
  if (defaultCommunicationDevice) {
    ret =
        _GetDefaultDeviceID(eRender, eCommunications, szDeviceName, bufferLen);
  } else {
    ret = _GetListDeviceID(eRender, index, szDeviceName, bufferLen);
  }

  if (guid != NULL && ret == 0) {
    // Convert the endpoint device's ID string to UTF-8
    if (WideCharToMultiByte(CP_UTF8, 0, szDeviceName, -1, guid, kAdmMaxGuidSize,
                            NULL, NULL) == 0) {
      RTC_LOG(LS_ERROR)
          << "WideCharToMultiByte(CP_UTF8) failed with error code "
          << GetLastError();
    }
  }

  return ret;
}

// ----------------------------------------------------------------------------
//  RecordingDeviceName
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::RecordingDeviceName(
    uint16_t index,
    char name[kAdmMaxDeviceNameSize],
    char guid[kAdmMaxGuidSize]) {
  bool defaultCommunicationDevice(false);
  const int16_t nDevices(
      RecordingDevices());  // also updates the list of devices

  // Special fix for the case when the user selects '-1' as index (<=> Default
  // Communication Device)
  if (index == (uint16_t)(-1)) {
    defaultCommunicationDevice = true;
    index = 0;
    RTC_LOG(LS_VERBOSE) << "Default Communication endpoint device will be used";
  }

  if ((index > (nDevices - 1)) || (name == NULL)) {
    return -1;
  }

  memset(name, 0, kAdmMaxDeviceNameSize);

  if (guid != NULL) {
    memset(guid, 0, kAdmMaxGuidSize);
  }

  rtc::CritScope lock(&_critSect);

  int32_t ret(-1);
  WCHAR szDeviceName[MAX_PATH];
  const int bufferLen = sizeof(szDeviceName) / sizeof(szDeviceName)[0];

  // Get the endpoint device's friendly-name
  if (defaultCommunicationDevice) {
    ret = _GetDefaultDeviceName(eCapture, eCommunications, szDeviceName,
                                bufferLen);
  } else {
    ret = _GetListDeviceName(eCapture, index, szDeviceName, bufferLen);
  }

  if (ret == 0) {
    // Convert the endpoint device's friendly-name to UTF-8
    if (WideCharToMultiByte(CP_UTF8, 0, szDeviceName, -1, name,
                            kAdmMaxDeviceNameSize, NULL, NULL) == 0) {
      RTC_LOG(LS_ERROR)
          << "WideCharToMultiByte(CP_UTF8) failed with error code "
          << GetLastError();
    }
  }

  // Get the endpoint ID string (uniquely identifies the device among all audio
  // endpoint devices)
  if (defaultCommunicationDevice) {
    ret =
        _GetDefaultDeviceID(eCapture, eCommunications, szDeviceName, bufferLen);
  } else {
    ret = _GetListDeviceID(eCapture, index, szDeviceName, bufferLen);
  }

  if (guid != NULL && ret == 0) {
    // Convert the endpoint device's ID string to UTF-8
    if (WideCharToMultiByte(CP_UTF8, 0, szDeviceName, -1, guid, kAdmMaxGuidSize,
                            NULL, NULL) == 0) {
      RTC_LOG(LS_ERROR)
          << "WideCharToMultiByte(CP_UTF8) failed with error code "
          << GetLastError();
    }
  }

  return ret;
}

// ----------------------------------------------------------------------------
//  RecordingDevices
// ----------------------------------------------------------------------------

int16_t AudioDeviceWindowsCore::RecordingDevices() {
  rtc::CritScope lock(&_critSect);

  if (_RefreshDeviceList(eCapture) != -1) {
    return (_DeviceListCount(eCapture));
  }

  return -1;
}

// ----------------------------------------------------------------------------
//  SetRecordingDevice I (II)
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetRecordingDevice(uint16_t index) {
  if (_recIsInitialized) {
    return -1;
  }

  // Get current number of available capture endpoint devices and refresh the
  // capture collection.
  UINT nDevices = RecordingDevices();

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

  rtc::CritScope lock(&_critSect);

  HRESULT hr(S_OK);

  assert(_ptrCaptureCollection != NULL);

  // Select an endpoint capture device given the specified index
  SAFE_RELEASE(_ptrDeviceIn);
  hr = _ptrCaptureCollection->Item(index, &_ptrDeviceIn);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(_ptrDeviceIn);
    return -1;
  }

  WCHAR szDeviceName[MAX_PATH];
  const int bufferLen = sizeof(szDeviceName) / sizeof(szDeviceName)[0];

  // Get the endpoint device's friendly-name
  if (_GetDeviceName(_ptrDeviceIn, szDeviceName, bufferLen) == 0) {
    RTC_LOG(LS_VERBOSE) << "friendly name: \"" << szDeviceName << "\"";
  }

  _usingInputDeviceIndex = true;
  _inputDeviceIndex = index;

  return 0;
}

// ----------------------------------------------------------------------------
//  SetRecordingDevice II (II)
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::SetRecordingDevice(
    AudioDeviceModule::WindowsDeviceType device) {
  if (_recIsInitialized) {
    return -1;
  }

  ERole role(eCommunications);

  if (device == AudioDeviceModule::kDefaultDevice) {
    role = eConsole;
  } else if (device == AudioDeviceModule::kDefaultCommunicationDevice) {
    role = eCommunications;
  }

  rtc::CritScope lock(&_critSect);

  // Refresh the list of capture endpoint devices
  _RefreshDeviceList(eCapture);

  HRESULT hr(S_OK);

  assert(_ptrEnumerator != NULL);

  //  Select an endpoint capture device given the specified role
  SAFE_RELEASE(_ptrDeviceIn);
  hr = _ptrEnumerator->GetDefaultAudioEndpoint(eCapture, role, &_ptrDeviceIn);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(_ptrDeviceIn);
    return -1;
  }

  WCHAR szDeviceName[MAX_PATH];
  const int bufferLen = sizeof(szDeviceName) / sizeof(szDeviceName)[0];

  // Get the endpoint device's friendly-name
  if (_GetDeviceName(_ptrDeviceIn, szDeviceName, bufferLen) == 0) {
    RTC_LOG(LS_VERBOSE) << "friendly name: \"" << szDeviceName << "\"";
  }

  _usingInputDeviceIndex = false;
  _inputDevice = device;

  return 0;
}

// ----------------------------------------------------------------------------
//  PlayoutIsAvailable
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::PlayoutIsAvailable(bool& available) {
  available = false;

  // Try to initialize the playout side
  int32_t res = InitPlayout();

  // Cancel effect of initialization
  StopPlayout();

  if (res != -1) {
    available = true;
  }

  return 0;
}

// ----------------------------------------------------------------------------
//  RecordingIsAvailable
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::RecordingIsAvailable(bool& available) {
  available = false;

  // Try to initialize the recording side
  int32_t res = InitRecording();

  // Cancel effect of initialization
  StopRecording();

  if (res != -1) {
    available = true;
  }

  return 0;
}

// ----------------------------------------------------------------------------
//  InitPlayout
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::InitPlayout() {
  rtc::CritScope lock(&_critSect);

  if (_playing) {
    return -1;
  }

  if (_playIsInitialized) {
    return 0;
  }

  if (_ptrDeviceOut == NULL) {
    return -1;
  }

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

  // Ensure that the updated rendering endpoint device is valid
  if (_ptrDeviceOut == NULL) {
    return -1;
  }

  if (_builtInAecEnabled && _recIsInitialized) {
    // Ensure the correct render device is configured in case
    // InitRecording() was called before InitPlayout().
    if (SetDMOProperties() == -1) {
      return -1;
    }
  }

  HRESULT hr = S_OK;
  WAVEFORMATEX* pWfxOut = NULL;
  WAVEFORMATEX Wfx = WAVEFORMATEX();
  WAVEFORMATEX* pWfxClosestMatch = NULL;

  // Create COM object with IAudioClient interface.
  SAFE_RELEASE(_ptrClientOut);
  hr = _ptrDeviceOut->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL,
                               (void**)&_ptrClientOut);
  EXIT_ON_ERROR(hr);

  // Retrieve the stream format that the audio engine uses for its internal
  // processing (mixing) of shared-mode streams.
  hr = _ptrClientOut->GetMixFormat(&pWfxOut);
  if (SUCCEEDED(hr)) {
    RTC_LOG(LS_VERBOSE) << "Audio Engine's current rendering mix format:";
    // format type
    RTC_LOG(LS_VERBOSE) << "wFormatTag     : 0x"
                        << rtc::ToHex(pWfxOut->wFormatTag) << " ("
                        << pWfxOut->wFormatTag << ")";
    // number of channels (i.e. mono, stereo...)
    RTC_LOG(LS_VERBOSE) << "nChannels      : " << pWfxOut->nChannels;
    // sample rate
    RTC_LOG(LS_VERBOSE) << "nSamplesPerSec : " << pWfxOut->nSamplesPerSec;
    // for buffer estimation
    RTC_LOG(LS_VERBOSE) << "nAvgBytesPerSec: " << pWfxOut->nAvgBytesPerSec;
    // block size of data
    RTC_LOG(LS_VERBOSE) << "nBlockAlign    : " << pWfxOut->nBlockAlign;
    // number of bits per sample of mono data
    RTC_LOG(LS_VERBOSE) << "wBitsPerSample : " << pWfxOut->wBitsPerSample;
    RTC_LOG(LS_VERBOSE) << "cbSize         : " << pWfxOut->cbSize;
  }

  // Set wave format
  Wfx.wFormatTag = WAVE_FORMAT_PCM;
  Wfx.wBitsPerSample = 16;
  Wfx.cbSize = 0;

  const int freqs[] = {48000, 44100, 16000, 96000, 32000, 8000};
  hr = S_FALSE;

  // Iterate over frequencies and channels, in order of priority
  for (unsigned int freq = 0; freq < sizeof(freqs) / sizeof(freqs[0]); freq++) {
    for (unsigned int chan = 0; chan < sizeof(_playChannelsPrioList) /
                                           sizeof(_playChannelsPrioList[0]);
         chan++) {
      Wfx.nChannels = _playChannelsPrioList[chan];
      Wfx.nSamplesPerSec = freqs[freq];
      Wfx.nBlockAlign = Wfx.nChannels * Wfx.wBitsPerSample / 8;
      Wfx.nAvgBytesPerSec = Wfx.nSamplesPerSec * Wfx.nBlockAlign;
      // If the method succeeds and the audio endpoint device supports the
      // specified stream format, it returns S_OK. If the method succeeds and
      // provides a closest match to the specified format, it returns S_FALSE.
      hr = _ptrClientOut->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &Wfx,
                                            &pWfxClosestMatch);
      if (hr == S_OK) {
        break;
      } else {
        if (pWfxClosestMatch) {
          RTC_LOG(INFO) << "nChannels=" << Wfx.nChannels
                        << ", nSamplesPerSec=" << Wfx.nSamplesPerSec
                        << " is not supported. Closest match: "
                        << "nChannels=" << pWfxClosestMatch->nChannels
                        << ", nSamplesPerSec="
                        << pWfxClosestMatch->nSamplesPerSec;
          CoTaskMemFree(pWfxClosestMatch);
          pWfxClosestMatch = NULL;
        } else {
          RTC_LOG(INFO) << "nChannels=" << Wfx.nChannels
                        << ", nSamplesPerSec=" << Wfx.nSamplesPerSec
                        << " is not supported. No closest match.";
        }
      }
    }
    if (hr == S_OK)
      break;
  }

  // TODO(andrew): what happens in the event of failure in the above loop?
  //   Is _ptrClientOut->Initialize expected to fail?
  //   Same in InitRecording().
  if (hr == S_OK) {
    _playAudioFrameSize = Wfx.nBlockAlign;
    // Block size is the number of samples each channel in 10ms.
    _playBlockSize = Wfx.nSamplesPerSec / 100;
    _playSampleRate = Wfx.nSamplesPerSec;
    _devicePlaySampleRate =
        Wfx.nSamplesPerSec;  // The device itself continues to run at 44.1 kHz.
    _devicePlayBlockSize = Wfx.nSamplesPerSec / 100;
    _playChannels = Wfx.nChannels;

    RTC_LOG(LS_VERBOSE) << "VoE selected this rendering format:";
    RTC_LOG(LS_VERBOSE) << "wFormatTag         : 0x"
                        << rtc::ToHex(Wfx.wFormatTag) << " (" << Wfx.wFormatTag
                        << ")";
    RTC_LOG(LS_VERBOSE) << "nChannels          : " << Wfx.nChannels;
    RTC_LOG(LS_VERBOSE) << "nSamplesPerSec     : " << Wfx.nSamplesPerSec;
    RTC_LOG(LS_VERBOSE) << "nAvgBytesPerSec    : " << Wfx.nAvgBytesPerSec;
    RTC_LOG(LS_VERBOSE) << "nBlockAlign        : " << Wfx.nBlockAlign;
    RTC_LOG(LS_VERBOSE) << "wBitsPerSample     : " << Wfx.wBitsPerSample;
    RTC_LOG(LS_VERBOSE) << "cbSize             : " << Wfx.cbSize;
    RTC_LOG(LS_VERBOSE) << "Additional settings:";
    RTC_LOG(LS_VERBOSE) << "_playAudioFrameSize: " << _playAudioFrameSize;
    RTC_LOG(LS_VERBOSE) << "_playBlockSize     : " << _playBlockSize;
    RTC_LOG(LS_VERBOSE) << "_playChannels      : " << _playChannels;
  }

  // Create a rendering stream.
  //
  // ****************************************************************************
  // For a shared-mode stream that uses event-driven buffering, the caller must
  // set both hnsPeriodicity and hnsBufferDuration to 0. The Initialize method
  // determines how large a buffer to allocate based on the scheduling period
  // of the audio engine. Although the client's buffer processing thread is
  // event driven, the basic buffer management process, as described previously,
  // is unaltered.
  // Each time the thread awakens, it should call
  // IAudioClient::GetCurrentPadding to determine how much data to write to a
  // rendering buffer or read from a capture buffer. In contrast to the two
  // buffers that the Initialize method allocates for an exclusive-mode stream
  // that uses event-driven buffering, a shared-mode stream requires a single
  // buffer.
  // ****************************************************************************
  //
  REFERENCE_TIME hnsBufferDuration =
      0;  // ask for minimum buffer size (default)
  if (_devicePlaySampleRate == 44100) {
    // Ask for a larger buffer size (30ms) when using 44.1kHz as render rate.
    // There seems to be a larger risk of underruns for 44.1 compared
    // with the default rate (48kHz). When using default, we set the requested
    // buffer duration to 0, which sets the buffer to the minimum size
    // required by the engine thread. The actual buffer size can then be
    // read by GetBufferSize() and it is 20ms on most machines.
    hnsBufferDuration = 30 * 10000;
  }
  hr = _ptrClientOut->Initialize(
      AUDCLNT_SHAREMODE_SHARED,  // share Audio Engine with other applications
      AUDCLNT_STREAMFLAGS_EVENTCALLBACK,  // processing of the audio buffer by
                                          // the client will be event driven
      hnsBufferDuration,  // requested buffer capacity as a time value (in
                          // 100-nanosecond units)
      0,                  // periodicity
      &Wfx,               // selected wave format
      NULL);              // session GUID

  if (FAILED(hr)) {
    RTC_LOG(LS_ERROR) << "IAudioClient::Initialize() failed:";
  }
  EXIT_ON_ERROR(hr);

  if (_ptrAudioBuffer) {
    // Update the audio buffer with the selected parameters
    _ptrAudioBuffer->SetPlayoutSampleRate(_playSampleRate);
    _ptrAudioBuffer->SetPlayoutChannels((uint8_t)_playChannels);
  } else {
    // We can enter this state during CoreAudioIsSupported() when no
    // AudioDeviceImplementation has been created, hence the AudioDeviceBuffer
    // does not exist. It is OK to end up here since we don't initiate any media
    // in CoreAudioIsSupported().
    RTC_LOG(LS_VERBOSE)
        << "AudioDeviceBuffer must be attached before streaming can start";
  }

  // Get the actual size of the shared (endpoint buffer).
  // Typical value is 960 audio frames <=> 20ms @ 48kHz sample rate.
  UINT bufferFrameCount(0);
  hr = _ptrClientOut->GetBufferSize(&bufferFrameCount);
  if (SUCCEEDED(hr)) {
    RTC_LOG(LS_VERBOSE) << "IAudioClient::GetBufferSize() => "
                        << bufferFrameCount << " (<=> "
                        << bufferFrameCount * _playAudioFrameSize << " bytes)";
  }

  // Set the event handle that the system signals when an audio buffer is ready
  // to be processed by the client.
  hr = _ptrClientOut->SetEventHandle(_hRenderSamplesReadyEvent);
  EXIT_ON_ERROR(hr);

  // Get an IAudioRenderClient interface.
  SAFE_RELEASE(_ptrRenderClient);
  hr = _ptrClientOut->GetService(__uuidof(IAudioRenderClient),
                                 (void**)&_ptrRenderClient);
  EXIT_ON_ERROR(hr);

  // Mark playout side as initialized
  _playIsInitialized = true;

  CoTaskMemFree(pWfxOut);
  CoTaskMemFree(pWfxClosestMatch);

  RTC_LOG(LS_VERBOSE) << "render side is now initialized";
  return 0;

Exit:
  _TraceCOMError(hr);
  CoTaskMemFree(pWfxOut);
  CoTaskMemFree(pWfxClosestMatch);
  SAFE_RELEASE(_ptrClientOut);
  SAFE_RELEASE(_ptrRenderClient);
  return -1;
}

// Capture initialization when the built-in AEC DirectX Media Object (DMO) is
// used. Called from InitRecording(), most of which is skipped over. The DMO
// handles device initialization itself.
// Reference: http://msdn.microsoft.com/en-us/library/ff819492(v=vs.85).aspx
int32_t AudioDeviceWindowsCore::InitRecordingDMO() {
  assert(_builtInAecEnabled);
  assert(_dmo != NULL);

  if (SetDMOProperties() == -1) {
    return -1;
  }

  DMO_MEDIA_TYPE mt = {};
  HRESULT hr = MoInitMediaType(&mt, sizeof(WAVEFORMATEX));
  if (FAILED(hr)) {
    MoFreeMediaType(&mt);
    _TraceCOMError(hr);
    return -1;
  }
  mt.majortype = MEDIATYPE_Audio;
  mt.subtype = MEDIASUBTYPE_PCM;
  mt.formattype = FORMAT_WaveFormatEx;

  // Supported formats
  // nChannels: 1 (in AEC-only mode)
  // nSamplesPerSec: 8000, 11025, 16000, 22050
  // wBitsPerSample: 16
  WAVEFORMATEX* ptrWav = reinterpret_cast<WAVEFORMATEX*>(mt.pbFormat);
  ptrWav->wFormatTag = WAVE_FORMAT_PCM;
  ptrWav->nChannels = 1;
  // 16000 is the highest we can support with our resampler.
  ptrWav->nSamplesPerSec = 16000;
  ptrWav->nAvgBytesPerSec = 32000;
  ptrWav->nBlockAlign = 2;
  ptrWav->wBitsPerSample = 16;
  ptrWav->cbSize = 0;

  // Set the VoE format equal to the AEC output format.
  _recAudioFrameSize = ptrWav->nBlockAlign;
  _recSampleRate = ptrWav->nSamplesPerSec;
  _recBlockSize = ptrWav->nSamplesPerSec / 100;
  _recChannels = ptrWav->nChannels;

  // Set the DMO output format parameters.
  hr = _dmo->SetOutputType(kAecCaptureStreamIndex, &mt, 0);
  MoFreeMediaType(&mt);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    return -1;
  }

  if (_ptrAudioBuffer) {
    _ptrAudioBuffer->SetRecordingSampleRate(_recSampleRate);
    _ptrAudioBuffer->SetRecordingChannels(_recChannels);
  } else {
    // Refer to InitRecording() for comments.
    RTC_LOG(LS_VERBOSE)
        << "AudioDeviceBuffer must be attached before streaming can start";
  }

  _mediaBuffer = new MediaBufferImpl(_recBlockSize * _recAudioFrameSize);

  // Optional, but if called, must be after media types are set.
  hr = _dmo->AllocateStreamingResources();
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    return -1;
  }

  _recIsInitialized = true;
  RTC_LOG(LS_VERBOSE) << "Capture side is now initialized";

  return 0;
}

// ----------------------------------------------------------------------------
//  InitRecording
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::InitRecording() {
  rtc::CritScope lock(&_critSect);

  if (_recording) {
    return -1;
  }

  if (_recIsInitialized) {
    return 0;
  }

  if (QueryPerformanceFrequency(&_perfCounterFreq) == 0) {
    return -1;
  }
  _perfCounterFactor = 10000000.0 / (double)_perfCounterFreq.QuadPart;

  if (_ptrDeviceIn == NULL) {
    return -1;
  }

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

  // Ensure that the updated capturing endpoint device is valid
  if (_ptrDeviceIn == NULL) {
    return -1;
  }

  if (_builtInAecEnabled) {
    // The DMO will configure the capture device.
    return InitRecordingDMO();
  }

  HRESULT hr = S_OK;
  WAVEFORMATEX* pWfxIn = NULL;
  WAVEFORMATEXTENSIBLE Wfx = WAVEFORMATEXTENSIBLE();
  WAVEFORMATEX* pWfxClosestMatch = NULL;

  // Create COM object with IAudioClient interface.
  SAFE_RELEASE(_ptrClientIn);
  hr = _ptrDeviceIn->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL,
                              (void**)&_ptrClientIn);
  EXIT_ON_ERROR(hr);

  // Retrieve the stream format that the audio engine uses for its internal
  // processing (mixing) of shared-mode streams.
  hr = _ptrClientIn->GetMixFormat(&pWfxIn);
  if (SUCCEEDED(hr)) {
    RTC_LOG(LS_VERBOSE) << "Audio Engine's current capturing mix format:";
    // format type
    RTC_LOG(LS_VERBOSE) << "wFormatTag     : 0x"
                        << rtc::ToHex(pWfxIn->wFormatTag) << " ("
                        << pWfxIn->wFormatTag << ")";
    // number of channels (i.e. mono, stereo...)
    RTC_LOG(LS_VERBOSE) << "nChannels      : " << pWfxIn->nChannels;
    // sample rate
    RTC_LOG(LS_VERBOSE) << "nSamplesPerSec : " << pWfxIn->nSamplesPerSec;
    // for buffer estimation
    RTC_LOG(LS_VERBOSE) << "nAvgBytesPerSec: " << pWfxIn->nAvgBytesPerSec;
    // block size of data
    RTC_LOG(LS_VERBOSE) << "nBlockAlign    : " << pWfxIn->nBlockAlign;
    // number of bits per sample of mono data
    RTC_LOG(LS_VERBOSE) << "wBitsPerSample : " << pWfxIn->wBitsPerSample;
    RTC_LOG(LS_VERBOSE) << "cbSize         : " << pWfxIn->cbSize;
  }

  // Set wave format
  Wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
  Wfx.Format.wBitsPerSample = 16;
  Wfx.Format.cbSize = 22;
  Wfx.dwChannelMask = 0;
  Wfx.Samples.wValidBitsPerSample = Wfx.Format.wBitsPerSample;
  Wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;

  const int freqs[6] = {48000, 44100, 16000, 96000, 32000, 8000};
  hr = S_FALSE;

  // Iterate over frequencies and channels, in order of priority
  for (unsigned int freq = 0; freq < sizeof(freqs) / sizeof(freqs[0]); freq++) {
    for (unsigned int chan = 0;
         chan < sizeof(_recChannelsPrioList) / sizeof(_recChannelsPrioList[0]);
         chan++) {
      Wfx.Format.nChannels = _recChannelsPrioList[chan];
      Wfx.Format.nSamplesPerSec = freqs[freq];
      Wfx.Format.nBlockAlign =
          Wfx.Format.nChannels * Wfx.Format.wBitsPerSample / 8;
      Wfx.Format.nAvgBytesPerSec =
          Wfx.Format.nSamplesPerSec * Wfx.Format.nBlockAlign;
      // If the method succeeds and the audio endpoint device supports the
      // specified stream format, it returns S_OK. If the method succeeds and
      // provides a closest match to the specified format, it returns S_FALSE.
      hr = _ptrClientIn->IsFormatSupported(
          AUDCLNT_SHAREMODE_SHARED, (WAVEFORMATEX*)&Wfx, &pWfxClosestMatch);
      if (hr == S_OK) {
        break;
      } else {
        if (pWfxClosestMatch) {
          RTC_LOG(INFO) << "nChannels=" << Wfx.Format.nChannels
                        << ", nSamplesPerSec=" << Wfx.Format.nSamplesPerSec
                        << " is not supported. Closest match: "
                        << "nChannels=" << pWfxClosestMatch->nChannels
                        << ", nSamplesPerSec="
                        << pWfxClosestMatch->nSamplesPerSec;
          CoTaskMemFree(pWfxClosestMatch);
          pWfxClosestMatch = NULL;
        } else {
          RTC_LOG(INFO) << "nChannels=" << Wfx.Format.nChannels
                        << ", nSamplesPerSec=" << Wfx.Format.nSamplesPerSec
                        << " is not supported. No closest match.";
        }
      }
    }
    if (hr == S_OK)
      break;
  }

  if (hr == S_OK) {
    _recAudioFrameSize = Wfx.Format.nBlockAlign;
    _recSampleRate = Wfx.Format.nSamplesPerSec;
    _recBlockSize = Wfx.Format.nSamplesPerSec / 100;
    _recChannels = Wfx.Format.nChannels;

    RTC_LOG(LS_VERBOSE) << "VoE selected this capturing format:";
    RTC_LOG(LS_VERBOSE) << "wFormatTag        : 0x"
                        << rtc::ToHex(Wfx.Format.wFormatTag) << " ("
                        << Wfx.Format.wFormatTag << ")";
    RTC_LOG(LS_VERBOSE) << "nChannels         : " << Wfx.Format.nChannels;
    RTC_LOG(LS_VERBOSE) << "nSamplesPerSec    : " << Wfx.Format.nSamplesPerSec;
    RTC_LOG(LS_VERBOSE) << "nAvgBytesPerSec   : " << Wfx.Format.nAvgBytesPerSec;
    RTC_LOG(LS_VERBOSE) << "nBlockAlign       : " << Wfx.Format.nBlockAlign;
    RTC_LOG(LS_VERBOSE) << "wBitsPerSample    : " << Wfx.Format.wBitsPerSample;
    RTC_LOG(LS_VERBOSE) << "cbSize            : " << Wfx.Format.cbSize;
    RTC_LOG(LS_VERBOSE) << "Additional settings:";
    RTC_LOG(LS_VERBOSE) << "_recAudioFrameSize: " << _recAudioFrameSize;
    RTC_LOG(LS_VERBOSE) << "_recBlockSize     : " << _recBlockSize;
    RTC_LOG(LS_VERBOSE) << "_recChannels      : " << _recChannels;
  }

  // Create a capturing stream.
  hr = _ptrClientIn->Initialize(
      AUDCLNT_SHAREMODE_SHARED,  // share Audio Engine with other applications
      AUDCLNT_STREAMFLAGS_EVENTCALLBACK |  // processing of the audio buffer by
                                           // the client will be event driven
          AUDCLNT_STREAMFLAGS_NOPERSIST,   // volume and mute settings for an
                                           // audio session will not persist
                                           // across system restarts
      0,                    // required for event-driven shared mode
      0,                    // periodicity
      (WAVEFORMATEX*)&Wfx,  // selected wave format
      NULL);                // session GUID

  if (hr != S_OK) {
    RTC_LOG(LS_ERROR) << "IAudioClient::Initialize() failed:";
  }
  EXIT_ON_ERROR(hr);

  if (_ptrAudioBuffer) {
    // Update the audio buffer with the selected parameters
    _ptrAudioBuffer->SetRecordingSampleRate(_recSampleRate);
    _ptrAudioBuffer->SetRecordingChannels((uint8_t)_recChannels);
  } else {
    // We can enter this state during CoreAudioIsSupported() when no
    // AudioDeviceImplementation has been created, hence the AudioDeviceBuffer
    // does not exist. It is OK to end up here since we don't initiate any media
    // in CoreAudioIsSupported().
    RTC_LOG(LS_VERBOSE)
        << "AudioDeviceBuffer must be attached before streaming can start";
  }

  // Get the actual size of the shared (endpoint buffer).
  // Typical value is 960 audio frames <=> 20ms @ 48kHz sample rate.
  UINT bufferFrameCount(0);
  hr = _ptrClientIn->GetBufferSize(&bufferFrameCount);
  if (SUCCEEDED(hr)) {
    RTC_LOG(LS_VERBOSE) << "IAudioClient::GetBufferSize() => "
                        << bufferFrameCount << " (<=> "
                        << bufferFrameCount * _recAudioFrameSize << " bytes)";
  }

  // Set the event handle that the system signals when an audio buffer is ready
  // to be processed by the client.
  hr = _ptrClientIn->SetEventHandle(_hCaptureSamplesReadyEvent);
  EXIT_ON_ERROR(hr);

  // Get an IAudioCaptureClient interface.
  SAFE_RELEASE(_ptrCaptureClient);
  hr = _ptrClientIn->GetService(__uuidof(IAudioCaptureClient),
                                (void**)&_ptrCaptureClient);
  EXIT_ON_ERROR(hr);

  // Mark capture side as initialized
  _recIsInitialized = true;

  CoTaskMemFree(pWfxIn);
  CoTaskMemFree(pWfxClosestMatch);

  RTC_LOG(LS_VERBOSE) << "capture side is now initialized";
  return 0;

Exit:
  _TraceCOMError(hr);
  CoTaskMemFree(pWfxIn);
  CoTaskMemFree(pWfxClosestMatch);
  SAFE_RELEASE(_ptrClientIn);
  SAFE_RELEASE(_ptrCaptureClient);
  return -1;
}

// ----------------------------------------------------------------------------
//  StartRecording
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::StartRecording() {
  if (!_recIsInitialized) {
    return -1;
  }

  if (_hRecThread != NULL) {
    return 0;
  }

  if (_recording) {
    return 0;
  }

  {
    rtc::CritScope critScoped(&_critSect);

    // Create thread which will drive the capturing
    LPTHREAD_START_ROUTINE lpStartAddress = WSAPICaptureThread;
    if (_builtInAecEnabled) {
      // Redirect to the DMO polling method.
      lpStartAddress = WSAPICaptureThreadPollDMO;

      if (!_playing) {
        // The DMO won't provide us captured output data unless we
        // give it render data to process.
        RTC_LOG(LS_ERROR)
            << "Playout must be started before recording when using"
            << " the built-in AEC";
        return -1;
      }
    }

    assert(_hRecThread == NULL);
    _hRecThread = CreateThread(NULL, 0, lpStartAddress, this, 0, NULL);
    if (_hRecThread == NULL) {
      RTC_LOG(LS_ERROR) << "failed to create the recording thread";
      return -1;
    }

    // Set thread priority to highest possible
    SetThreadPriority(_hRecThread, THREAD_PRIORITY_TIME_CRITICAL);

  }  // critScoped

  DWORD ret = WaitForSingleObject(_hCaptureStartedEvent, 1000);
  if (ret != WAIT_OBJECT_0) {
    RTC_LOG(LS_VERBOSE) << "capturing did not start up properly";
    return -1;
  }
  RTC_LOG(LS_VERBOSE) << "capture audio stream has now started...";

  _recording = true;

  return 0;
}

// ----------------------------------------------------------------------------
//  StopRecording
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::StopRecording() {
  int32_t err = 0;

  if (!_recIsInitialized) {
    return 0;
  }

  _Lock();

  if (_hRecThread == NULL) {
    RTC_LOG(LS_VERBOSE)
        << "no capturing stream is active => close down WASAPI only";
    SAFE_RELEASE(_ptrClientIn);
    SAFE_RELEASE(_ptrCaptureClient);
    _recIsInitialized = false;
    _recording = false;
    _UnLock();
    return 0;
  }

  // Stop the driving thread...
  RTC_LOG(LS_VERBOSE) << "closing down the webrtc_core_audio_capture_thread...";
  // Manual-reset event; it will remain signalled to stop all capture threads.
  SetEvent(_hShutdownCaptureEvent);

  _UnLock();
  DWORD ret = WaitForSingleObject(_hRecThread, 2000);
  if (ret != WAIT_OBJECT_0) {
    RTC_LOG(LS_ERROR)
        << "failed to close down webrtc_core_audio_capture_thread";
    err = -1;
  } else {
    RTC_LOG(LS_VERBOSE) << "webrtc_core_audio_capture_thread is now closed";
  }
  _Lock();

  ResetEvent(_hShutdownCaptureEvent);  // Must be manually reset.
  // Ensure that the thread has released these interfaces properly.
  assert(err == -1 || _ptrClientIn == NULL);
  assert(err == -1 || _ptrCaptureClient == NULL);

  _recIsInitialized = false;
  _recording = false;

  // These will create thread leaks in the result of an error,
  // but we can at least resume the call.
  CloseHandle(_hRecThread);
  _hRecThread = NULL;

  if (_builtInAecEnabled) {
    assert(_dmo != NULL);
    // This is necessary. Otherwise the DMO can generate garbage render
    // audio even after rendering has stopped.
    HRESULT hr = _dmo->FreeStreamingResources();
    if (FAILED(hr)) {
      _TraceCOMError(hr);
      err = -1;
    }
  }

  // Reset the recording delay value.
  _sndCardRecDelay = 0;

  _UnLock();

  return err;
}

// ----------------------------------------------------------------------------
//  RecordingIsInitialized
// ----------------------------------------------------------------------------

bool AudioDeviceWindowsCore::RecordingIsInitialized() const {
  return (_recIsInitialized);
}

// ----------------------------------------------------------------------------
//  Recording
// ----------------------------------------------------------------------------

bool AudioDeviceWindowsCore::Recording() const {
  return (_recording);
}

// ----------------------------------------------------------------------------
//  PlayoutIsInitialized
// ----------------------------------------------------------------------------

bool AudioDeviceWindowsCore::PlayoutIsInitialized() const {
  return (_playIsInitialized);
}

// ----------------------------------------------------------------------------
//  StartPlayout
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::StartPlayout() {
  if (!_playIsInitialized) {
    return -1;
  }

  if (_hPlayThread != NULL) {
    return 0;
  }

  if (_playing) {
    return 0;
  }

  {
    rtc::CritScope critScoped(&_critSect);

    // Create thread which will drive the rendering.
    assert(_hPlayThread == NULL);
    _hPlayThread = CreateThread(NULL, 0, WSAPIRenderThread, this, 0, NULL);
    if (_hPlayThread == NULL) {
      RTC_LOG(LS_ERROR) << "failed to create the playout thread";
      return -1;
    }

    // Set thread priority to highest possible.
    SetThreadPriority(_hPlayThread, THREAD_PRIORITY_TIME_CRITICAL);
  }  // critScoped

  DWORD ret = WaitForSingleObject(_hRenderStartedEvent, 1000);
  if (ret != WAIT_OBJECT_0) {
    RTC_LOG(LS_VERBOSE) << "rendering did not start up properly";
    return -1;
  }

  _playing = true;
  RTC_LOG(LS_VERBOSE) << "rendering audio stream has now started...";

  return 0;
}

// ----------------------------------------------------------------------------
//  StopPlayout
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::StopPlayout() {
  if (!_playIsInitialized) {
    return 0;
  }

  {
    rtc::CritScope critScoped(&_critSect);

    if (_hPlayThread == NULL) {
      RTC_LOG(LS_VERBOSE)
          << "no rendering stream is active => close down WASAPI only";
      SAFE_RELEASE(_ptrClientOut);
      SAFE_RELEASE(_ptrRenderClient);
      _playIsInitialized = false;
      _playing = false;
      return 0;
    }

    // stop the driving thread...
    RTC_LOG(LS_VERBOSE)
        << "closing down the webrtc_core_audio_render_thread...";
    SetEvent(_hShutdownRenderEvent);
  }  // critScoped

  DWORD ret = WaitForSingleObject(_hPlayThread, 2000);
  if (ret != WAIT_OBJECT_0) {
    // the thread did not stop as it should
    RTC_LOG(LS_ERROR) << "failed to close down webrtc_core_audio_render_thread";
    CloseHandle(_hPlayThread);
    _hPlayThread = NULL;
    _playIsInitialized = false;
    _playing = false;
    return -1;
  }

  {
    rtc::CritScope critScoped(&_critSect);
    RTC_LOG(LS_VERBOSE) << "webrtc_core_audio_render_thread is now closed";

    // to reset this event manually at each time we finish with it,
    // in case that the render thread has exited before StopPlayout(),
    // this event might be caught by the new render thread within same VoE
    // instance.
    ResetEvent(_hShutdownRenderEvent);

    SAFE_RELEASE(_ptrClientOut);
    SAFE_RELEASE(_ptrRenderClient);

    _playIsInitialized = false;
    _playing = false;

    CloseHandle(_hPlayThread);
    _hPlayThread = NULL;

    if (_builtInAecEnabled && _recording) {
      // The DMO won't provide us captured output data unless we
      // give it render data to process.
      //
      // We still permit the playout to shutdown, and trace a warning.
      // Otherwise, VoE can get into a state which will never permit
      // playout to stop properly.
      RTC_LOG(LS_WARNING)
          << "Recording should be stopped before playout when using the"
          << " built-in AEC";
    }

    // Reset the playout delay value.
    _sndCardPlayDelay = 0;
  }  // critScoped

  return 0;
}

// ----------------------------------------------------------------------------
//  PlayoutDelay
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::PlayoutDelay(uint16_t& delayMS) const {
  rtc::CritScope critScoped(&_critSect);
  delayMS = static_cast<uint16_t>(_sndCardPlayDelay);
  return 0;
}

bool AudioDeviceWindowsCore::BuiltInAECIsAvailable() const {
  return _dmo != nullptr;
}

// ----------------------------------------------------------------------------
//  Playing
// ----------------------------------------------------------------------------

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

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

// ----------------------------------------------------------------------------
//  [static] WSAPIRenderThread
// ----------------------------------------------------------------------------

DWORD WINAPI AudioDeviceWindowsCore::WSAPIRenderThread(LPVOID context) {
  return reinterpret_cast<AudioDeviceWindowsCore*>(context)->DoRenderThread();
}

// ----------------------------------------------------------------------------
//  [static] WSAPICaptureThread
// ----------------------------------------------------------------------------

DWORD WINAPI AudioDeviceWindowsCore::WSAPICaptureThread(LPVOID context) {
  return reinterpret_cast<AudioDeviceWindowsCore*>(context)->DoCaptureThread();
}

DWORD WINAPI AudioDeviceWindowsCore::WSAPICaptureThreadPollDMO(LPVOID context) {
  return reinterpret_cast<AudioDeviceWindowsCore*>(context)
      ->DoCaptureThreadPollDMO();
}

// ----------------------------------------------------------------------------
//  DoRenderThread
// ----------------------------------------------------------------------------

DWORD AudioDeviceWindowsCore::DoRenderThread() {
  bool keepPlaying = true;
  HANDLE waitArray[2] = {_hShutdownRenderEvent, _hRenderSamplesReadyEvent};
  HRESULT hr = S_OK;
  HANDLE hMmTask = NULL;

  // Initialize COM as MTA in this thread.
  ScopedCOMInitializer comInit(ScopedCOMInitializer::kMTA);
  if (!comInit.succeeded()) {
    RTC_LOG(LS_ERROR) << "failed to initialize COM in render thread";
    return 1;
  }

  rtc::SetCurrentThreadName("webrtc_core_audio_render_thread");

  // Use Multimedia Class Scheduler Service (MMCSS) to boost the thread
  // priority.
  //
  if (_winSupportAvrt) {
    DWORD taskIndex(0);
    hMmTask = _PAvSetMmThreadCharacteristicsA("Pro Audio", &taskIndex);
    if (hMmTask) {
      if (FALSE == _PAvSetMmThreadPriority(hMmTask, AVRT_PRIORITY_CRITICAL)) {
        RTC_LOG(LS_WARNING) << "failed to boost play-thread using MMCSS";
      }
      RTC_LOG(LS_VERBOSE)
          << "render thread is now registered with MMCSS (taskIndex="
          << taskIndex << ")";
    } else {
      RTC_LOG(LS_WARNING) << "failed to enable MMCSS on render thread (err="
                          << GetLastError() << ")";
      _TraceCOMError(GetLastError());
    }
  }

  _Lock();

  IAudioClock* clock = NULL;

  // Get size of rendering buffer (length is expressed as the number of audio
  // frames the buffer can hold). This value is fixed during the rendering
  // session.
  //
  UINT32 bufferLength = 0;
  hr = _ptrClientOut->GetBufferSize(&bufferLength);
  EXIT_ON_ERROR(hr);
  RTC_LOG(LS_VERBOSE) << "[REND] size of buffer       : " << bufferLength;

  // Get maximum latency for the current stream (will not change for the
  // lifetime  of the IAudioClient object).
  //
  REFERENCE_TIME latency;
  _ptrClientOut->GetStreamLatency(&latency);
  RTC_LOG(LS_VERBOSE) << "[REND] max stream latency   : " << (DWORD)latency
                      << " (" << (double)(latency / 10000.0) << " ms)";

  // Get the length of the periodic interval separating successive processing
  // passes by the audio engine on the data in the endpoint buffer.
  //
  // The period between processing passes by the audio engine is fixed for a
  // particular audio endpoint device and represents the smallest processing
  // quantum for the audio engine. This period plus the stream latency between
  // the buffer and endpoint device represents the minimum possible latency that
  // an audio application can achieve. Typical value: 100000 <=> 0.01 sec =
  // 10ms.
  //
  REFERENCE_TIME devPeriod = 0;
  REFERENCE_TIME devPeriodMin = 0;
  _ptrClientOut->GetDevicePeriod(&devPeriod, &devPeriodMin);
  RTC_LOG(LS_VERBOSE) << "[REND] device period        : " << (DWORD)devPeriod
                      << " (" << (double)(devPeriod / 10000.0) << " ms)";

  // Derive initial rendering delay.
  // Example: 10*(960/480) + 15 = 20 + 15 = 35ms
  //
  int playout_delay = 10 * (bufferLength / _playBlockSize) +
                      (int)((latency + devPeriod) / 10000);
  _sndCardPlayDelay = playout_delay;
  _writtenSamples = 0;
  RTC_LOG(LS_VERBOSE) << "[REND] initial delay        : " << playout_delay;

  double endpointBufferSizeMS =
      10.0 * ((double)bufferLength / (double)_devicePlayBlockSize);
  RTC_LOG(LS_VERBOSE) << "[REND] endpointBufferSizeMS : "
                      << endpointBufferSizeMS;

  // Before starting the stream, fill the rendering buffer with silence.
  //
  BYTE* pData = NULL;
  hr = _ptrRenderClient->GetBuffer(bufferLength, &pData);
  EXIT_ON_ERROR(hr);

  hr =
      _ptrRenderClient->ReleaseBuffer(bufferLength, AUDCLNT_BUFFERFLAGS_SILENT);
  EXIT_ON_ERROR(hr);

  _writtenSamples += bufferLength;

  hr = _ptrClientOut->GetService(__uuidof(IAudioClock), (void**)&clock);
  if (FAILED(hr)) {
    RTC_LOG(LS_WARNING)
        << "failed to get IAudioClock interface from the IAudioClient";
  }

  // Start up the rendering audio stream.
  hr = _ptrClientOut->Start();
  EXIT_ON_ERROR(hr);

  _UnLock();

  // Set event which will ensure that the calling thread modifies the playing
  // state to true.
  //
  SetEvent(_hRenderStartedEvent);

  // >> ------------------ THREAD LOOP ------------------

  while (keepPlaying) {
    // Wait for a render notification event or a shutdown event
    DWORD waitResult = WaitForMultipleObjects(2, waitArray, FALSE, 500);
    switch (waitResult) {
      case WAIT_OBJECT_0 + 0:  // _hShutdownRenderEvent
        keepPlaying = false;
        break;
      case WAIT_OBJECT_0 + 1:  // _hRenderSamplesReadyEvent
        break;
      case WAIT_TIMEOUT:  // timeout notification
        RTC_LOG(LS_WARNING) << "render event timed out after 0.5 seconds";
        goto Exit;
      default:  // unexpected error
        RTC_LOG(LS_WARNING) << "unknown wait termination on render side";
        goto Exit;
    }

    while (keepPlaying) {
      _Lock();

      // Sanity check to ensure that essential states are not modified
      // during the unlocked period.
      if (_ptrRenderClient == NULL || _ptrClientOut == NULL) {
        _UnLock();
        RTC_LOG(LS_ERROR)
            << "output state has been modified during unlocked period";
        goto Exit;
      }

      // Get the number of frames of padding (queued up to play) in the endpoint
      // buffer.
      UINT32 padding = 0;
      hr = _ptrClientOut->GetCurrentPadding(&padding);
      EXIT_ON_ERROR(hr);

      // Derive the amount of available space in the output buffer
      uint32_t framesAvailable = bufferLength - padding;

      // Do we have 10 ms available in the render buffer?
      if (framesAvailable < _playBlockSize) {
        // Not enough space in render buffer to store next render packet.
        _UnLock();
        break;
      }

      // Write n*10ms buffers to the render buffer
      const uint32_t n10msBuffers = (framesAvailable / _playBlockSize);
      for (uint32_t n = 0; n < n10msBuffers; n++) {
        // Get pointer (i.e., grab the buffer) to next space in the shared
        // render buffer.
        hr = _ptrRenderClient->GetBuffer(_playBlockSize, &pData);
        EXIT_ON_ERROR(hr);

        if (_ptrAudioBuffer) {
          // Request data to be played out (#bytes =
          // _playBlockSize*_audioFrameSize)
          _UnLock();
          int32_t nSamples =
              _ptrAudioBuffer->RequestPlayoutData(_playBlockSize);
          _Lock();

          if (nSamples == -1) {
            _UnLock();
            RTC_LOG(LS_ERROR) << "failed to read data from render client";
            goto Exit;
          }

          // Sanity check to ensure that essential states are not modified
          // during the unlocked period
          if (_ptrRenderClient == NULL || _ptrClientOut == NULL) {
            _UnLock();
            RTC_LOG(LS_ERROR)
                << "output state has been modified during unlocked"
                << " period";
            goto Exit;
          }
          if (nSamples != static_cast<int32_t>(_playBlockSize)) {
            RTC_LOG(LS_WARNING)
                << "nSamples(" << nSamples << ") != _playBlockSize"
                << _playBlockSize << ")";
          }

          // Get the actual (stored) data
          nSamples = _ptrAudioBuffer->GetPlayoutData((int8_t*)pData);
        }

        DWORD dwFlags(0);
        hr = _ptrRenderClient->ReleaseBuffer(_playBlockSize, dwFlags);
        // See http://msdn.microsoft.com/en-us/library/dd316605(VS.85).aspx
        // for more details regarding AUDCLNT_E_DEVICE_INVALIDATED.
        EXIT_ON_ERROR(hr);

        _writtenSamples += _playBlockSize;
      }

      // Check the current delay on the playout side.
      if (clock) {
        UINT64 pos = 0;
        UINT64 freq = 1;
        clock->GetPosition(&pos, NULL);
        clock->GetFrequency(&freq);
        playout_delay = ROUND((double(_writtenSamples) / _devicePlaySampleRate -
                               double(pos) / freq) *
                              1000.0);
        _sndCardPlayDelay = playout_delay;
      }

      _UnLock();
    }
  }

  // ------------------ THREAD LOOP ------------------ <<

  SleepMs(static_cast<DWORD>(endpointBufferSizeMS + 0.5));
  hr = _ptrClientOut->Stop();

Exit:
  SAFE_RELEASE(clock);

  if (FAILED(hr)) {
    _ptrClientOut->Stop();
    _UnLock();
    _TraceCOMError(hr);
  }

  if (_winSupportAvrt) {
    if (NULL != hMmTask) {
      _PAvRevertMmThreadCharacteristics(hMmTask);
    }
  }

  _Lock();

  if (keepPlaying) {
    if (_ptrClientOut != NULL) {
      hr = _ptrClientOut->Stop();
      if (FAILED(hr)) {
        _TraceCOMError(hr);
      }
      hr = _ptrClientOut->Reset();
      if (FAILED(hr)) {
        _TraceCOMError(hr);
      }
    }
    RTC_LOG(LS_ERROR)
        << "Playout error: rendering thread has ended pre-maturely";
  } else {
    RTC_LOG(LS_VERBOSE) << "_Rendering thread is now terminated properly";
  }

  _UnLock();

  return (DWORD)hr;
}

DWORD AudioDeviceWindowsCore::InitCaptureThreadPriority() {
  _hMmTask = NULL;

  rtc::SetCurrentThreadName("webrtc_core_audio_capture_thread");

  // Use Multimedia Class Scheduler Service (MMCSS) to boost the thread
  // priority.
  if (_winSupportAvrt) {
    DWORD taskIndex(0);
    _hMmTask = _PAvSetMmThreadCharacteristicsA("Pro Audio", &taskIndex);
    if (_hMmTask) {
      if (!_PAvSetMmThreadPriority(_hMmTask, AVRT_PRIORITY_CRITICAL)) {
        RTC_LOG(LS_WARNING) << "failed to boost rec-thread using MMCSS";
      }
      RTC_LOG(LS_VERBOSE)
          << "capture thread is now registered with MMCSS (taskIndex="
          << taskIndex << ")";
    } else {
      RTC_LOG(LS_WARNING) << "failed to enable MMCSS on capture thread (err="
                          << GetLastError() << ")";
      _TraceCOMError(GetLastError());
    }
  }

  return S_OK;
}

void AudioDeviceWindowsCore::RevertCaptureThreadPriority() {
  if (_winSupportAvrt) {
    if (NULL != _hMmTask) {
      _PAvRevertMmThreadCharacteristics(_hMmTask);
    }
  }

  _hMmTask = NULL;
}

DWORD AudioDeviceWindowsCore::DoCaptureThreadPollDMO() {
  assert(_mediaBuffer != NULL);
  bool keepRecording = true;

  // Initialize COM as MTA in this thread.
  ScopedCOMInitializer comInit(ScopedCOMInitializer::kMTA);
  if (!comInit.succeeded()) {
    RTC_LOG(LS_ERROR) << "failed to initialize COM in polling DMO thread";
    return 1;
  }

  HRESULT hr = InitCaptureThreadPriority();
  if (FAILED(hr)) {
    return hr;
  }

  // Set event which will ensure that the calling thread modifies the
  // recording state to true.
  SetEvent(_hCaptureStartedEvent);

  // >> ---------------------------- THREAD LOOP ----------------------------
  while (keepRecording) {
    // Poll the DMO every 5 ms.
    // (The same interval used in the Wave implementation.)
    DWORD waitResult = WaitForSingleObject(_hShutdownCaptureEvent, 5);
    switch (waitResult) {
      case WAIT_OBJECT_0:  // _hShutdownCaptureEvent
        keepRecording = false;
        break;
      case WAIT_TIMEOUT:  // timeout notification
        break;
      default:  // unexpected error
        RTC_LOG(LS_WARNING) << "Unknown wait termination on capture side";
        hr = -1;  // To signal an error callback.
        keepRecording = false;
        break;
    }

    while (keepRecording) {
      rtc::CritScope critScoped(&_critSect);

      DWORD dwStatus = 0;
      {
        DMO_OUTPUT_DATA_BUFFER dmoBuffer = {0};
        dmoBuffer.pBuffer = _mediaBuffer;
        dmoBuffer.pBuffer->AddRef();

        // Poll the DMO for AEC processed capture data. The DMO will
        // copy available data to |dmoBuffer|, and should only return
        // 10 ms frames. The value of |dwStatus| should be ignored.
        hr = _dmo->ProcessOutput(0, 1, &dmoBuffer, &dwStatus);
        SAFE_RELEASE(dmoBuffer.pBuffer);
        dwStatus = dmoBuffer.dwStatus;
      }
      if (FAILED(hr)) {
        _TraceCOMError(hr);
        keepRecording = false;
        assert(false);
        break;
      }

      ULONG bytesProduced = 0;
      BYTE* data;
      // Get a pointer to the data buffer. This should be valid until
      // the next call to ProcessOutput.
      hr = _mediaBuffer->GetBufferAndLength(&data, &bytesProduced);
      if (FAILED(hr)) {
        _TraceCOMError(hr);
        keepRecording = false;
        assert(false);
        break;
      }

      if (bytesProduced > 0) {
        const int kSamplesProduced = bytesProduced / _recAudioFrameSize;
        // TODO(andrew): verify that this is always satisfied. It might
        // be that ProcessOutput will try to return more than 10 ms if
        // we fail to call it frequently enough.
        assert(kSamplesProduced == static_cast<int>(_recBlockSize));
        assert(sizeof(BYTE) == sizeof(int8_t));
        _ptrAudioBuffer->SetRecordedBuffer(reinterpret_cast<int8_t*>(data),
                                           kSamplesProduced);
        _ptrAudioBuffer->SetVQEData(0, 0);

        _UnLock();  // Release lock while making the callback.
        _ptrAudioBuffer->DeliverRecordedData();
        _Lock();
      }

      // Reset length to indicate buffer availability.
      hr = _mediaBuffer->SetLength(0);
      if (FAILED(hr)) {
        _TraceCOMError(hr);
        keepRecording = false;
        assert(false);
        break;
      }

      if (!(dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE)) {
        // The DMO cannot currently produce more data. This is the
        // normal case; otherwise it means the DMO had more than 10 ms
        // of data available and ProcessOutput should be called again.
        break;
      }
    }
  }
  // ---------------------------- THREAD LOOP ---------------------------- <<

  RevertCaptureThreadPriority();

  if (FAILED(hr)) {
    RTC_LOG(LS_ERROR)
        << "Recording error: capturing thread has ended prematurely";
  } else {
    RTC_LOG(LS_VERBOSE) << "Capturing thread is now terminated properly";
  }

  return hr;
}

// ----------------------------------------------------------------------------
//  DoCaptureThread
// ----------------------------------------------------------------------------

DWORD AudioDeviceWindowsCore::DoCaptureThread() {
  bool keepRecording = true;
  HANDLE waitArray[2] = {_hShutdownCaptureEvent, _hCaptureSamplesReadyEvent};
  HRESULT hr = S_OK;

  LARGE_INTEGER t1;

  BYTE* syncBuffer = NULL;
  UINT32 syncBufIndex = 0;

  _readSamples = 0;

  // Initialize COM as MTA in this thread.
  ScopedCOMInitializer comInit(ScopedCOMInitializer::kMTA);
  if (!comInit.succeeded()) {
    RTC_LOG(LS_ERROR) << "failed to initialize COM in capture thread";
    return 1;
  }

  hr = InitCaptureThreadPriority();
  if (FAILED(hr)) {
    return hr;
  }

  _Lock();

  // Get size of capturing buffer (length is expressed as the number of audio
  // frames the buffer can hold). This value is fixed during the capturing
  // session.
  //
  UINT32 bufferLength = 0;
  if (_ptrClientIn == NULL) {
    RTC_LOG(LS_ERROR)
        << "input state has been modified before capture loop starts.";
    return 1;
  }
  hr = _ptrClientIn->GetBufferSize(&bufferLength);
  EXIT_ON_ERROR(hr);
  RTC_LOG(LS_VERBOSE) << "[CAPT] size of buffer       : " << bufferLength;

  // Allocate memory for sync buffer.
  // It is used for compensation between native 44.1 and internal 44.0 and
  // for cases when the capture buffer is larger than 10ms.
  //
  const UINT32 syncBufferSize = 2 * (bufferLength * _recAudioFrameSize);
  syncBuffer = new BYTE[syncBufferSize];
  if (syncBuffer == NULL) {
    return (DWORD)E_POINTER;
  }
  RTC_LOG(LS_VERBOSE) << "[CAPT] size of sync buffer  : " << syncBufferSize
                      << " [bytes]";

  // Get maximum latency for the current stream (will not change for the
  // lifetime of the IAudioClient object).
  //
  REFERENCE_TIME latency;
  _ptrClientIn->GetStreamLatency(&latency);
  RTC_LOG(LS_VERBOSE) << "[CAPT] max stream latency   : " << (DWORD)latency
                      << " (" << (double)(latency / 10000.0) << " ms)";

  // Get the length of the periodic interval separating successive processing
  // passes by the audio engine on the data in the endpoint buffer.
  //
  REFERENCE_TIME devPeriod = 0;
  REFERENCE_TIME devPeriodMin = 0;
  _ptrClientIn->GetDevicePeriod(&devPeriod, &devPeriodMin);
  RTC_LOG(LS_VERBOSE) << "[CAPT] device period        : " << (DWORD)devPeriod
                      << " (" << (double)(devPeriod / 10000.0) << " ms)";

  double extraDelayMS = (double)((latency + devPeriod) / 10000.0);
  RTC_LOG(LS_VERBOSE) << "[CAPT] extraDelayMS         : " << extraDelayMS;

  double endpointBufferSizeMS =
      10.0 * ((double)bufferLength / (double)_recBlockSize);
  RTC_LOG(LS_VERBOSE) << "[CAPT] endpointBufferSizeMS : "
                      << endpointBufferSizeMS;

  // Start up the capturing stream.
  //
  hr = _ptrClientIn->Start();
  EXIT_ON_ERROR(hr);

  _UnLock();

  // Set event which will ensure that the calling thread modifies the recording
  // state to true.
  //
  SetEvent(_hCaptureStartedEvent);

  // >> ---------------------------- THREAD LOOP ----------------------------

  while (keepRecording) {
    // Wait for a capture notification event or a shutdown event
    DWORD waitResult = WaitForMultipleObjects(2, waitArray, FALSE, 500);
    switch (waitResult) {
      case WAIT_OBJECT_0 + 0:  // _hShutdownCaptureEvent
        keepRecording = false;
        break;
      case WAIT_OBJECT_0 + 1:  // _hCaptureSamplesReadyEvent
        break;
      case WAIT_TIMEOUT:  // timeout notification
        RTC_LOG(LS_WARNING) << "capture event timed out after 0.5 seconds";
        goto Exit;
      default:  // unexpected error
        RTC_LOG(LS_WARNING) << "unknown wait termination on capture side";
        goto Exit;
    }

    while (keepRecording) {
      BYTE* pData = 0;
      UINT32 framesAvailable = 0;
      DWORD flags = 0;
      UINT64 recTime = 0;
      UINT64 recPos = 0;

      _Lock();

      // Sanity check to ensure that essential states are not modified
      // during the unlocked period.
      if (_ptrCaptureClient == NULL || _ptrClientIn == NULL) {
        _UnLock();
        RTC_LOG(LS_ERROR)
            << "input state has been modified during unlocked period";
        goto Exit;
      }

      //  Find out how much capture data is available
      //
      hr = _ptrCaptureClient->GetBuffer(
          &pData,            // packet which is ready to be read by used
          &framesAvailable,  // #frames in the captured packet (can be zero)
          &flags,            // support flags (check)
          &recPos,    // device position of first audio frame in data packet
          &recTime);  // value of performance counter at the time of recording
                      // the first audio frame

      if (SUCCEEDED(hr)) {
        if (AUDCLNT_S_BUFFER_EMPTY == hr) {
          // Buffer was empty => start waiting for a new capture notification
          // event
          _UnLock();
          break;
        }

        if (flags & AUDCLNT_BUFFERFLAGS_SILENT) {
          // Treat all of the data in the packet as silence and ignore the
          // actual data values.
          RTC_LOG(LS_WARNING) << "AUDCLNT_BUFFERFLAGS_SILENT";
          pData = NULL;
        }

        assert(framesAvailable != 0);

        if (pData) {
          CopyMemory(&syncBuffer[syncBufIndex * _recAudioFrameSize], pData,
                     framesAvailable * _recAudioFrameSize);
        } else {
          ZeroMemory(&syncBuffer[syncBufIndex * _recAudioFrameSize],
                     framesAvailable * _recAudioFrameSize);
        }
        assert(syncBufferSize >= (syncBufIndex * _recAudioFrameSize) +
                                     framesAvailable * _recAudioFrameSize);

        // Release the capture buffer
        //
        hr = _ptrCaptureClient->ReleaseBuffer(framesAvailable);
        EXIT_ON_ERROR(hr);

        _readSamples += framesAvailable;
        syncBufIndex += framesAvailable;

        QueryPerformanceCounter(&t1);

        // Get the current recording and playout delay.
        uint32_t sndCardRecDelay = (uint32_t)(
            ((((UINT64)t1.QuadPart * _perfCounterFactor) - recTime) / 10000) +
            (10 * syncBufIndex) / _recBlockSize - 10);
        uint32_t sndCardPlayDelay = static_cast<uint32_t>(_sndCardPlayDelay);

        _sndCardRecDelay = sndCardRecDelay;

        while (syncBufIndex >= _recBlockSize) {
          if (_ptrAudioBuffer) {
            _ptrAudioBuffer->SetRecordedBuffer((const int8_t*)syncBuffer,
                                               _recBlockSize);
            _ptrAudioBuffer->SetVQEData(sndCardPlayDelay, sndCardRecDelay);

            _ptrAudioBuffer->SetTypingStatus(KeyPressed());

            _UnLock();  // release lock while making the callback
            _ptrAudioBuffer->DeliverRecordedData();
            _Lock();  // restore the lock

            // Sanity check to ensure that essential states are not modified
            // during the unlocked period
            if (_ptrCaptureClient == NULL || _ptrClientIn == NULL) {
              _UnLock();
              RTC_LOG(LS_ERROR) << "input state has been modified during"
                                << " unlocked period";
              goto Exit;
            }
          }

          // store remaining data which was not able to deliver as 10ms segment
          MoveMemory(&syncBuffer[0],
                     &syncBuffer[_recBlockSize * _recAudioFrameSize],
                     (syncBufIndex - _recBlockSize) * _recAudioFrameSize);
          syncBufIndex -= _recBlockSize;
          sndCardRecDelay -= 10;
        }
      } else {
        // If GetBuffer returns AUDCLNT_E_BUFFER_ERROR, the thread consuming the
        // audio samples must wait for the next processing pass. The client
        // might benefit from keeping a count of the failed GetBuffer calls. If
        // GetBuffer returns this error repeatedly, the client can start a new
        // processing loop after shutting down the current client by calling
        // IAudioClient::Stop, IAudioClient::Reset, and releasing the audio
        // client.
        RTC_LOG(LS_ERROR) << "IAudioCaptureClient::GetBuffer returned"
                          << " AUDCLNT_E_BUFFER_ERROR, hr = 0x"
                          << rtc::ToHex(hr);
        goto Exit;
      }

      _UnLock();
    }
  }

  // ---------------------------- THREAD LOOP ---------------------------- <<

  if (_ptrClientIn) {
    hr = _ptrClientIn->Stop();
  }

Exit:
  if (FAILED(hr)) {
    _ptrClientIn->Stop();
    _UnLock();
    _TraceCOMError(hr);
  }

  RevertCaptureThreadPriority();

  _Lock();

  if (keepRecording) {
    if (_ptrClientIn != NULL) {
      hr = _ptrClientIn->Stop();
      if (FAILED(hr)) {
        _TraceCOMError(hr);
      }
      hr = _ptrClientIn->Reset();
      if (FAILED(hr)) {
        _TraceCOMError(hr);
      }
    }

    RTC_LOG(LS_ERROR)
        << "Recording error: capturing thread has ended pre-maturely";
  } else {
    RTC_LOG(LS_VERBOSE) << "_Capturing thread is now terminated properly";
  }

  SAFE_RELEASE(_ptrClientIn);
  SAFE_RELEASE(_ptrCaptureClient);

  _UnLock();

  if (syncBuffer) {
    delete[] syncBuffer;
  }

  return (DWORD)hr;
}

int32_t AudioDeviceWindowsCore::EnableBuiltInAEC(bool enable) {
  if (_recIsInitialized) {
    RTC_LOG(LS_ERROR)
        << "Attempt to set Windows AEC with recording already initialized";
    return -1;
  }

  if (_dmo == NULL) {
    RTC_LOG(LS_ERROR)
        << "Built-in AEC DMO was not initialized properly at create time";
    return -1;
  }

  _builtInAecEnabled = enable;
  return 0;
}

void AudioDeviceWindowsCore::_Lock() RTC_NO_THREAD_SAFETY_ANALYSIS {
  _critSect.Enter();
}

void AudioDeviceWindowsCore::_UnLock() RTC_NO_THREAD_SAFETY_ANALYSIS {
  _critSect.Leave();
}

int AudioDeviceWindowsCore::SetDMOProperties() {
  HRESULT hr = S_OK;
  assert(_dmo != NULL);

  rtc::scoped_refptr<IPropertyStore> ps;
  {
    IPropertyStore* ptrPS = NULL;
    hr = _dmo->QueryInterface(IID_IPropertyStore,
                              reinterpret_cast<void**>(&ptrPS));
    if (FAILED(hr) || ptrPS == NULL) {
      _TraceCOMError(hr);
      return -1;
    }
    ps = ptrPS;
    SAFE_RELEASE(ptrPS);
  }

  // Set the AEC system mode.
  // SINGLE_CHANNEL_AEC - AEC processing only.
  if (SetVtI4Property(ps, MFPKEY_WMAAECMA_SYSTEM_MODE, SINGLE_CHANNEL_AEC)) {
    return -1;
  }

  // Set the AEC source mode.
  // VARIANT_TRUE - Source mode (we poll the AEC for captured data).
  if (SetBoolProperty(ps, MFPKEY_WMAAECMA_DMO_SOURCE_MODE, VARIANT_TRUE) ==
      -1) {
    return -1;
  }

  // Enable the feature mode.
  // This lets us override all the default processing settings below.
  if (SetBoolProperty(ps, MFPKEY_WMAAECMA_FEATURE_MODE, VARIANT_TRUE) == -1) {
    return -1;
  }

  // Disable analog AGC (default enabled).
  if (SetBoolProperty(ps, MFPKEY_WMAAECMA_MIC_GAIN_BOUNDER, VARIANT_FALSE) ==
      -1) {
    return -1;
  }

  // Disable noise suppression (default enabled).
  // 0 - Disabled, 1 - Enabled
  if (SetVtI4Property(ps, MFPKEY_WMAAECMA_FEATR_NS, 0) == -1) {
    return -1;
  }

  // Relevant parameters to leave at default settings:
  // MFPKEY_WMAAECMA_FEATR_AGC - Digital AGC (disabled).
  // MFPKEY_WMAAECMA_FEATR_CENTER_CLIP - AEC center clipping (enabled).
  // MFPKEY_WMAAECMA_FEATR_ECHO_LENGTH - Filter length (256 ms).
  //   TODO(andrew): investigate decresing the length to 128 ms.
  // MFPKEY_WMAAECMA_FEATR_FRAME_SIZE - Frame size (0).
  //   0 is automatic; defaults to 160 samples (or 10 ms frames at the
  //   selected 16 kHz) as long as mic array processing is disabled.
  // MFPKEY_WMAAECMA_FEATR_NOISE_FILL - Comfort noise (enabled).
  // MFPKEY_WMAAECMA_FEATR_VAD - VAD (disabled).

  // Set the devices selected by VoE. If using a default device, we need to
  // search for the device index.
  int inDevIndex = _inputDeviceIndex;
  int outDevIndex = _outputDeviceIndex;
  if (!_usingInputDeviceIndex) {
    ERole role = eCommunications;
    if (_inputDevice == AudioDeviceModule::kDefaultDevice) {
      role = eConsole;
    }

    if (_GetDefaultDeviceIndex(eCapture, role, &inDevIndex) == -1) {
      return -1;
    }
  }

  if (!_usingOutputDeviceIndex) {
    ERole role = eCommunications;
    if (_outputDevice == AudioDeviceModule::kDefaultDevice) {
      role = eConsole;
    }

    if (_GetDefaultDeviceIndex(eRender, role, &outDevIndex) == -1) {
      return -1;
    }
  }

  DWORD devIndex = static_cast<uint32_t>(outDevIndex << 16) +
                   static_cast<uint32_t>(0x0000ffff & inDevIndex);
  RTC_LOG(LS_VERBOSE) << "Capture device index: " << inDevIndex
                      << ", render device index: " << outDevIndex;
  if (SetVtI4Property(ps, MFPKEY_WMAAECMA_DEVICE_INDEXES, devIndex) == -1) {
    return -1;
  }

  return 0;
}

int AudioDeviceWindowsCore::SetBoolProperty(IPropertyStore* ptrPS,
                                            REFPROPERTYKEY key,
                                            VARIANT_BOOL value) {
  PROPVARIANT pv;
  PropVariantInit(&pv);
  pv.vt = VT_BOOL;
  pv.boolVal = value;
  HRESULT hr = ptrPS->SetValue(key, pv);
  PropVariantClear(&pv);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    return -1;
  }
  return 0;
}

int AudioDeviceWindowsCore::SetVtI4Property(IPropertyStore* ptrPS,
                                            REFPROPERTYKEY key,
                                            LONG value) {
  PROPVARIANT pv;
  PropVariantInit(&pv);
  pv.vt = VT_I4;
  pv.lVal = value;
  HRESULT hr = ptrPS->SetValue(key, pv);
  PropVariantClear(&pv);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    return -1;
  }
  return 0;
}

// ----------------------------------------------------------------------------
//  _RefreshDeviceList
//
//  Creates a new list of endpoint rendering or capture devices after
//  deleting any previously created (and possibly out-of-date) list of
//  such devices.
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_RefreshDeviceList(EDataFlow dir) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  HRESULT hr = S_OK;
  IMMDeviceCollection* pCollection = NULL;

  assert(dir == eRender || dir == eCapture);
  assert(_ptrEnumerator != NULL);

  // Create a fresh list of devices using the specified direction
  hr = _ptrEnumerator->EnumAudioEndpoints(dir, DEVICE_STATE_ACTIVE,
                                          &pCollection);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(pCollection);
    return -1;
  }

  if (dir == eRender) {
    SAFE_RELEASE(_ptrRenderCollection);
    _ptrRenderCollection = pCollection;
  } else {
    SAFE_RELEASE(_ptrCaptureCollection);
    _ptrCaptureCollection = pCollection;
  }

  return 0;
}

// ----------------------------------------------------------------------------
//  _DeviceListCount
//
//  Gets a count of the endpoint rendering or capture devices in the
//  current list of such devices.
// ----------------------------------------------------------------------------

int16_t AudioDeviceWindowsCore::_DeviceListCount(EDataFlow dir) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  HRESULT hr = S_OK;
  UINT count = 0;

  assert(eRender == dir || eCapture == dir);

  if (eRender == dir && NULL != _ptrRenderCollection) {
    hr = _ptrRenderCollection->GetCount(&count);
  } else if (NULL != _ptrCaptureCollection) {
    hr = _ptrCaptureCollection->GetCount(&count);
  }

  if (FAILED(hr)) {
    _TraceCOMError(hr);
    return -1;
  }

  return static_cast<int16_t>(count);
}

// ----------------------------------------------------------------------------
//  _GetListDeviceName
//
//  Gets the friendly name of an endpoint rendering or capture device
//  from the current list of such devices. The caller uses an index
//  into the list to identify the device.
//
//  Uses: _ptrRenderCollection or _ptrCaptureCollection which is updated
//  in _RefreshDeviceList().
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_GetListDeviceName(EDataFlow dir,
                                                   int index,
                                                   LPWSTR szBuffer,
                                                   int bufferLen) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  HRESULT hr = S_OK;
  IMMDevice* pDevice = NULL;

  assert(dir == eRender || dir == eCapture);

  if (eRender == dir && NULL != _ptrRenderCollection) {
    hr = _ptrRenderCollection->Item(index, &pDevice);
  } else if (NULL != _ptrCaptureCollection) {
    hr = _ptrCaptureCollection->Item(index, &pDevice);
  }

  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(pDevice);
    return -1;
  }

  int32_t res = _GetDeviceName(pDevice, szBuffer, bufferLen);
  SAFE_RELEASE(pDevice);
  return res;
}

// ----------------------------------------------------------------------------
//  _GetDefaultDeviceName
//
//  Gets the friendly name of an endpoint rendering or capture device
//  given a specified device role.
//
//  Uses: _ptrEnumerator
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_GetDefaultDeviceName(EDataFlow dir,
                                                      ERole role,
                                                      LPWSTR szBuffer,
                                                      int bufferLen) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  HRESULT hr = S_OK;
  IMMDevice* pDevice = NULL;

  assert(dir == eRender || dir == eCapture);
  assert(role == eConsole || role == eCommunications);
  assert(_ptrEnumerator != NULL);

  hr = _ptrEnumerator->GetDefaultAudioEndpoint(dir, role, &pDevice);

  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(pDevice);
    return -1;
  }

  int32_t res = _GetDeviceName(pDevice, szBuffer, bufferLen);
  SAFE_RELEASE(pDevice);
  return res;
}

// ----------------------------------------------------------------------------
//  _GetListDeviceID
//
//  Gets the unique ID string of an endpoint rendering or capture device
//  from the current list of such devices. The caller uses an index
//  into the list to identify the device.
//
//  Uses: _ptrRenderCollection or _ptrCaptureCollection which is updated
//  in _RefreshDeviceList().
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_GetListDeviceID(EDataFlow dir,
                                                 int index,
                                                 LPWSTR szBuffer,
                                                 int bufferLen) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  HRESULT hr = S_OK;
  IMMDevice* pDevice = NULL;

  assert(dir == eRender || dir == eCapture);

  if (eRender == dir && NULL != _ptrRenderCollection) {
    hr = _ptrRenderCollection->Item(index, &pDevice);
  } else if (NULL != _ptrCaptureCollection) {
    hr = _ptrCaptureCollection->Item(index, &pDevice);
  }

  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(pDevice);
    return -1;
  }

  int32_t res = _GetDeviceID(pDevice, szBuffer, bufferLen);
  SAFE_RELEASE(pDevice);
  return res;
}

// ----------------------------------------------------------------------------
//  _GetDefaultDeviceID
//
//  Gets the uniqe device ID of an endpoint rendering or capture device
//  given a specified device role.
//
//  Uses: _ptrEnumerator
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_GetDefaultDeviceID(EDataFlow dir,
                                                    ERole role,
                                                    LPWSTR szBuffer,
                                                    int bufferLen) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  HRESULT hr = S_OK;
  IMMDevice* pDevice = NULL;

  assert(dir == eRender || dir == eCapture);
  assert(role == eConsole || role == eCommunications);
  assert(_ptrEnumerator != NULL);

  hr = _ptrEnumerator->GetDefaultAudioEndpoint(dir, role, &pDevice);

  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(pDevice);
    return -1;
  }

  int32_t res = _GetDeviceID(pDevice, szBuffer, bufferLen);
  SAFE_RELEASE(pDevice);
  return res;
}

int32_t AudioDeviceWindowsCore::_GetDefaultDeviceIndex(EDataFlow dir,
                                                       ERole role,
                                                       int* index) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  HRESULT hr = S_OK;
  WCHAR szDefaultDeviceID[MAX_PATH] = {0};
  WCHAR szDeviceID[MAX_PATH] = {0};

  const size_t kDeviceIDLength = sizeof(szDeviceID) / sizeof(szDeviceID[0]);
  assert(kDeviceIDLength ==
         sizeof(szDefaultDeviceID) / sizeof(szDefaultDeviceID[0]));

  if (_GetDefaultDeviceID(dir, role, szDefaultDeviceID, kDeviceIDLength) ==
      -1) {
    return -1;
  }

  IMMDeviceCollection* collection = _ptrCaptureCollection;
  if (dir == eRender) {
    collection = _ptrRenderCollection;
  }

  if (!collection) {
    RTC_LOG(LS_ERROR) << "Device collection not valid";
    return -1;
  }

  UINT count = 0;
  hr = collection->GetCount(&count);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    return -1;
  }

  *index = -1;
  for (UINT i = 0; i < count; i++) {
    memset(szDeviceID, 0, sizeof(szDeviceID));
    rtc::scoped_refptr<IMMDevice> device;
    {
      IMMDevice* ptrDevice = NULL;
      hr = collection->Item(i, &ptrDevice);
      if (FAILED(hr) || ptrDevice == NULL) {
        _TraceCOMError(hr);
        return -1;
      }
      device = ptrDevice;
      SAFE_RELEASE(ptrDevice);
    }

    if (_GetDeviceID(device, szDeviceID, kDeviceIDLength) == -1) {
      return -1;
    }

    if (wcsncmp(szDefaultDeviceID, szDeviceID, kDeviceIDLength) == 0) {
      // Found a match.
      *index = i;
      break;
    }
  }

  if (*index == -1) {
    RTC_LOG(LS_ERROR) << "Unable to find collection index for default device";
    return -1;
  }

  return 0;
}

// ----------------------------------------------------------------------------
//  _GetDeviceName
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_GetDeviceName(IMMDevice* pDevice,
                                               LPWSTR pszBuffer,
                                               int bufferLen) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  static const WCHAR szDefault[] = L"<Device not available>";

  HRESULT hr = E_FAIL;
  IPropertyStore* pProps = NULL;
  PROPVARIANT varName;

  assert(pszBuffer != NULL);
  assert(bufferLen > 0);

  if (pDevice != NULL) {
    hr = pDevice->OpenPropertyStore(STGM_READ, &pProps);
    if (FAILED(hr)) {
      RTC_LOG(LS_ERROR) << "IMMDevice::OpenPropertyStore failed, hr = 0x"
                        << rtc::ToHex(hr);
    }
  }

  // Initialize container for property value.
  PropVariantInit(&varName);

  if (SUCCEEDED(hr)) {
    // Get the endpoint device's friendly-name property.
    hr = pProps->GetValue(PKEY_Device_FriendlyName, &varName);
    if (FAILED(hr)) {
      RTC_LOG(LS_ERROR) << "IPropertyStore::GetValue failed, hr = 0x"
                        << rtc::ToHex(hr);
    }
  }

  if ((SUCCEEDED(hr)) && (VT_EMPTY == varName.vt)) {
    hr = E_FAIL;
    RTC_LOG(LS_ERROR) << "IPropertyStore::GetValue returned no value,"
                      << " hr = 0x" << rtc::ToHex(hr);
  }

  if ((SUCCEEDED(hr)) && (VT_LPWSTR != varName.vt)) {
    // The returned value is not a wide null terminated string.
    hr = E_UNEXPECTED;
    RTC_LOG(LS_ERROR) << "IPropertyStore::GetValue returned unexpected"
                      << " type, hr = 0x" << rtc::ToHex(hr);
  }

  if (SUCCEEDED(hr) && (varName.pwszVal != NULL)) {
    // Copy the valid device name to the provided ouput buffer.
    wcsncpy_s(pszBuffer, bufferLen, varName.pwszVal, _TRUNCATE);
  } else {
    // Failed to find the device name.
    wcsncpy_s(pszBuffer, bufferLen, szDefault, _TRUNCATE);
  }

  PropVariantClear(&varName);
  SAFE_RELEASE(pProps);

  return 0;
}

// ----------------------------------------------------------------------------
//  _GetDeviceID
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_GetDeviceID(IMMDevice* pDevice,
                                             LPWSTR pszBuffer,
                                             int bufferLen) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  static const WCHAR szDefault[] = L"<Device not available>";

  HRESULT hr = E_FAIL;
  LPWSTR pwszID = NULL;

  assert(pszBuffer != NULL);
  assert(bufferLen > 0);

  if (pDevice != NULL) {
    hr = pDevice->GetId(&pwszID);
  }

  if (hr == S_OK) {
    // Found the device ID.
    wcsncpy_s(pszBuffer, bufferLen, pwszID, _TRUNCATE);
  } else {
    // Failed to find the device ID.
    wcsncpy_s(pszBuffer, bufferLen, szDefault, _TRUNCATE);
  }

  CoTaskMemFree(pwszID);
  return 0;
}

// ----------------------------------------------------------------------------
//  _GetDefaultDevice
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_GetDefaultDevice(EDataFlow dir,
                                                  ERole role,
                                                  IMMDevice** ppDevice) {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  HRESULT hr(S_OK);

  assert(_ptrEnumerator != NULL);

  hr = _ptrEnumerator->GetDefaultAudioEndpoint(dir, role, ppDevice);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    return -1;
  }

  return 0;
}

// ----------------------------------------------------------------------------
//  _GetListDevice
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_GetListDevice(EDataFlow dir,
                                               int index,
                                               IMMDevice** ppDevice) {
  HRESULT hr(S_OK);

  assert(_ptrEnumerator != NULL);

  IMMDeviceCollection* pCollection = NULL;

  hr = _ptrEnumerator->EnumAudioEndpoints(
      dir,
      DEVICE_STATE_ACTIVE,  // only active endpoints are OK
      &pCollection);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(pCollection);
    return -1;
  }

  hr = pCollection->Item(index, ppDevice);
  if (FAILED(hr)) {
    _TraceCOMError(hr);
    SAFE_RELEASE(pCollection);
    return -1;
  }

  return 0;
}

// ----------------------------------------------------------------------------
//  _EnumerateEndpointDevicesAll
// ----------------------------------------------------------------------------

int32_t AudioDeviceWindowsCore::_EnumerateEndpointDevicesAll(
    EDataFlow dataFlow) const {
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  assert(_ptrEnumerator != NULL);

  HRESULT hr = S_OK;
  IMMDeviceCollection* pCollection = NULL;
  IMMDevice* pEndpoint = NULL;
  IPropertyStore* pProps = NULL;
  IAudioEndpointVolume* pEndpointVolume = NULL;
  LPWSTR pwszID = NULL;

  // Generate a collection of audio endpoint devices in the system.
  // Get states for *all* endpoint devices.
  // Output: IMMDeviceCollection interface.
  hr = _ptrEnumerator->EnumAudioEndpoints(
      dataFlow,  // data-flow direction (input parameter)
      DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED | DEVICE_STATE_UNPLUGGED,
      &pCollection);  // release interface when done

  EXIT_ON_ERROR(hr);

  // use the IMMDeviceCollection interface...

  UINT count = 0;

  // Retrieve a count of the devices in the device collection.
  hr = pCollection->GetCount(&count);
  EXIT_ON_ERROR(hr);
  if (dataFlow == eRender)
    RTC_LOG(LS_VERBOSE) << "#rendering endpoint devices (counting all): "
                        << count;
  else if (dataFlow == eCapture)
    RTC_LOG(LS_VERBOSE) << "#capturing endpoint devices (counting all): "
                        << count;

  if (count == 0) {
    return 0;
  }

  // Each loop prints the name of an endpoint device.
  for (ULONG i = 0; i < count; i++) {
    RTC_LOG(LS_VERBOSE) << "Endpoint " << i << ":";

    // Get pointer to endpoint number i.
    // Output: IMMDevice interface.
    hr = pCollection->Item(i, &pEndpoint);
    CONTINUE_ON_ERROR(hr);

    // use the IMMDevice interface of the specified endpoint device...

    // Get the endpoint ID string (uniquely identifies the device among all
    // audio endpoint devices)
    hr = pEndpoint->GetId(&pwszID);
    CONTINUE_ON_ERROR(hr);
    RTC_LOG(LS_VERBOSE) << "ID string    : " << pwszID;

    // Retrieve an interface to the device's property store.
    // Output: IPropertyStore interface.
    hr = pEndpoint->OpenPropertyStore(STGM_READ, &pProps);
    CONTINUE_ON_ERROR(hr);

    // use the IPropertyStore interface...

    PROPVARIANT varName;
    // Initialize container for property value.
    PropVariantInit(&varName);

    // Get the endpoint's friendly-name property.
    // Example: "Speakers (Realtek High Definition Audio)"
    hr = pProps->GetValue(PKEY_Device_FriendlyName, &varName);
    CONTINUE_ON_ERROR(hr);
    RTC_LOG(LS_VERBOSE) << "friendly name: \"" << varName.pwszVal << "\"";

    // Get the endpoint's current device state
    DWORD dwState;
    hr = pEndpoint->GetState(&dwState);
    CONTINUE_ON_ERROR(hr);
    if (dwState & DEVICE_STATE_ACTIVE)
      RTC_LOG(LS_VERBOSE) << "state (0x" << rtc::ToHex(dwState)
                          << ")  : *ACTIVE*";
    if (dwState & DEVICE_STATE_DISABLED)
      RTC_LOG(LS_VERBOSE) << "state (0x" << rtc::ToHex(dwState)
                          << ")  : DISABLED";
    if (dwState & DEVICE_STATE_NOTPRESENT)
      RTC_LOG(LS_VERBOSE) << "state (0x" << rtc::ToHex(dwState)
                          << ")  : NOTPRESENT";
    if (dwState & DEVICE_STATE_UNPLUGGED)
      RTC_LOG(LS_VERBOSE) << "state (0x" << rtc::ToHex(dwState)
                          << ")  : UNPLUGGED";

    // Check the hardware volume capabilities.
    DWORD dwHwSupportMask = 0;
    hr = pEndpoint->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
                             (void**)&pEndpointVolume);
    CONTINUE_ON_ERROR(hr);
    hr = pEndpointVolume->QueryHardwareSupport(&dwHwSupportMask);
    CONTINUE_ON_ERROR(hr);
    if (dwHwSupportMask & ENDPOINT_HARDWARE_SUPPORT_VOLUME)
      // The audio endpoint device supports a hardware volume control
      RTC_LOG(LS_VERBOSE) << "hwmask (0x" << rtc::ToHex(dwHwSupportMask)
                          << ") : HARDWARE_SUPPORT_VOLUME";
    if (dwHwSupportMask & ENDPOINT_HARDWARE_SUPPORT_MUTE)
      // The audio endpoint device supports a hardware mute control
      RTC_LOG(LS_VERBOSE) << "hwmask (0x" << rtc::ToHex(dwHwSupportMask)
                          << ") : HARDWARE_SUPPORT_MUTE";
    if (dwHwSupportMask & ENDPOINT_HARDWARE_SUPPORT_METER)
      // The audio endpoint device supports a hardware peak meter
      RTC_LOG(LS_VERBOSE) << "hwmask (0x" << rtc::ToHex(dwHwSupportMask)
                          << ") : HARDWARE_SUPPORT_METER";

    // Check the channel count (#channels in the audio stream that enters or
    // leaves the audio endpoint device)
    UINT nChannelCount(0);
    hr = pEndpointVolume->GetChannelCount(&nChannelCount);
    CONTINUE_ON_ERROR(hr);
    RTC_LOG(LS_VERBOSE) << "#channels    : " << nChannelCount;

    if (dwHwSupportMask & ENDPOINT_HARDWARE_SUPPORT_VOLUME) {
      // Get the volume range.
      float fLevelMinDB(0.0);
      float fLevelMaxDB(0.0);
      float fVolumeIncrementDB(0.0);
      hr = pEndpointVolume->GetVolumeRange(&fLevelMinDB, &fLevelMaxDB,
                                           &fVolumeIncrementDB);
      CONTINUE_ON_ERROR(hr);
      RTC_LOG(LS_VERBOSE) << "volume range : " << fLevelMinDB << " (min), "
                          << fLevelMaxDB << " (max), " << fVolumeIncrementDB
                          << " (inc) [dB]";

      // The volume range from vmin = fLevelMinDB to vmax = fLevelMaxDB is
      // divided into n uniform intervals of size vinc = fVolumeIncrementDB,
      // where n = (vmax ?vmin) / vinc. The values vmin, vmax, and vinc are
      // measured in decibels. The client can set the volume level to one of n +
      // 1 discrete values in the range from vmin to vmax.
      int n = (int)((fLevelMaxDB - fLevelMinDB) / fVolumeIncrementDB);
      RTC_LOG(LS_VERBOSE) << "#intervals   : " << n;

      // Get information about the current step in the volume range.
      // This method represents the volume level of the audio stream that enters
      // or leaves the audio endpoint device as an index or "step" in a range of
      // discrete volume levels. Output value nStepCount is the number of steps
      // in the range. Output value nStep is the step index of the current
      // volume level. If the number of steps is n = nStepCount, then step index
      // nStep can assume values from 0 (minimum volume) to n ?1 (maximum
      // volume).
      UINT nStep(0);
      UINT nStepCount(0);
      hr = pEndpointVolume->GetVolumeStepInfo(&nStep, &nStepCount);
      CONTINUE_ON_ERROR(hr);
      RTC_LOG(LS_VERBOSE) << "volume steps : " << nStep << " (nStep), "
                          << nStepCount << " (nStepCount)";
    }
  Next:
    if (FAILED(hr)) {
      RTC_LOG(LS_VERBOSE) << "Error when logging device information";
    }
    CoTaskMemFree(pwszID);
    pwszID = NULL;
    PropVariantClear(&varName);
    SAFE_RELEASE(pProps);
    SAFE_RELEASE(pEndpoint);
    SAFE_RELEASE(pEndpointVolume);
  }
  SAFE_RELEASE(pCollection);
  return 0;

Exit:
  _TraceCOMError(hr);
  CoTaskMemFree(pwszID);
  pwszID = NULL;
  SAFE_RELEASE(pCollection);
  SAFE_RELEASE(pEndpoint);
  SAFE_RELEASE(pEndpointVolume);
  SAFE_RELEASE(pProps);
  return -1;
}

// ----------------------------------------------------------------------------
//  _TraceCOMError
// ----------------------------------------------------------------------------

void AudioDeviceWindowsCore::_TraceCOMError(HRESULT hr) const {
  wchar_t buf[MAXERRORLENGTH];
  wchar_t errorText[MAXERRORLENGTH];

  const DWORD dwFlags =
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
  const DWORD dwLangID = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);

  // Gets the system's human readable message string for this HRESULT.
  // All error message in English by default.
  DWORD messageLength = ::FormatMessageW(dwFlags, 0, hr, dwLangID, errorText,
                                         MAXERRORLENGTH, NULL);

  assert(messageLength <= MAXERRORLENGTH);

  // Trims tailing white space (FormatMessage() leaves a trailing cr-lf.).
  for (; messageLength && ::isspace(errorText[messageLength - 1]);
       --messageLength) {
    errorText[messageLength - 1] = '\0';
  }

  RTC_LOG(LS_ERROR) << "Core Audio method failed (hr=" << hr << ")";
  StringCchPrintfW(buf, MAXERRORLENGTH, L"Error details: ");
  StringCchCatW(buf, MAXERRORLENGTH, errorText);
  RTC_LOG(LS_ERROR) << WideToUTF8(buf);
}

// ----------------------------------------------------------------------------
//  WideToUTF8
// ----------------------------------------------------------------------------

char* AudioDeviceWindowsCore::WideToUTF8(const wchar_t* src) const {
  const size_t kStrLen = sizeof(_str);
  memset(_str, 0, kStrLen);
  // Get required size (in bytes) to be able to complete the conversion.
  unsigned int required_size =
      (unsigned int)WideCharToMultiByte(CP_UTF8, 0, src, -1, _str, 0, 0, 0);
  if (required_size <= kStrLen) {
    // Process the entire input string, including the terminating null char.
    if (WideCharToMultiByte(CP_UTF8, 0, src, -1, _str, kStrLen, 0, 0) == 0)
      memset(_str, 0, kStrLen);
  }
  return _str;
}

bool AudioDeviceWindowsCore::KeyPressed() const {
  int key_down = 0;
  for (int key = VK_SPACE; key < VK_NUMLOCK; key++) {
    short res = GetAsyncKeyState(key);
    key_down |= res & 0x1;  // Get the LSB
  }
  return (key_down > 0);
}
}  // namespace webrtc

#endif  // WEBRTC_WINDOWS_CORE_AUDIO_BUILD
