/*
 *  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";
    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.
  //
  if (MMDeviceIsAvailable) {
    coreAudioIsSupported = false;

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

    int ok(0);

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

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

  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),
      _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() {
  MutexLock lock(&mutex_);

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

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

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

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

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

    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;
  volume_mutex_.Lock();
  hr = _ptrRenderSimpleVolume->SetMasterVolume(fLevel, NULL);
  volume_mutex_.Unlock();
  EXIT_ON_ERROR(hr);

  return 0;

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

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

int32_t AudioDeviceWindowsCore::SpeakerVolume(uint32_t& volume) const {
  {
    MutexLock lock(&mutex_);

    if (!_speakerIsInitialized) {
      return -1;
    }

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

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

  volume_mutex_.Lock();
  hr = _ptrRenderSimpleVolume->GetMasterVolume(&fLevel);
  volume_mutex_.Unlock();
  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) {
  MutexLock lock(&mutex_);

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

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

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

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

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

  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 << ")";

  {
    MutexLock lock(&mutex_);

    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;
  volume_mutex_.Lock();
  _ptrCaptureVolume->SetMasterVolumeLevelScalar(fLevel, NULL);
  volume_mutex_.Unlock();
  EXIT_ON_ERROR(hr);

  return 0;

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

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

int32_t AudioDeviceWindowsCore::MicrophoneVolume(uint32_t& volume) const {
  {
    MutexLock lock(&mutex_);

    if (!_microphoneIsInitialized) {
      return -1;
    }

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

  HRESULT hr = S_OK;
  float fLevel(0.0f);
  volume = 0;
  volume_mutex_.Lock();
  hr = _ptrCaptureVolume->GetMasterVolumeLevelScalar(&fLevel);
  volume_mutex_.Unlock();
  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() {
  MutexLock lock(&mutex_);

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

  MutexLock lock(&mutex_);

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

  MutexLock lock(&mutex_);

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

  MutexLock lock(&mutex_);

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

  MutexLock lock(&mutex_);

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

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

  MutexLock lock(&mutex_);

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

  MutexLock lock(&mutex_);

  // 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() {
  MutexLock lock(&mutex_);

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

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

  {
    MutexLock lockScoped(&mutex_);

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

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

  {
    MutexLock lockScoped(&mutex_);

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

  {
    MutexLock lockScoped(&mutex_);

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

  {
    MutexLock lockScoped(&mutex_);
    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 {
  MutexLock lockScoped(&mutex_);
  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) {
      MutexLock lockScoped(&mutex_);

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

        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 {
  mutex_.Lock();
}

void AudioDeviceWindowsCore::_UnLock() RTC_NO_THREAD_SAFETY_ANALYSIS {
  mutex_.Unlock();
}

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) << rtc::ToUtf8(buf);
}

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
