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

#include "modules/audio_device/linux/audio_device_alsa_linux.h"

#include <asm-generic/errno.h>

#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <vector>

#include "api/audio/audio_device.h"
#include "api/audio/audio_device_defines.h"
#include "modules/audio_device/audio_device_buffer.h"
#include "modules/audio_device/audio_device_generic.h"
#include "modules/audio_device/linux/latebindingsymboltable_linux.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread.h"

#if defined(WEBRTC_USE_X11)
#include <X11/Xlib.h>
#endif

WebRTCAlsaSymbolTable* GetAlsaSymbolTable() {
  static WebRTCAlsaSymbolTable* alsa_symbol_table = []() {
    auto* table = new WebRTCAlsaSymbolTable();
    table->Load();
    return table;
  }();
  return alsa_symbol_table;
}

// Accesses ALSA functions through our late-binding symbol table instead of
// directly. This way we don't have to link to libasound, which means our binary
// will work on systems that don't have it.
#define LATE(sym)                                                            \
  LATESYM_GET(webrtc::adm_linux_alsa::AlsaSymbolTable, GetAlsaSymbolTable(), \
              sym)

// Redefine these here to be able to do late-binding
#undef snd_ctl_card_info_alloca
#define snd_ctl_card_info_alloca(ptr)                  \
  do {                                                 \
    *ptr = (snd_ctl_card_info_t*)__builtin_alloca(     \
        LATE(snd_ctl_card_info_sizeof)());             \
    memset(*ptr, 0, LATE(snd_ctl_card_info_sizeof)()); \
  } while (0)

#undef snd_pcm_info_alloca
#define snd_pcm_info_alloca(pInfo)                                           \
  do {                                                                       \
    *pInfo = (snd_pcm_info_t*)__builtin_alloca(LATE(snd_pcm_info_sizeof)()); \
    memset(*pInfo, 0, LATE(snd_pcm_info_sizeof)());                          \
  } while (0)

// snd_lib_error_handler_t
void WebrtcAlsaErrorHandler(const char* file,
                            int line,
                            const char* function,
                            int err,
                            const char* fmt,
                            ...) {}

namespace webrtc {
static const unsigned int ALSA_PLAYOUT_FREQ = 48000;
static const unsigned int ALSA_PLAYOUT_CH = 2;
static const unsigned int ALSA_PLAYOUT_LATENCY = 40 * 1000;  // in us
static const unsigned int ALSA_CAPTURE_FREQ = 48000;
static const unsigned int ALSA_CAPTURE_CH = 2;
static const unsigned int ALSA_CAPTURE_LATENCY = 40 * 1000;  // in us
static const unsigned int ALSA_CAPTURE_WAIT_TIMEOUT = 5;     // in ms

#define FUNC_GET_NUM_OF_DEVICE 0
#define FUNC_GET_DEVICE_NAME 1
#define FUNC_GET_DEVICE_NAME_FOR_AN_ENUM 2

AudioDeviceLinuxALSA::AudioDeviceLinuxALSA()
    : _ptrAudioBuffer(nullptr),
      _inputDeviceIndex(0),
      _outputDeviceIndex(0),
      _inputDeviceIsSpecified(false),
      _outputDeviceIsSpecified(false),
      _handleRecord(nullptr),
      _handlePlayout(nullptr),
      _recordingBuffersizeInFrame(0),
      _recordingPeriodSizeInFrame(0),
      _playoutBufferSizeInFrame(0),
      _playoutPeriodSizeInFrame(0),
      _recordingBufferSizeIn10MS(0),
      _playoutBufferSizeIn10MS(0),
      _recordingFramesIn10MS(0),
      _playoutFramesIn10MS(0),
      _recordingFreq(ALSA_CAPTURE_FREQ),
      _playoutFreq(ALSA_PLAYOUT_FREQ),
      _recChannels(ALSA_CAPTURE_CH),
      _playChannels(ALSA_PLAYOUT_CH),
      _recordingBuffer(nullptr),
      _playoutBuffer(nullptr),
      _recordingFramesLeft(0),
      _playoutFramesLeft(0),
      _initialized(false),
      _recording(false),
      _playing(false),
      _recIsInitialized(false),
      _playIsInitialized(false),
      _recordingDelay(0),
      _playoutDelay(0) {
  memset(_oldKeyState, 0, sizeof(_oldKeyState));
  RTC_DLOG(LS_INFO) << __FUNCTION__ << " created";
}

// ----------------------------------------------------------------------------
//  AudioDeviceLinuxALSA - dtor
// ----------------------------------------------------------------------------

AudioDeviceLinuxALSA::~AudioDeviceLinuxALSA() {
  RTC_DLOG(LS_INFO) << __FUNCTION__ << " destroyed";

  Terminate();

  // Clean up the recording buffer and playout buffer.
  if (_recordingBuffer) {
    delete[] _recordingBuffer;
    _recordingBuffer = nullptr;
  }
  if (_playoutBuffer) {
    delete[] _playoutBuffer;
    _playoutBuffer = nullptr;
  }
}

void AudioDeviceLinuxALSA::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
  MutexLock lock(&mutex_);

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

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

AudioDeviceGeneric::InitStatus AudioDeviceLinuxALSA::Init() {
  MutexLock lock(&mutex_);

  // Load libasound
  if (!GetAlsaSymbolTable()->IsLoaded()) {
    // Alsa is not installed on this system
    RTC_LOG(LS_ERROR) << "failed to load symbol table";
    return InitStatus::OTHER_ERROR;
  }

  if (_initialized) {
    return InitStatus::OK;
  }
#if defined(WEBRTC_USE_X11)
  // Get X display handle for typing detection
  _XDisplay = XOpenDisplay(nullptr);
  if (!_XDisplay) {
    RTC_LOG(LS_WARNING)
        << "failed to open X display, typing detection will not work";
  }
#endif

  _initialized = true;

  return InitStatus::OK;
}

int32_t AudioDeviceLinuxALSA::Terminate() {
  if (!_initialized) {
    return 0;
  }

  MutexLock lock(&mutex_);

  _mixerManager.Close();

  // RECORDING
  mutex_.Unlock();
  _ptrThreadRec.Finalize();

  // PLAYOUT
  _ptrThreadPlay.Finalize();
  mutex_.Lock();

#if defined(WEBRTC_USE_X11)
  if (_XDisplay) {
    XCloseDisplay(_XDisplay);
    _XDisplay = nullptr;
  }
#endif
  _initialized = false;
  _outputDeviceIsSpecified = false;
  _inputDeviceIsSpecified = false;

  return 0;
}

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

int32_t AudioDeviceLinuxALSA::InitSpeaker() {
  MutexLock lock(&mutex_);
  return InitSpeakerLocked();
}

int32_t AudioDeviceLinuxALSA::InitSpeakerLocked() {
  if (_playing) {
    return -1;
  }

  char devName[kAdmMaxDeviceNameSize] = {0};
  GetDevicesInfo(2, true, _outputDeviceIndex, devName, kAdmMaxDeviceNameSize);
  return _mixerManager.OpenSpeaker(devName);
}

int32_t AudioDeviceLinuxALSA::InitMicrophone() {
  MutexLock lock(&mutex_);
  return InitMicrophoneLocked();
}

int32_t AudioDeviceLinuxALSA::InitMicrophoneLocked() {
  if (_recording) {
    return -1;
  }

  char devName[kAdmMaxDeviceNameSize] = {0};
  GetDevicesInfo(2, false, _inputDeviceIndex, devName, kAdmMaxDeviceNameSize);
  return _mixerManager.OpenMicrophone(devName);
}

bool AudioDeviceLinuxALSA::SpeakerIsInitialized() const {
  return (_mixerManager.SpeakerIsInitialized());
}

bool AudioDeviceLinuxALSA::MicrophoneIsInitialized() const {
  return (_mixerManager.MicrophoneIsInitialized());
}

int32_t AudioDeviceLinuxALSA::SpeakerVolumeIsAvailable(bool& available) {
  bool wasInitialized = _mixerManager.SpeakerIsInitialized();

  // Make an attempt to open up the
  // output mixer corresponding to the currently selected output device.
  if (!wasInitialized && InitSpeaker() == -1) {
    // If we end up here it means that the selected speaker has no volume
    // control.
    available = false;
    return 0;
  }

  // Given that InitSpeaker was successful, we know that a volume control
  // exists
  available = true;

  // Close the initialized output mixer
  if (!wasInitialized) {
    _mixerManager.CloseSpeaker();
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::SetSpeakerVolume(uint32_t volume) {
  return (_mixerManager.SetSpeakerVolume(volume));
}

int32_t AudioDeviceLinuxALSA::SpeakerVolume(uint32_t& volume) const {
  uint32_t level(0);

  if (_mixerManager.SpeakerVolume(level) == -1) {
    return -1;
  }

  volume = level;

  return 0;
}

int32_t AudioDeviceLinuxALSA::MaxSpeakerVolume(uint32_t& maxVolume) const {
  uint32_t maxVol(0);

  if (_mixerManager.MaxSpeakerVolume(maxVol) == -1) {
    return -1;
  }

  maxVolume = maxVol;

  return 0;
}

int32_t AudioDeviceLinuxALSA::MinSpeakerVolume(uint32_t& minVolume) const {
  uint32_t minVol(0);

  if (_mixerManager.MinSpeakerVolume(minVol) == -1) {
    return -1;
  }

  minVolume = minVol;

  return 0;
}

int32_t AudioDeviceLinuxALSA::SpeakerMuteIsAvailable(bool& available) {
  bool isAvailable(false);
  bool wasInitialized = _mixerManager.SpeakerIsInitialized();

  // Make an attempt to open up the
  // output mixer corresponding to the currently selected output device.
  //
  if (!wasInitialized && InitSpeaker() == -1) {
    // If we end up here it means that the selected speaker has no volume
    // control, hence it is safe to state that there is no mute control
    // already at this stage.
    available = false;
    return 0;
  }

  // Check if the selected speaker has a mute control
  _mixerManager.SpeakerMuteIsAvailable(isAvailable);

  available = isAvailable;

  // Close the initialized output mixer
  if (!wasInitialized) {
    _mixerManager.CloseSpeaker();
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::SetSpeakerMute(bool enable) {
  return (_mixerManager.SetSpeakerMute(enable));
}

int32_t AudioDeviceLinuxALSA::SpeakerMute(bool& enabled) const {
  bool muted(0);

  if (_mixerManager.SpeakerMute(muted) == -1) {
    return -1;
  }

  enabled = muted;

  return 0;
}

int32_t AudioDeviceLinuxALSA::MicrophoneMuteIsAvailable(bool& available) {
  bool isAvailable(false);
  bool wasInitialized = _mixerManager.MicrophoneIsInitialized();

  // Make an attempt to open up the
  // input mixer corresponding to the currently selected input device.
  //
  if (!wasInitialized && InitMicrophone() == -1) {
    // If we end up here it means that the selected microphone has no volume
    // control, hence it is safe to state that there is no mute control
    // already at this stage.
    available = false;
    return 0;
  }

  // Check if the selected microphone has a mute control
  //
  _mixerManager.MicrophoneMuteIsAvailable(isAvailable);
  available = isAvailable;

  // Close the initialized input mixer
  //
  if (!wasInitialized) {
    _mixerManager.CloseMicrophone();
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::SetMicrophoneMute(bool enable) {
  return (_mixerManager.SetMicrophoneMute(enable));
}

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

int32_t AudioDeviceLinuxALSA::MicrophoneMute(bool& enabled) const {
  bool muted(0);

  if (_mixerManager.MicrophoneMute(muted) == -1) {
    return -1;
  }

  enabled = muted;
  return 0;
}

int32_t AudioDeviceLinuxALSA::StereoRecordingIsAvailable(bool& available) {
  MutexLock lock(&mutex_);

  // If we already have initialized in stereo it's obviously available
  if (_recIsInitialized && (2 == _recChannels)) {
    available = true;
    return 0;
  }

  // Save rec states and the number of rec channels
  bool recIsInitialized = _recIsInitialized;
  bool recording = _recording;
  int recChannels = _recChannels;

  available = false;

  // Stop/uninitialize recording if initialized (and possibly started)
  if (_recIsInitialized) {
    StopRecordingLocked();
  }

  // Try init in stereo;
  _recChannels = 2;
  if (InitRecordingLocked() == 0) {
    available = true;
  }

  // Stop/uninitialize recording
  StopRecordingLocked();

  // Recover previous states
  _recChannels = recChannels;
  if (recIsInitialized) {
    InitRecordingLocked();
  }
  if (recording) {
    StartRecording();
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::SetStereoRecording(bool enable) {
  if (enable)
    _recChannels = 2;
  else
    _recChannels = 1;

  return 0;
}

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

  return 0;
}

int32_t AudioDeviceLinuxALSA::StereoPlayoutIsAvailable(bool& available) {
  MutexLock lock(&mutex_);

  // If we already have initialized in stereo it's obviously available
  if (_playIsInitialized && (2 == _playChannels)) {
    available = true;
    return 0;
  }

  // Save rec states and the number of rec channels
  bool playIsInitialized = _playIsInitialized;
  bool playing = _playing;
  int playChannels = _playChannels;

  available = false;

  // Stop/uninitialize recording if initialized (and possibly started)
  if (_playIsInitialized) {
    StopPlayoutLocked();
  }

  // Try init in stereo;
  _playChannels = 2;
  if (InitPlayoutLocked() == 0) {
    available = true;
  }

  // Stop/uninitialize recording
  StopPlayoutLocked();

  // Recover previous states
  _playChannels = playChannels;
  if (playIsInitialized) {
    InitPlayoutLocked();
  }
  if (playing) {
    StartPlayout();
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::SetStereoPlayout(bool enable) {
  if (enable)
    _playChannels = 2;
  else
    _playChannels = 1;

  return 0;
}

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

  return 0;
}

int32_t AudioDeviceLinuxALSA::MicrophoneVolumeIsAvailable(bool& available) {
  bool wasInitialized = _mixerManager.MicrophoneIsInitialized();

  // Make an attempt to open up the
  // input mixer corresponding to the currently selected output device.
  if (!wasInitialized && InitMicrophone() == -1) {
    // If we end up here it means that the selected microphone has no volume
    // control.
    available = false;
    return 0;
  }

  // Given that InitMicrophone was successful, we know that a volume control
  // exists
  available = true;

  // Close the initialized input mixer
  if (!wasInitialized) {
    _mixerManager.CloseMicrophone();
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::SetMicrophoneVolume(uint32_t volume) {
  return (_mixerManager.SetMicrophoneVolume(volume));
}

int32_t AudioDeviceLinuxALSA::MicrophoneVolume(uint32_t& volume) const {
  uint32_t level(0);

  if (_mixerManager.MicrophoneVolume(level) == -1) {
    RTC_LOG(LS_WARNING) << "failed to retrive current microphone level";
    return -1;
  }

  volume = level;

  return 0;
}

int32_t AudioDeviceLinuxALSA::MaxMicrophoneVolume(uint32_t& maxVolume) const {
  uint32_t maxVol(0);

  if (_mixerManager.MaxMicrophoneVolume(maxVol) == -1) {
    return -1;
  }

  maxVolume = maxVol;

  return 0;
}

int32_t AudioDeviceLinuxALSA::MinMicrophoneVolume(uint32_t& minVolume) const {
  uint32_t minVol(0);

  if (_mixerManager.MinMicrophoneVolume(minVol) == -1) {
    return -1;
  }

  minVolume = minVol;

  return 0;
}

int16_t AudioDeviceLinuxALSA::PlayoutDevices() {
  return (int16_t)GetDevicesInfo(0, true);
}

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

  int32_t nDevices = GetDevicesInfo(0, true);
  RTC_LOG(LS_VERBOSE) << "number of available audio output devices is "
                      << nDevices;

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

  _outputDeviceIndex = index;
  _outputDeviceIsSpecified = true;

  return 0;
}

int32_t AudioDeviceLinuxALSA::SetPlayoutDevice(
    AudioDeviceModule::WindowsDeviceType /*device*/) {
  RTC_LOG(LS_ERROR) << "WindowsDeviceType not supported";
  return -1;
}

int32_t AudioDeviceLinuxALSA::PlayoutDeviceName(
    uint16_t index,
    char name[kAdmMaxDeviceNameSize],
    char guid[kAdmMaxGuidSize]) {
  const uint16_t nDevices(PlayoutDevices());

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

  memset(name, 0, kAdmMaxDeviceNameSize);

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

  return GetDevicesInfo(1, true, index, name, kAdmMaxDeviceNameSize);
}

int32_t AudioDeviceLinuxALSA::RecordingDeviceName(
    uint16_t index,
    char name[kAdmMaxDeviceNameSize],
    char guid[kAdmMaxGuidSize]) {
  const uint16_t nDevices(RecordingDevices());

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

  memset(name, 0, kAdmMaxDeviceNameSize);

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

  return GetDevicesInfo(1, false, index, name, kAdmMaxDeviceNameSize);
}

int16_t AudioDeviceLinuxALSA::RecordingDevices() {
  return (int16_t)GetDevicesInfo(0, false);
}

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

  int32_t nDevices = GetDevicesInfo(0, false);
  RTC_LOG(LS_VERBOSE) << "number of availiable audio input devices is "
                      << nDevices;

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

  _inputDeviceIndex = index;
  _inputDeviceIsSpecified = true;

  return 0;
}

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

int32_t AudioDeviceLinuxALSA::SetRecordingDevice(
    AudioDeviceModule::WindowsDeviceType /*device*/) {
  RTC_LOG(LS_ERROR) << "WindowsDeviceType not supported";
  return -1;
}

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

  // Try to initialize the playout side with mono
  // Assumes that user set num channels after calling this function
  _playChannels = 1;
  int32_t res = InitPlayout();

  // Cancel effect of initialization
  StopPlayout();

  if (res != -1) {
    available = true;
  } else {
    // It may be possible to play out in stereo
    res = StereoPlayoutIsAvailable(available);
    if (available) {
      // Then set channels to 2 so InitPlayout doesn't fail
      _playChannels = 2;
    }
  }

  return res;
}

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

  // Try to initialize the recording side with mono
  // Assumes that user set num channels after calling this function
  _recChannels = 1;
  int32_t res = InitRecording();

  // Cancel effect of initialization
  StopRecording();

  if (res != -1) {
    available = true;
  } else {
    // It may be possible to record in stereo
    res = StereoRecordingIsAvailable(available);
    if (available) {
      // Then set channels to 2 so InitPlayout doesn't fail
      _recChannels = 2;
    }
  }

  return res;
}

int32_t AudioDeviceLinuxALSA::InitPlayout() {
  MutexLock lock(&mutex_);
  return InitPlayoutLocked();
}

int32_t AudioDeviceLinuxALSA::InitPlayoutLocked() {
  int errVal = 0;

  if (_playing) {
    return -1;
  }

  if (!_outputDeviceIsSpecified) {
    return -1;
  }

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

  // Start by closing any existing wave-output devices
  //
  if (_handlePlayout != nullptr) {
    LATE(snd_pcm_close)(_handlePlayout);
    _handlePlayout = nullptr;
    _playIsInitialized = false;
    if (errVal < 0) {
      RTC_LOG(LS_ERROR) << "Error closing current playout sound device, error: "
                        << LATE(snd_strerror)(errVal);
    }
  }

  // Open PCM device for playout
  char deviceName[kAdmMaxDeviceNameSize] = {0};
  GetDevicesInfo(2, true, _outputDeviceIndex, deviceName,
                 kAdmMaxDeviceNameSize);

  RTC_LOG(LS_VERBOSE) << "InitPlayout open (" << deviceName << ")";

  errVal = LATE(snd_pcm_open)(&_handlePlayout, deviceName,
                              SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);

  if (errVal == -EBUSY)  // Device busy - try some more!
  {
    for (int i = 0; i < 5; i++) {
      Thread::SleepMs(1000);
      errVal = LATE(snd_pcm_open)(&_handlePlayout, deviceName,
                                  SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
      if (errVal == 0) {
        break;
      }
    }
  }
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "unable to open playback device: "
                      << LATE(snd_strerror)(errVal) << " (" << errVal << ")";
    _handlePlayout = nullptr;
    return -1;
  }

  _playoutFramesIn10MS = _playoutFreq / 100;
  if ((errVal = LATE(snd_pcm_set_params)(
           _handlePlayout,
#if defined(WEBRTC_ARCH_BIG_ENDIAN)
           SND_PCM_FORMAT_S16_BE,
#else
           SND_PCM_FORMAT_S16_LE,  // format
#endif
           SND_PCM_ACCESS_RW_INTERLEAVED,  // access
           _playChannels,                  // channels
           _playoutFreq,                   // rate
           1,                              // soft_resample
           ALSA_PLAYOUT_LATENCY  // 40*1000 //latency required overall latency
                                 // in us
           )) < 0) {             /* 0.5sec */
    _playoutFramesIn10MS = 0;
    RTC_LOG(LS_ERROR) << "unable to set playback device: "
                      << LATE(snd_strerror)(errVal) << " (" << errVal << ")";
    ErrorRecovery(errVal, _handlePlayout);
    errVal = LATE(snd_pcm_close)(_handlePlayout);
    _handlePlayout = nullptr;
    return -1;
  }

  errVal = LATE(snd_pcm_get_params)(_handlePlayout, &_playoutBufferSizeInFrame,
                                    &_playoutPeriodSizeInFrame);
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "snd_pcm_get_params: " << LATE(snd_strerror)(errVal)
                      << " (" << errVal << ")";
    _playoutBufferSizeInFrame = 0;
    _playoutPeriodSizeInFrame = 0;
  } else {
    RTC_LOG(LS_VERBOSE) << "playout snd_pcm_get_params buffer_size:"
                        << _playoutBufferSizeInFrame
                        << " period_size :" << _playoutPeriodSizeInFrame;
  }

  if (_ptrAudioBuffer) {
    // Update webrtc audio buffer with the selected parameters
    _ptrAudioBuffer->SetPlayoutSampleRate(_playoutFreq);
    _ptrAudioBuffer->SetPlayoutChannels(_playChannels);
  }

  // Set play buffer size
  _playoutBufferSizeIn10MS =
      LATE(snd_pcm_frames_to_bytes)(_handlePlayout, _playoutFramesIn10MS);

  // Init varaibles used for play

  if (_handlePlayout != nullptr) {
    _playIsInitialized = true;
    return 0;
  } else {
    return -1;
  }
}

int32_t AudioDeviceLinuxALSA::InitRecording() {
  MutexLock lock(&mutex_);
  return InitRecordingLocked();
}

int32_t AudioDeviceLinuxALSA::InitRecordingLocked() {
  int errVal = 0;

  if (_recording) {
    return -1;
  }

  if (!_inputDeviceIsSpecified) {
    return -1;
  }

  if (_recIsInitialized) {
    return 0;
  }

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

  // Start by closing any existing pcm-input devices
  //
  if (_handleRecord != nullptr) {
    errVal = LATE(snd_pcm_close)(_handleRecord);
    _handleRecord = nullptr;
    _recIsInitialized = false;
    if (errVal < 0) {
      RTC_LOG(LS_ERROR)
          << "Error closing current recording sound device, error: "
          << LATE(snd_strerror)(errVal);
    }
  }

  // Open PCM device for recording
  // The corresponding settings for playout are made after the record settings
  char deviceName[kAdmMaxDeviceNameSize] = {0};
  GetDevicesInfo(2, false, _inputDeviceIndex, deviceName,
                 kAdmMaxDeviceNameSize);

  RTC_LOG(LS_VERBOSE) << "InitRecording open (" << deviceName << ")";
  errVal = LATE(snd_pcm_open)(&_handleRecord, deviceName,
                              SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);

  // Available modes: 0 = blocking, SND_PCM_NONBLOCK, SND_PCM_ASYNC
  if (errVal == -EBUSY)  // Device busy - try some more!
  {
    for (int i = 0; i < 5; i++) {
      Thread::SleepMs(1000);
      errVal = LATE(snd_pcm_open)(&_handleRecord, deviceName,
                                  SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
      if (errVal == 0) {
        break;
      }
    }
  }
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "unable to open record device: "
                      << LATE(snd_strerror)(errVal);
    _handleRecord = nullptr;
    return -1;
  }

  _recordingFramesIn10MS = _recordingFreq / 100;
  if ((errVal =
           LATE(snd_pcm_set_params)(_handleRecord,
#if defined(WEBRTC_ARCH_BIG_ENDIAN)
                                    SND_PCM_FORMAT_S16_BE,  // format
#else
                                    SND_PCM_FORMAT_S16_LE,  // format
#endif
                                    SND_PCM_ACCESS_RW_INTERLEAVED,  // access
                                    _recChannels,                   // channels
                                    _recordingFreq,                 // rate
                                    1,                    // soft_resample
                                    ALSA_CAPTURE_LATENCY  // latency in us
                                    )) < 0) {
    // Fall back to another mode then.
    if (_recChannels == 1)
      _recChannels = 2;
    else
      _recChannels = 1;

    if ((errVal =
             LATE(snd_pcm_set_params)(_handleRecord,
#if defined(WEBRTC_ARCH_BIG_ENDIAN)
                                      SND_PCM_FORMAT_S16_BE,  // format
#else
                                      SND_PCM_FORMAT_S16_LE,  // format
#endif
                                      SND_PCM_ACCESS_RW_INTERLEAVED,  // access
                                      _recChannels,         // channels
                                      _recordingFreq,       // rate
                                      1,                    // soft_resample
                                      ALSA_CAPTURE_LATENCY  // latency in us
                                      )) < 0) {
      _recordingFramesIn10MS = 0;
      RTC_LOG(LS_ERROR) << "unable to set record settings: "
                        << LATE(snd_strerror)(errVal) << " (" << errVal << ")";
      ErrorRecovery(errVal, _handleRecord);
      errVal = LATE(snd_pcm_close)(_handleRecord);
      _handleRecord = nullptr;
      return -1;
    }
  }

  errVal = LATE(snd_pcm_get_params)(_handleRecord, &_recordingBuffersizeInFrame,
                                    &_recordingPeriodSizeInFrame);
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "snd_pcm_get_params " << LATE(snd_strerror)(errVal)
                      << " (" << errVal << ")";
    _recordingBuffersizeInFrame = 0;
    _recordingPeriodSizeInFrame = 0;
  } else {
    RTC_LOG(LS_VERBOSE) << "capture snd_pcm_get_params, buffer_size:"
                        << _recordingBuffersizeInFrame
                        << ", period_size:" << _recordingPeriodSizeInFrame;
  }

  if (_ptrAudioBuffer) {
    // Update webrtc audio buffer with the selected parameters
    _ptrAudioBuffer->SetRecordingSampleRate(_recordingFreq);
    _ptrAudioBuffer->SetRecordingChannels(_recChannels);
  }

  // Set rec buffer size and create buffer
  _recordingBufferSizeIn10MS =
      LATE(snd_pcm_frames_to_bytes)(_handleRecord, _recordingFramesIn10MS);

  if (_handleRecord != nullptr) {
    // Mark recording side as initialized
    _recIsInitialized = true;
    return 0;
  } else {
    return -1;
  }
}

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

  if (_recording) {
    return 0;
  }

  _recording = true;

  int errVal = 0;
  _recordingFramesLeft = _recordingFramesIn10MS;

  // Make sure we only create the buffer once.
  if (!_recordingBuffer)
    _recordingBuffer = new int8_t[_recordingBufferSizeIn10MS];
  if (!_recordingBuffer) {
    RTC_LOG(LS_ERROR) << "failed to alloc recording buffer";
    _recording = false;
    return -1;
  }
  // RECORDING
  _ptrThreadRec = PlatformThread::SpawnJoinable(
      [this] {
        while (RecThreadProcess()) {
        }
      },
      "webrtc_audio_module_capture_thread",
      ThreadAttributes().SetPriority(ThreadPriority::kRealtime));

  errVal = LATE(snd_pcm_prepare)(_handleRecord);
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "capture snd_pcm_prepare failed ("
                      << LATE(snd_strerror)(errVal) << ")\n";
    // just log error
    // if snd_pcm_open fails will return -1
  }

  errVal = LATE(snd_pcm_start)(_handleRecord);
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "capture snd_pcm_start err: "
                      << LATE(snd_strerror)(errVal);
    errVal = LATE(snd_pcm_start)(_handleRecord);
    if (errVal < 0) {
      RTC_LOG(LS_ERROR) << "capture snd_pcm_start 2nd try err: "
                        << LATE(snd_strerror)(errVal);
      StopRecording();
      return -1;
    }
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::StopRecording() {
  MutexLock lock(&mutex_);
  return StopRecordingLocked();
}

int32_t AudioDeviceLinuxALSA::StopRecordingLocked() {
  if (!_recIsInitialized) {
    return 0;
  }

  if (_handleRecord == nullptr) {
    return -1;
  }

  // Make sure we don't start recording (it's asynchronous).
  _recIsInitialized = false;
  _recording = false;

  _ptrThreadRec.Finalize();

  _recordingFramesLeft = 0;
  if (_recordingBuffer) {
    delete[] _recordingBuffer;
    _recordingBuffer = nullptr;
  }

  // Stop and close pcm recording device.
  int errVal = LATE(snd_pcm_drop)(_handleRecord);
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "Error stop recording: " << LATE(snd_strerror)(errVal);
    return -1;
  }

  errVal = LATE(snd_pcm_close)(_handleRecord);
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "Error closing record sound device, error: "
                      << LATE(snd_strerror)(errVal);
    return -1;
  }

  // Check if we have muted and unmute if so.
  bool muteEnabled = false;
  MicrophoneMute(muteEnabled);
  if (muteEnabled) {
    SetMicrophoneMute(false);
  }

  // set the pcm input handle to NULL
  _handleRecord = nullptr;
  return 0;
}

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

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

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

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

  if (_playing) {
    return 0;
  }

  _playing = true;

  _playoutFramesLeft = 0;
  if (!_playoutBuffer)
    _playoutBuffer = new int8_t[_playoutBufferSizeIn10MS];
  if (!_playoutBuffer) {
    RTC_LOG(LS_ERROR) << "failed to alloc playout buf";
    _playing = false;
    return -1;
  }

  // PLAYOUT
  _ptrThreadPlay = PlatformThread::SpawnJoinable(
      [this] {
        while (PlayThreadProcess()) {
        }
      },
      "webrtc_audio_module_play_thread",
      ThreadAttributes().SetPriority(ThreadPriority::kRealtime));

  int errVal = LATE(snd_pcm_prepare)(_handlePlayout);
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "playout snd_pcm_prepare failed ("
                      << LATE(snd_strerror)(errVal) << ")\n";
    // just log error
    // if snd_pcm_open fails will return -1
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::StopPlayout() {
  MutexLock lock(&mutex_);
  return StopPlayoutLocked();
}

int32_t AudioDeviceLinuxALSA::StopPlayoutLocked() {
  if (!_playIsInitialized) {
    return 0;
  }

  if (_handlePlayout == nullptr) {
    return -1;
  }

  _playing = false;

  // stop playout thread first
  _ptrThreadPlay.Finalize();

  _playoutFramesLeft = 0;
  delete[] _playoutBuffer;
  _playoutBuffer = nullptr;

  // stop and close pcm playout device
  int errVal = LATE(snd_pcm_drop)(_handlePlayout);
  if (errVal < 0) {
    RTC_LOG(LS_ERROR) << "Error stop playing: " << LATE(snd_strerror)(errVal);
  }

  errVal = LATE(snd_pcm_close)(_handlePlayout);
  if (errVal < 0)
    RTC_LOG(LS_ERROR) << "Error closing playout sound device, error: "
                      << LATE(snd_strerror)(errVal);

  // set the pcm input handle to NULL
  _playIsInitialized = false;
  _handlePlayout = nullptr;
  RTC_LOG(LS_VERBOSE) << "handle_playout is now set to NULL";

  return 0;
}

int32_t AudioDeviceLinuxALSA::PlayoutDelay(uint16_t& delayMS) const {
  delayMS = (uint16_t)_playoutDelay * 1000 / _playoutFreq;
  return 0;
}

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

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

int32_t AudioDeviceLinuxALSA::GetDevicesInfo(const int32_t function,
                                             const bool playback,
                                             const int32_t enumDeviceNo,
                                             char* enumDeviceName,
                                             const int32_t ednLen) const {
  // Device enumeration based on libjingle implementation
  // by Tristan Schmelcher at Google Inc.

  const char* type = playback ? "Output" : "Input";
  // dmix and dsnoop are only for playback and capture, respectively, but ALSA
  // stupidly includes them in both lists.
  const char* ignorePrefix = playback ? "dsnoop:" : "dmix:";
  // (ALSA lists many more "devices" of questionable interest, but we show them
  // just in case the weird devices may actually be desirable for some
  // users/systems.)

  int err;
  int enumCount(0);
  bool keepSearching(true);

  // From Chromium issue 95797
  // Loop through the sound cards to get Alsa device hints.
  // Don't use snd_device_name_hint(-1,..) since there is a access violation
  // inside this ALSA API with libasound.so.2.0.0.
  int card = -1;
  while (!(LATE(snd_card_next)(&card)) && (card >= 0) && keepSearching) {
    void** hints;
    err = LATE(snd_device_name_hint)(card, "pcm", &hints);
    if (err != 0) {
      RTC_LOG(LS_ERROR) << "GetDevicesInfo - device name hint error: "
                        << LATE(snd_strerror)(err);
      return -1;
    }

    enumCount++;  // default is 0
    if ((function == FUNC_GET_DEVICE_NAME ||
         function == FUNC_GET_DEVICE_NAME_FOR_AN_ENUM) &&
        enumDeviceNo == 0) {
      strcpy(enumDeviceName, "default");

      err = LATE(snd_device_name_free_hint)(hints);
      if (err != 0) {
        RTC_LOG(LS_ERROR) << "GetDevicesInfo - device name free hint error: "
                          << LATE(snd_strerror)(err);
      }

      return 0;
    }

    for (void** list = hints; *list != nullptr; ++list) {
      char* actualType = LATE(snd_device_name_get_hint)(*list, "IOID");
      if (actualType) {  // NULL means it's both.
        bool wrongType = (strcmp(actualType, type) != 0);
        free(actualType);
        if (wrongType) {
          // Wrong type of device (i.e., input vs. output).
          continue;
        }
      }

      char* name = LATE(snd_device_name_get_hint)(*list, "NAME");
      if (!name) {
        RTC_LOG(LS_ERROR) << "Device has no name";
        // Skip it.
        continue;
      }

      // Now check if we actually want to show this device.
      if (strcmp(name, "default") != 0 && strcmp(name, "null") != 0 &&
          strcmp(name, "pulse") != 0 &&
          strncmp(name, ignorePrefix, strlen(ignorePrefix)) != 0) {
        // Yes, we do.
        char* desc = LATE(snd_device_name_get_hint)(*list, "DESC");
        if (!desc) {
          // Virtual devices don't necessarily have descriptions.
          // Use their names instead.
          desc = name;
        }

        if (FUNC_GET_NUM_OF_DEVICE == function) {
          RTC_LOG(LS_VERBOSE) << "Enum device " << enumCount << " - " << name;
        }
        if ((FUNC_GET_DEVICE_NAME == function) && (enumDeviceNo == enumCount)) {
          // We have found the enum device, copy the name to buffer.
          strncpy(enumDeviceName, desc, ednLen);
          enumDeviceName[ednLen - 1] = '\0';
          keepSearching = false;
          // Replace '\n' with '-'.
          char* pret = strchr(enumDeviceName, '\n' /*0xa*/);  // LF
          if (pret)
            *pret = '-';
        }
        if ((FUNC_GET_DEVICE_NAME_FOR_AN_ENUM == function) &&
            (enumDeviceNo == enumCount)) {
          // We have found the enum device, copy the name to buffer.
          strncpy(enumDeviceName, name, ednLen);
          enumDeviceName[ednLen - 1] = '\0';
          keepSearching = false;
        }

        if (keepSearching)
          ++enumCount;

        if (desc != name)
          free(desc);
      }

      free(name);

      if (!keepSearching)
        break;
    }

    err = LATE(snd_device_name_free_hint)(hints);
    if (err != 0) {
      RTC_LOG(LS_ERROR) << "GetDevicesInfo - device name free hint error: "
                        << LATE(snd_strerror)(err);
      // Continue and return true anyway, since we did get the whole list.
    }
  }

  if (FUNC_GET_NUM_OF_DEVICE == function) {
    if (enumCount == 1)  // only default?
      enumCount = 0;
    return enumCount;  // Normal return point for function 0
  }

  if (keepSearching) {
    // If we get here for function 1 and 2, we didn't find the specified
    // enum device.
    RTC_LOG(LS_ERROR)
        << "GetDevicesInfo - Could not find device name or numbers";
    return -1;
  }

  return 0;
}

int32_t AudioDeviceLinuxALSA::InputSanityCheckAfterUnlockedPeriod() const {
  if (_handleRecord == nullptr) {
    RTC_LOG(LS_ERROR) << "input state has been modified during unlocked period";
    return -1;
  }
  return 0;
}

int32_t AudioDeviceLinuxALSA::OutputSanityCheckAfterUnlockedPeriod() const {
  if (_handlePlayout == nullptr) {
    RTC_LOG(LS_ERROR)
        << "output state has been modified during unlocked period";
    return -1;
  }
  return 0;
}

int32_t AudioDeviceLinuxALSA::ErrorRecovery(int32_t error,
                                            snd_pcm_t* deviceHandle) {
  int st = LATE(snd_pcm_state)(deviceHandle);
  RTC_LOG(LS_VERBOSE) << "Trying to recover from "
                      << ((LATE(snd_pcm_stream)(deviceHandle) ==
                           SND_PCM_STREAM_CAPTURE)
                              ? "capture"
                              : "playout")
                      << " error: " << LATE(snd_strerror)(error) << " ("
                      << error << ") (state " << st << ")";

  // It is recommended to use snd_pcm_recover for all errors. If that function
  // cannot handle the error, the input error code will be returned, otherwise
  // 0 is returned. From snd_pcm_recover API doc: "This functions handles
  // -EINTR (4) (interrupted system call), -EPIPE (32) (playout overrun or
  // capture underrun) and -ESTRPIPE (86) (stream is suspended) error codes
  // trying to prepare given stream for next I/O."

  /** Open */
  //    SND_PCM_STATE_OPEN = 0,
  /** Setup installed */
  //    SND_PCM_STATE_SETUP,
  /** Ready to start */
  //    SND_PCM_STATE_PREPARED,
  /** Running */
  //    SND_PCM_STATE_RUNNING,
  /** Stopped: underrun (playback) or overrun (capture) detected */
  //    SND_PCM_STATE_XRUN,= 4
  /** Draining: running (playback) or stopped (capture) */
  //    SND_PCM_STATE_DRAINING,
  /** Paused */
  //    SND_PCM_STATE_PAUSED,
  /** Hardware is suspended */
  //    SND_PCM_STATE_SUSPENDED,
  //  ** Hardware is disconnected */
  //    SND_PCM_STATE_DISCONNECTED,
  //    SND_PCM_STATE_LAST = SND_PCM_STATE_DISCONNECTED

  // snd_pcm_recover isn't available in older alsa, e.g. on the FC4 machine
  // in Sthlm lab.

  int res = LATE(snd_pcm_recover)(deviceHandle, error, 1);
  if (0 == res) {
    RTC_LOG(LS_VERBOSE) << "Recovery - snd_pcm_recover OK";

    if ((error == -EPIPE || error == -ESTRPIPE) &&  // Buf underrun/overrun.
        _recording &&
        LATE(snd_pcm_stream)(deviceHandle) == SND_PCM_STREAM_CAPTURE) {
      // For capture streams we also have to repeat the explicit start()
      // to get data flowing again.
      int err = LATE(snd_pcm_start)(deviceHandle);
      if (err != 0) {
        RTC_LOG(LS_ERROR) << "Recovery - snd_pcm_start error: " << err;
        return -1;
      }
    }

    if ((error == -EPIPE || error == -ESTRPIPE) &&  // Buf underrun/overrun.
        _playing &&
        LATE(snd_pcm_stream)(deviceHandle) == SND_PCM_STREAM_PLAYBACK) {
      // For capture streams we also have to repeat the explicit start() to get
      // data flowing again.
      int err = LATE(snd_pcm_start)(deviceHandle);
      if (err != 0) {
        RTC_LOG(LS_ERROR) << "Recovery - snd_pcm_start error: "
                          << LATE(snd_strerror)(err);
        return -1;
      }
    }

    return -EPIPE == error ? 1 : 0;
  } else {
    RTC_LOG(LS_ERROR) << "Unrecoverable alsa stream error: " << res;
  }

  return res;
}

// ============================================================================
//                                  Thread Methods
// ============================================================================

bool AudioDeviceLinuxALSA::PlayThreadProcess() {
  if (!_playing)
    return false;

  int err;
  snd_pcm_sframes_t frames;
  snd_pcm_sframes_t avail_frames;

  Lock();
  // return a positive number of frames ready otherwise a negative error code
  avail_frames = LATE(snd_pcm_avail_update)(_handlePlayout);
  if (avail_frames < 0) {
    RTC_LOG(LS_ERROR) << "playout snd_pcm_avail_update error: "
                      << LATE(snd_strerror)(avail_frames);
    ErrorRecovery(avail_frames, _handlePlayout);
    UnLock();
    return true;
  } else if (avail_frames == 0) {
    UnLock();

    // maximum tixe in milliseconds to wait, a negative value means infinity
    err = LATE(snd_pcm_wait)(_handlePlayout, 2);
    if (err == 0) {  // timeout occured
      RTC_LOG(LS_VERBOSE) << "playout snd_pcm_wait timeout";
    }

    return true;
  }

  if (_playoutFramesLeft <= 0) {
    UnLock();
    _ptrAudioBuffer->RequestPlayoutData(_playoutFramesIn10MS);
    Lock();

    _playoutFramesLeft = _ptrAudioBuffer->GetPlayoutData(_playoutBuffer);
    RTC_DCHECK_EQ(_playoutFramesLeft, _playoutFramesIn10MS);
  }

  if (static_cast<uint32_t>(avail_frames) > _playoutFramesLeft)
    avail_frames = _playoutFramesLeft;

  int size = LATE(snd_pcm_frames_to_bytes)(_handlePlayout, _playoutFramesLeft);
  frames = LATE(snd_pcm_writei)(
      _handlePlayout, &_playoutBuffer[_playoutBufferSizeIn10MS - size],
      avail_frames);

  if (frames < 0) {
    RTC_LOG(LS_VERBOSE) << "playout snd_pcm_writei error: "
                        << LATE(snd_strerror)(frames);
    _playoutFramesLeft = 0;
    ErrorRecovery(frames, _handlePlayout);
    UnLock();
    return true;
  } else {
    RTC_DCHECK_EQ(frames, avail_frames);
    _playoutFramesLeft -= frames;
  }

  UnLock();
  return true;
}

bool AudioDeviceLinuxALSA::RecThreadProcess() {
  if (!_recording)
    return false;

  int err;
  snd_pcm_sframes_t frames;
  snd_pcm_sframes_t avail_frames;
  std::vector<int8_t> buffer(_recordingBufferSizeIn10MS);

  Lock();

  // return a positive number of frames ready otherwise a negative error code
  avail_frames = LATE(snd_pcm_avail_update)(_handleRecord);
  if (avail_frames < 0) {
    RTC_LOG(LS_ERROR) << "capture snd_pcm_avail_update error: "
                      << LATE(snd_strerror)(avail_frames);
    ErrorRecovery(avail_frames, _handleRecord);
    UnLock();
    return true;
  } else if (avail_frames == 0) {  // no frame is available now
    UnLock();

    // maximum time in milliseconds to wait, a negative value means infinity
    err = LATE(snd_pcm_wait)(_handleRecord, ALSA_CAPTURE_WAIT_TIMEOUT);
    if (err == 0)  // timeout occured
      RTC_LOG(LS_VERBOSE) << "capture snd_pcm_wait timeout";

    return true;
  }

  if (static_cast<uint32_t>(avail_frames) > _recordingFramesLeft)
    avail_frames = _recordingFramesLeft;

  frames = LATE(snd_pcm_readi)(_handleRecord, buffer.data(),
                               avail_frames);  // frames to be written
  if (frames < 0) {
    RTC_LOG(LS_ERROR) << "capture snd_pcm_readi error: "
                      << LATE(snd_strerror)(frames);
    ErrorRecovery(frames, _handleRecord);
    UnLock();
    return true;
  } else if (frames > 0) {
    RTC_DCHECK_EQ(frames, avail_frames);

    int left_size =
        LATE(snd_pcm_frames_to_bytes)(_handleRecord, _recordingFramesLeft);
    int size = LATE(snd_pcm_frames_to_bytes)(_handleRecord, frames);

    memcpy(&_recordingBuffer[_recordingBufferSizeIn10MS - left_size],
           buffer.data(), size);
    _recordingFramesLeft -= frames;

    if (!_recordingFramesLeft) {  // buf is full
      _recordingFramesLeft = _recordingFramesIn10MS;

      // store the recorded buffer (no action will be taken if the
      // #recorded samples is not a full buffer)
      _ptrAudioBuffer->SetRecordedBuffer(_recordingBuffer,
                                         _recordingFramesIn10MS);

      // calculate delay
      _playoutDelay = 0;
      _recordingDelay = 0;
      if (_handlePlayout) {
        err = LATE(snd_pcm_delay)(_handlePlayout,
                                  &_playoutDelay);  // returned delay in frames
        if (err < 0) {
          // TODO(xians): Shall we call ErrorRecovery() here?
          _playoutDelay = 0;
          RTC_LOG(LS_ERROR)
              << "playout snd_pcm_delay: " << LATE(snd_strerror)(err);
        }
      }

      err = LATE(snd_pcm_delay)(_handleRecord,
                                &_recordingDelay);  // returned delay in frames
      if (err < 0) {
        // TODO(xians): Shall we call ErrorRecovery() here?
        _recordingDelay = 0;
        RTC_LOG(LS_ERROR) << "capture snd_pcm_delay: "
                          << LATE(snd_strerror)(err);
      }

      // TODO(xians): Shall we add 10ms buffer delay to the record delay?
      _ptrAudioBuffer->SetVQEData(_playoutDelay * 1000 / _playoutFreq,
                                  _recordingDelay * 1000 / _recordingFreq);

      _ptrAudioBuffer->SetTypingStatus(KeyPressed());

      // Deliver recorded samples at specified sample rate, mic level etc.
      // to the observer using callback.
      UnLock();
      _ptrAudioBuffer->DeliverRecordedData();
      Lock();
    }
  }

  UnLock();
  return true;
}

bool AudioDeviceLinuxALSA::KeyPressed() const {
#if defined(WEBRTC_USE_X11)
  char szKey[32];
  unsigned int i = 0;
  char state = 0;

  if (!_XDisplay)
    return false;

  // Check key map status
  XQueryKeymap(_XDisplay, szKey);

  // A bit change in keymap means a key is pressed
  for (i = 0; i < sizeof(szKey); i++)
    state |= (szKey[i] ^ _oldKeyState[i]) & szKey[i];

  // Save old state
  memcpy((char*)_oldKeyState, (char*)szKey, sizeof(_oldKeyState));
  return (state != 0);
#else
  return false;
#endif
}
}  // namespace webrtc
