/*
 *  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 "webrtc/modules/audio_device/audio_device_config.h"
#include "webrtc/modules/audio_device/linux/audio_device_alsa_linux.h"
#include "webrtc/rtc_base/logging.h"

#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/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),
    _playBufType(AudioDeviceModule::kFixedBufferSize),
    _initialized(false),
    _recording(false),
    _playing(false),
    _recIsInitialized(false),
    _playIsInitialized(false),
    _AGC(false),
    _recordingDelay(0),
    _playoutDelay(0),
    _playWarning(0),
    _playError(0),
    _recWarning(0),
    _recError(0),
    _playBufDelay(80),
    _playBufDelayFixed(80)
{
    memset(_oldKeyState, 0, sizeof(_oldKeyState));
    LOG(LS_INFO) << __FUNCTION__ << " created";
}

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

AudioDeviceLinuxALSA::~AudioDeviceLinuxALSA()
{
    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
    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) {
      LOG(LS_WARNING)
          << "failed to open X display, typing detection will not work";
    }
#endif
    _playWarning = 0;
    _playError = 0;
    _recWarning = 0;
    _recError = 0;

    _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::SetWaveOutVolume(uint16_t volumeLeft,
                                               uint16_t volumeRight)
{

    LOG(LS_WARNING) << "API call not supported on this platform";
    return -1;
}

int32_t AudioDeviceLinuxALSA::WaveOutVolume(
    uint16_t& /*volumeLeft*/,
    uint16_t& /*volumeRight*/) const
{

    LOG(LS_WARNING) << "API call not supported on this platform";
    return -1;
}

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::SpeakerVolumeStepSize(
    uint16_t& stepSize) const
{

    uint16_t delta(0);

    if (_mixerManager.SpeakerVolumeStepSize(delta) == -1)
    {
        return -1;
    }

    stepSize = delta;

    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::MicrophoneBoostIsAvailable(bool& available)
{

    bool isAvailable(false);
    bool wasInitialized = _mixerManager.MicrophoneIsInitialized();

    // Enumerate all avaliable microphone and 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 boost control
        // already at this stage.
        available = false;
        return 0;
    }

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

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

    return 0;
}

int32_t AudioDeviceLinuxALSA::SetMicrophoneBoost(bool enable)
{

    return (_mixerManager.SetMicrophoneBoost(enable));
}

int32_t AudioDeviceLinuxALSA::MicrophoneBoost(bool& enabled) const
{

    bool onOff(0);

    if (_mixerManager.MicrophoneBoost(onOff) == -1)
    {
        return -1;
    }

    enabled = onOff;

    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::SetAGC(bool enable)
{

    _AGC = enable;

    return 0;
}

bool AudioDeviceLinuxALSA::AGC() const
{

    return _AGC;
}

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

int32_t AudioDeviceLinuxALSA::MicrophoneVolumeStepSize(
    uint16_t& stepSize) const
{

    uint16_t delta(0);

    if (_mixerManager.MicrophoneVolumeStepSize(delta) == -1)
    {
        return -1;
    }

    stepSize = delta;

    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);
    LOG(LS_VERBOSE) << "number of available audio output devices is "
                    << nDevices;

    if (index > (nDevices-1))
    {
        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*/)
{
    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);
    LOG(LS_VERBOSE) << "number of availiable audio input devices is "
                    << nDevices;

    if (index > (nDevices-1))
    {
        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*/)
{
    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)
    {
        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)
        {
            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);

    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)
    {
        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;
        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)
    {
        LOG(LS_ERROR) << "snd_pcm_get_params: " << LATE(snd_strerror)(errVal)
                      << " (" << errVal << ")";
        _playoutBufferSizeInFrame = 0;
        _playoutPeriodSizeInFrame = 0;
    }
    else {
        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
    _playWarning = 0;
    _playError = 0;

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

    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)
    {
        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;
             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)
    {
        LOG(LS_ERROR) << "snd_pcm_get_params " << LATE(snd_strerror)(errVal)
                      << " (" << errVal << ")";
        _recordingBuffersizeInFrame = 0;
        _recordingPeriodSizeInFrame = 0;
    }
    else {
        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)
    {
        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)
    {
        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)
    {
        LOG(LS_ERROR) << "capture snd_pcm_start err: "
                      << LATE(snd_strerror)(errVal);
        errVal = LATE(snd_pcm_start)(_handleRecord);
        if (errVal < 0)
        {
            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)
    {
        LOG(LS_ERROR) << "Error stop recording: " << LATE(snd_strerror)(errVal);
        return -1;
    }

    errVal = LATE(snd_pcm_close)(_handleRecord);
    if (errVal < 0)
    {
        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)
    {
      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)
    {
        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)
    {
        LOG(LS_ERROR) << "Error stop playing: " << LATE(snd_strerror)(errVal);
    }

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

     // set the pcm input handle to NULL
     _playIsInitialized = false;
     _handlePlayout = NULL;
     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;
}

int32_t AudioDeviceLinuxALSA::RecordingDelay(uint16_t& delayMS) const
{
    // Adding 10ms adjusted value to the record delay due to 10ms buffering.
    delayMS = (uint16_t)(10 + _recordingDelay * 1000 / _recordingFreq);
    return 0;
}

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

int32_t AudioDeviceLinuxALSA::SetPlayoutBuffer(
    const AudioDeviceModule::BufferType type,
    uint16_t sizeMS)
{
    _playBufType = type;
    if (type == AudioDeviceModule::kFixedBufferSize)
    {
        _playBufDelayFixed = sizeMS;
    }
    return 0;
}

int32_t AudioDeviceLinuxALSA::PlayoutBuffer(
    AudioDeviceModule::BufferType& type,
    uint16_t& sizeMS) const
{
    type = _playBufType;
    if (type == AudioDeviceModule::kFixedBufferSize)
    {
        sizeMS = _playBufDelayFixed;
    }
    else
    {
        sizeMS = _playBufDelay;
    }

    return 0;
}

int32_t AudioDeviceLinuxALSA::CPULoad(uint16_t& load) const
{

    LOG(LS_WARNING) << "API call not supported on this platform";
    return -1;
}

bool AudioDeviceLinuxALSA::PlayoutWarning() const
{
    rtc::CritScope lock(&_critSect);
    return (_playWarning > 0);
}

bool AudioDeviceLinuxALSA::PlayoutError() const
{
    rtc::CritScope lock(&_critSect);
    return (_playError > 0);
}

bool AudioDeviceLinuxALSA::RecordingWarning() const
{
    rtc::CritScope lock(&_critSect);
    return (_recWarning > 0);
}

bool AudioDeviceLinuxALSA::RecordingError() const
{
    rtc::CritScope lock(&_critSect);
    return (_recError > 0);
}

void AudioDeviceLinuxALSA::ClearPlayoutWarning()
{
    rtc::CritScope lock(&_critSect);
    _playWarning = 0;
}

void AudioDeviceLinuxALSA::ClearPlayoutError()
{
    rtc::CritScope lock(&_critSect);
    _playError = 0;
}

void AudioDeviceLinuxALSA::ClearRecordingWarning()
{
    rtc::CritScope lock(&_critSect);
    _recWarning = 0;
}

void AudioDeviceLinuxALSA::ClearRecordingError()
{
    rtc::CritScope lock(&_critSect);
    _recError = 0;
}

// ============================================================================
//                                 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)
        {
            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)
            {
                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)
            {
                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)
                {
                    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)
        {
            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.
        LOG(LS_ERROR)
            << "GetDevicesInfo - Could not find device name or numbers";
        return -1;
    }

    return 0;
}

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

int32_t AudioDeviceLinuxALSA::OutputSanityCheckAfterUnlockedPeriod() const
{
    if (_handlePlayout == NULL)
    {
        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);
    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)
    {
        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)
            {
                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)
            {
              LOG(LS_ERROR) << "Recovery - snd_pcm_start error: "
                            << LATE(snd_strerror)(err);
              return -1;
            }
        }

        return -EPIPE == error ? 1 : 0;
    }
    else {
        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)
    {
        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
            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)
    {
        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)
    {
        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
            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)
    {
        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);

            uint32_t currentMicLevel = 0;
            uint32_t newMicLevel = 0;

            if (AGC())
            {
                // store current mic level in the audio buffer if AGC is enabled
                if (MicrophoneVolume(currentMicLevel) == 0)
                {
                    if (currentMicLevel == 0xffffffff)
                        currentMicLevel = 100;
                    // this call does not affect the actual microphone volume
                    _ptrAudioBuffer->SetCurrentMicLevel(currentMicLevel);
                }
            }

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

            if (AGC())
            {
                newMicLevel = _ptrAudioBuffer->NewMicLevel();
                if (newMicLevel != 0)
                {
                    // The VQE will only deliver non-zero microphone levels when a
                    // change is needed. Set this new mic level (received from the
                    // observer as return value in the callback).
                    if (SetMicrophoneVolume(newMicLevel) == -1)
                        LOG(LS_WARNING)
                            << "the required modification of the microphone volume failed";
                }
            }
        }
    }

    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
