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

#include "modules/audio_device/audio_device_config.h"
#include "modules/audio_device/linux/audio_device_alsa_linux.h"
#include "rtc_base/logging.h"

#include "system_wrappers/include/event_wrapper.h"
#include "system_wrappers/include/sleep.h"
webrtc::adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable;

// 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, &AlsaSymbolTable, 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 (!AlsaSymbolTable.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(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(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"));

  _ptrThreadRec->Start();
  _ptrThreadRec->SetPriority(rtc::kRealtimePriority);

  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"));
  _ptrThreadPlay->Start();
  _ptrThreadPlay->SetPriority(rtc::kRealtimePriority);

  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
// ============================================================================

bool AudioDeviceLinuxALSA::PlayThreadFunc(void* pThis) {
  return (static_cast<AudioDeviceLinuxALSA*>(pThis)->PlayThreadProcess());
}

bool AudioDeviceLinuxALSA::RecThreadFunc(void* pThis) {
  return (static_cast<AudioDeviceLinuxALSA*>(pThis)->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, 0);

      _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(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
