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

#include "modules/audio_device/audio_device_config.h"
#include "rtc_base/logging.h"
#include "rtc_base/system/arch.h"
#include "system_wrappers/include/sleep.h"

WebRTCAlsaSymbolTable* GetAlsaSymbolTable() {
  static WebRTCAlsaSymbolTable* alsa_symbol_table = new WebRTCAlsaSymbolTable();
  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(NULL),
      _inputDeviceIndex(0),
      _outputDeviceIndex(0),
      _inputDeviceIsSpecified(false),
      _outputDeviceIsSpecified(false),
      _handleRecord(NULL),
      _handlePlayout(NULL),
      _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(NULL),
      _playoutBuffer(NULL),
      _recordingFramesLeft(0),
      _playoutFramesLeft(0),
      _initialized(false),
      _recording(false),
      _playing(false),
      _recIsInitialized(false),
      _playIsInitialized(false),
      _recordingDelay(0),
      _playoutDelay(0) {
  memset(_oldKeyState, 0, sizeof(_oldKeyState));
  RTC_LOG(LS_INFO) << __FUNCTION__ << " created";
}

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

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

  Terminate();

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

void AudioDeviceLinuxALSA::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
  rtc::CritScope lock(&_critSect);

  _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() {
  rtc::CritScope lock(&_critSect);

  // Load libasound
  if (!GetAlsaSymbolTable()->Load()) {
    // 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(NULL);
  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;
  }

  rtc::CritScope lock(&_critSect);

  _mixerManager.Close();

  // RECORDING
  if (_ptrThreadRec) {
    rtc::PlatformThread* tmpThread = _ptrThreadRec.release();
    _critSect.Leave();

    tmpThread->Stop();
    delete tmpThread;

    _critSect.Enter();
  }

  // PLAYOUT
  if (_ptrThreadPlay) {
    rtc::PlatformThread* tmpThread = _ptrThreadPlay.release();
    _critSect.Leave();

    tmpThread->Stop();
    delete tmpThread;

    _critSect.Enter();
  }
#if defined(WEBRTC_USE_X11)
  if (_XDisplay) {
    XCloseDisplay(_XDisplay);
    _XDisplay = NULL;
  }
#endif
  _initialized = false;
  _outputDeviceIsSpecified = false;
  _inputDeviceIsSpecified = false;

  return 0;
}

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

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

  if (_playing) {
    return -1;
  }

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

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

  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) {
  rtc::CritScope lock(&_critSect);

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

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

  // Stop/uninitialize recording
  StopRecording();

  // Recover previous states
  _recChannels = recChannels;
  if (recIsInitialized) {
    InitRecording();
  }
  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) {
  rtc::CritScope lock(&_critSect);

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

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

  // Stop/uninitialize recording
  StopPlayout();

  // Recover previous states
  _playChannels = playChannels;
  if (playIsInitialized) {
    InitPlayout();
  }
  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));

  return 0;
}

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

  uint32_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 == NULL)) {
    return -1;
  }

  memset(name, 0, kAdmMaxDeviceNameSize);

  if (guid != NULL) {
    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 == NULL)) {
    return -1;
  }

  memset(name, 0, kAdmMaxDeviceNameSize);

  if (guid != NULL) {
    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;
  }

  uint32_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() {
  int errVal = 0;

  rtc::CritScope lock(&_critSect);
  if (_playing) {
    return -1;
  }

  if (!_outputDeviceIsSpecified) {
    return -1;
  }

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

  // Start by closing any existing wave-output devices
  //
  if (_handlePlayout != NULL) {
    LATE(snd_pcm_close)(_handlePlayout);
    _handlePlayout = NULL;
    _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++) {
      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 = NULL;
    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 = NULL;
    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 != NULL) {
    _playIsInitialized = true;
    return 0;
  } else {
    return -1;
  }

  return 0;
}

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

  rtc::CritScope lock(&_critSect);

  if (_recording) {
    return -1;
  }

  if (!_inputDeviceIsSpecified) {
    return -1;
  }

  if (_recIsInitialized) {
    return 0;
  }

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

  // Start by closing any existing pcm-input devices
  //
  if (_handleRecord != NULL) {
    int errVal = LATE(snd_pcm_close)(_handleRecord);
    _handleRecord = NULL;
    _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++) {
      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 = NULL;
    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 = NULL;
      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 != NULL) {
    // Mark recording side as initialized
    _recIsInitialized = true;
    return 0;
  } else {
    return -1;
  }

  return 0;
}

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.reset(new rtc::PlatformThread(
      RecThreadFunc, this, "webrtc_audio_module_capture_thread",
      rtc::kRealtimePriority));

  _ptrThreadRec->Start();

  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() {
  {
    rtc::CritScope lock(&_critSect);

    if (!_recIsInitialized) {
      return 0;
    }

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

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

  if (_ptrThreadRec) {
    _ptrThreadRec->Stop();
    _ptrThreadRec.reset();
  }

  rtc::CritScope lock(&_critSect);
  _recordingFramesLeft = 0;
  if (_recordingBuffer) {
    delete[] _recordingBuffer;
    _recordingBuffer = NULL;
  }

  // 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 = NULL;
  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.reset(new rtc::PlatformThread(
      PlayThreadFunc, this, "webrtc_audio_module_play_thread",
      rtc::kRealtimePriority));
  _ptrThreadPlay->Start();

  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() {
  {
    rtc::CritScope lock(&_critSect);

    if (!_playIsInitialized) {
      return 0;
    }

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

    _playing = false;
  }

  // stop playout thread first
  if (_ptrThreadPlay) {
    _ptrThreadPlay->Stop();
    _ptrThreadPlay.reset();
  }

  rtc::CritScope lock(&_critSect);

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

  // 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 = NULL;
  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 != NULL; ++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 == NULL) {
    RTC_LOG(LS_ERROR) << "input state has been modified during unlocked period";
    return -1;
  }
  return 0;
}

int32_t AudioDeviceLinuxALSA::OutputSanityCheckAfterUnlockedPeriod() const {
  if (_handlePlayout == NULL) {
    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
// ============================================================================

void AudioDeviceLinuxALSA::PlayThreadFunc(void* pThis) {
  AudioDeviceLinuxALSA* device = static_cast<AudioDeviceLinuxALSA*>(pThis);
  while (device->PlayThreadProcess()) {
  }
}

void AudioDeviceLinuxALSA::RecThreadFunc(void* pThis) {
  AudioDeviceLinuxALSA* device = static_cast<AudioDeviceLinuxALSA*>(pThis);
  while (device->RecThreadProcess()) {
  }
}

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);
    assert(_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 {
    assert(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;
  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,
                               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) {
    assert(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,
           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
