/*
 *  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/linux/audio_mixer_manager_pulse_linux.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"

extern webrtc::adm_linux_pulse::PulseAudioSymbolTable PaSymbolTable;

// Accesses Pulse functions through our late-binding symbol table instead of
// directly. This way we don't have to link to libpulse, which means our
// binary will work on systems that don't have it.
#define LATE(sym)                                                             \
  LATESYM_GET(webrtc::adm_linux_pulse::PulseAudioSymbolTable, &PaSymbolTable, \
              sym)

namespace webrtc
{

class AutoPulseLock {
 public:
  explicit AutoPulseLock(pa_threaded_mainloop* pa_mainloop)
      : pa_mainloop_(pa_mainloop) {
    LATE(pa_threaded_mainloop_lock)(pa_mainloop_);
  }

  ~AutoPulseLock() {
    LATE(pa_threaded_mainloop_unlock)(pa_mainloop_);
  }

 private:
  pa_threaded_mainloop* const pa_mainloop_;
};

AudioMixerManagerLinuxPulse::AudioMixerManagerLinuxPulse() :
    _paOutputDeviceIndex(-1),
    _paInputDeviceIndex(-1),
    _paPlayStream(NULL),
    _paRecStream(NULL),
    _paMainloop(NULL),
    _paContext(NULL),
    _paVolume(0),
    _paMute(0),
    _paVolSteps(0),
    _paSpeakerMute(false),
    _paSpeakerVolume(PA_VOLUME_NORM),
    _paChannels(0),
    _paObjectsSet(false)
{
    LOG(LS_INFO) << __FUNCTION__ << " created";
}

AudioMixerManagerLinuxPulse::~AudioMixerManagerLinuxPulse()
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_INFO) << __FUNCTION__ << " destroyed";

    Close();
}

// ===========================================================================
//                                    PUBLIC METHODS
// ===========================================================================

int32_t AudioMixerManagerLinuxPulse::SetPulseAudioObjects(
    pa_threaded_mainloop* mainloop,
    pa_context* context)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << __FUNCTION__;

    if (!mainloop || !context)
    {
        LOG(LS_ERROR) << "could not set PulseAudio objects for mixer";
        return -1;
    }

    _paMainloop = mainloop;
    _paContext = context;
    _paObjectsSet = true;

    LOG(LS_VERBOSE) << "the PulseAudio objects for the mixer has been set";

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::Close()
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << __FUNCTION__;

    CloseSpeaker();
    CloseMicrophone();

    _paMainloop = NULL;
    _paContext = NULL;
    _paObjectsSet = false;

    return 0;

}

int32_t AudioMixerManagerLinuxPulse::CloseSpeaker()
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << __FUNCTION__;

    // Reset the index to -1
    _paOutputDeviceIndex = -1;
    _paPlayStream = NULL;

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::CloseMicrophone()
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << __FUNCTION__;

    // Reset the index to -1
    _paInputDeviceIndex = -1;
    _paRecStream = NULL;

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetPlayStream(pa_stream* playStream)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetPlayStream(playStream)";

    _paPlayStream = playStream;
    return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetRecStream(pa_stream* recStream)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetRecStream(recStream)";

    _paRecStream = recStream;
    return 0;
}

int32_t AudioMixerManagerLinuxPulse::OpenSpeaker(
    uint16_t deviceIndex)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::OpenSpeaker(deviceIndex="
                    << deviceIndex << ")";

    // No point in opening the speaker
    // if PA objects have not been set
    if (!_paObjectsSet)
    {
        LOG(LS_ERROR) << "PulseAudio objects has not been set";
        return -1;
    }

    // Set the index for the PulseAudio
    // output device to control
    _paOutputDeviceIndex = deviceIndex;

    LOG(LS_VERBOSE) << "the output mixer device is now open";

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::OpenMicrophone(
    uint16_t deviceIndex)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE)
        << "AudioMixerManagerLinuxPulse::OpenMicrophone(deviceIndex="
        << deviceIndex << ")";

    // No point in opening the microphone
    // if PA objects have not been set
    if (!_paObjectsSet)
    {
        LOG(LS_ERROR) << "PulseAudio objects have not been set";
        return -1;
    }

    // Set the index for the PulseAudio
    // input device to control
    _paInputDeviceIndex = deviceIndex;

    LOG(LS_VERBOSE) << "the input mixer device is now open";

    return 0;
}

bool AudioMixerManagerLinuxPulse::SpeakerIsInitialized() const
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_INFO) << __FUNCTION__;

    return (_paOutputDeviceIndex != -1);
}

bool AudioMixerManagerLinuxPulse::MicrophoneIsInitialized() const
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_INFO) << __FUNCTION__;

    return (_paInputDeviceIndex != -1);
}

int32_t AudioMixerManagerLinuxPulse::SetSpeakerVolume(
    uint32_t volume)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetSpeakerVolume(volume="
                    << volume << ")";

    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    bool setFailed(false);

    if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream)
        != PA_STREAM_UNCONNECTED))
    {
        // We can only really set the volume if we have a connected stream
        AutoPulseLock auto_lock(_paMainloop);

        // Get the number of channels from the sample specification
        const pa_sample_spec *spec =
            LATE(pa_stream_get_sample_spec)(_paPlayStream);
        if (!spec)
        {
            LOG(LS_ERROR) << "could not get sample specification";
            return -1;
        }

        // Set the same volume for all channels
        pa_cvolume cVolumes;
        LATE(pa_cvolume_set)(&cVolumes, spec->channels, volume);

        pa_operation* paOperation = NULL;
        paOperation = LATE(pa_context_set_sink_input_volume)(
            _paContext,
            LATE(pa_stream_get_index)(_paPlayStream),
            &cVolumes,
            PaSetVolumeCallback, NULL);
        if (!paOperation)
        {
            setFailed = true;
        }

        // Don't need to wait for the completion
        LATE(pa_operation_unref)(paOperation);
    } else
    {
        // We have not created a stream or it's not connected to the sink
        // Save the volume to be set at connection
        _paSpeakerVolume = volume;
    }

    if (setFailed)
    {
        LOG(LS_WARNING) << "could not set speaker volume, error="
                        << LATE(pa_context_errno)(_paContext);

        return -1;
    }

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::SpeakerVolume(uint32_t& volume) const
{
    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream)
        != PA_STREAM_UNCONNECTED))
    {
        // We can only get the volume if we have a connected stream
        if (!GetSinkInputInfo())
          return -1;

        AutoPulseLock auto_lock(_paMainloop);
        volume = static_cast<uint32_t> (_paVolume);
    } else
    {
        AutoPulseLock auto_lock(_paMainloop);
        volume = _paSpeakerVolume;
    }

    LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SpeakerVolume() => vol="
                    << volume;

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::MaxSpeakerVolume(uint32_t& maxVolume) const
{

    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    // PA_VOLUME_NORM corresponds to 100% (0db)
    // but PA allows up to 150 db amplification
    maxVolume = static_cast<uint32_t> (PA_VOLUME_NORM);

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::MinSpeakerVolume(uint32_t& minVolume) const
{

    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    minVolume = static_cast<uint32_t> (PA_VOLUME_MUTED);

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::SpeakerVolumeIsAvailable(bool& available)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    // Always available in Pulse Audio
    available = true;

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::SpeakerMuteIsAvailable(bool& available)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    // Always available in Pulse Audio
    available = true;

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetSpeakerMute(bool enable)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetSpeakerMute(enable="
                    << enable << ")";

    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    bool setFailed(false);

    if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream)
        != PA_STREAM_UNCONNECTED))
    {
        // We can only really mute if we have a connected stream
        AutoPulseLock auto_lock(_paMainloop);

        pa_operation* paOperation = NULL;
        paOperation = LATE(pa_context_set_sink_input_mute)(
            _paContext,
            LATE(pa_stream_get_index)(_paPlayStream),
            (int) enable,
            PaSetVolumeCallback,
            NULL);
        if (!paOperation)
        {
            setFailed = true;
        }

        // Don't need to wait for the completion
        LATE(pa_operation_unref)(paOperation);
    } else
    {
        // We have not created a stream or it's not connected to the sink
        // Save the mute status to be set at connection
        _paSpeakerMute = enable;
    }

    if (setFailed)
    {
        LOG(LS_WARNING) << "could not mute speaker, error="
                        << LATE(pa_context_errno)(_paContext);
        return -1;
    }

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::SpeakerMute(bool& enabled) const
{

    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream)
        != PA_STREAM_UNCONNECTED))
    {
        // We can only get the mute status if we have a connected stream
        if (!GetSinkInputInfo())
          return -1;

        enabled = static_cast<bool> (_paMute);
    } else
    {
        enabled = _paSpeakerMute;
    }
    LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SpeakerMute() => enabled="
                    << enabled;

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::StereoPlayoutIsAvailable(bool& available)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    if (_paOutputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "output device index has not been set";
        return -1;
    }

    uint32_t deviceIndex = (uint32_t) _paOutputDeviceIndex;

    {
        AutoPulseLock auto_lock(_paMainloop);

        // Get the actual stream device index if we have a connected stream
        // The device used by the stream can be changed
        // during the call
        if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream)
            != PA_STREAM_UNCONNECTED))
        {
            deviceIndex = LATE(pa_stream_get_device_index)(_paPlayStream);
        }
    }

    if (!GetSinkInfoByIndex(deviceIndex))
      return -1;

    available = static_cast<bool> (_paChannels == 2);

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable(bool& available)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex;

    AutoPulseLock auto_lock(_paMainloop);

    // Get the actual stream device index if we have a connected stream
    // The device used by the stream can be changed
    // during the call
    if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream)
        != PA_STREAM_UNCONNECTED))
    {
        deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
    }

    pa_operation* paOperation = NULL;

    // Get info for this source
    // We want to know if the actual device can record in stereo
    paOperation = LATE(pa_context_get_source_info_by_index)(
        _paContext, deviceIndex,
        PaSourceInfoCallback,
        (void*) this);

    WaitForOperationCompletion(paOperation);

    available = static_cast<bool> (_paChannels == 2);

    LOG(LS_VERBOSE)
        << "AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable()"
        << " => available=" << available;

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::MicrophoneMuteIsAvailable(
    bool& available)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    // Always available in Pulse Audio
    available = true;

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetMicrophoneMute(bool enable)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetMicrophoneMute(enable="
                    << enable << ")";

    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    bool setFailed(false);
    pa_operation* paOperation = NULL;

    uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex;

    AutoPulseLock auto_lock(_paMainloop);

    // Get the actual stream device index if we have a connected stream
    // The device used by the stream can be changed
    // during the call
    if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream)
        != PA_STREAM_UNCONNECTED))
    {
        deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
    }

    // Set mute switch for the source
    paOperation = LATE(pa_context_set_source_mute_by_index)(
        _paContext, deviceIndex,
        enable,
        PaSetVolumeCallback, NULL);

    if (!paOperation)
    {
        setFailed = true;
    }

    // Don't need to wait for this to complete.
    LATE(pa_operation_unref)(paOperation);

    if (setFailed)
    {
        LOG(LS_WARNING) << "could not mute microphone, error="
                        << LATE(pa_context_errno)(_paContext);
        return -1;
    }

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::MicrophoneMute(bool& enabled) const
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex;

    {
        AutoPulseLock auto_lock(_paMainloop);
        // Get the actual stream device index if we have a connected stream
        // The device used by the stream can be changed
        // during the call
        if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream)
            != PA_STREAM_UNCONNECTED))
        {
            deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
        }
    }

    if (!GetSourceInfoByIndex(deviceIndex))
      return -1;

    enabled = static_cast<bool> (_paMute);

    LOG(LS_VERBOSE)
        << "AudioMixerManagerLinuxPulse::MicrophoneMute() => enabled="
        << enabled;

    return 0;
}

int32_t AudioMixerManagerLinuxPulse::MicrophoneVolumeIsAvailable(
    bool& available)
{
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    // Always available in Pulse Audio
    available = true;

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::SetMicrophoneVolume(uint32_t volume)
{
    LOG(LS_VERBOSE)
        << "AudioMixerManagerLinuxPulse::SetMicrophoneVolume(volume=" << volume
        << ")";

    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    // Unlike output streams, input streams have no concept of a stream
    // volume, only a device volume. So we have to change the volume of the
    // device itself.

    // The device may have a different number of channels than the stream and
    // their mapping may be different, so we don't want to use the channel
    // count from our sample spec. We could use PA_CHANNELS_MAX to cover our
    // bases, and the server allows that even if the device's channel count
    // is lower, but some buggy PA clients don't like that (the pavucontrol
    // on Hardy dies in an assert if the channel count is different). So
    // instead we look up the actual number of channels that the device has.
    AutoPulseLock auto_lock(_paMainloop);
    uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex;

    // Get the actual stream device index if we have a connected stream
    // The device used by the stream can be changed
    // during the call
    if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream)
        != PA_STREAM_UNCONNECTED))
    {
        deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
    }

    bool setFailed(false);
    pa_operation* paOperation = NULL;

    // Get the number of channels for this source
    paOperation
        = LATE(pa_context_get_source_info_by_index)(_paContext, deviceIndex,
                                                    PaSourceInfoCallback,
                                                    (void*) this);

    WaitForOperationCompletion(paOperation);

    uint8_t channels = _paChannels;
    pa_cvolume cVolumes;
    LATE(pa_cvolume_set)(&cVolumes, channels, volume);

    // Set the volume for the source
    paOperation
        = LATE(pa_context_set_source_volume_by_index)(_paContext, deviceIndex,
                                                      &cVolumes,
                                                      PaSetVolumeCallback,
                                                      NULL);

    if (!paOperation)
    {
        setFailed = true;
    }

    // Don't need to wait for this to complete.
    LATE(pa_operation_unref)(paOperation);

    if (setFailed)
    {
        LOG(LS_WARNING) << "could not set microphone volume, error="
                        << LATE(pa_context_errno)(_paContext);
        return -1;
    }

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::MicrophoneVolume(uint32_t& volume) const
{

    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex;

    {
      AutoPulseLock auto_lock(_paMainloop);
      // Get the actual stream device index if we have a connected stream.
      // The device used by the stream can be changed during the call.
      if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream)
          != PA_STREAM_UNCONNECTED))
      {
          deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
      }
    }

    if (!GetSourceInfoByIndex(deviceIndex))
        return -1;

    {
        AutoPulseLock auto_lock(_paMainloop);
        volume = static_cast<uint32_t> (_paVolume);
    }

    LOG(LS_VERBOSE)
        << "AudioMixerManagerLinuxPulse::MicrophoneVolume() => vol="
        << volume;

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::MaxMicrophoneVolume(uint32_t& maxVolume) const
{

    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    // PA_VOLUME_NORM corresponds to 100% (0db)
    // PA allows up to 150 db amplification (PA_VOLUME_MAX)
    // but that doesn't work well for all sound cards
    maxVolume = static_cast<uint32_t> (PA_VOLUME_NORM);

    return 0;
}

int32_t
AudioMixerManagerLinuxPulse::MinMicrophoneVolume(uint32_t& minVolume) const
{

    if (_paInputDeviceIndex == -1)
    {
        LOG(LS_WARNING) << "input device index has not been set";
        return -1;
    }

    minVolume = static_cast<uint32_t> (PA_VOLUME_MUTED);

    return 0;
}

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

void
AudioMixerManagerLinuxPulse::PaSinkInfoCallback(pa_context */*c*/,
                                                const pa_sink_info *i,
                                                int eol,
                                                void *pThis)
{
    static_cast<AudioMixerManagerLinuxPulse*> (pThis)->
        PaSinkInfoCallbackHandler(i, eol);
}

void
AudioMixerManagerLinuxPulse::PaSinkInputInfoCallback(
    pa_context */*c*/,
    const pa_sink_input_info *i,
    int eol,
    void *pThis)
{
    static_cast<AudioMixerManagerLinuxPulse*> (pThis)->
        PaSinkInputInfoCallbackHandler(i, eol);
}


void
AudioMixerManagerLinuxPulse::PaSourceInfoCallback(pa_context */*c*/,
                                                  const pa_source_info *i,
                                                  int eol,
                                                  void *pThis)
{
    static_cast<AudioMixerManagerLinuxPulse*> (pThis)->
        PaSourceInfoCallbackHandler(i, eol);
}

void
AudioMixerManagerLinuxPulse::PaSetVolumeCallback(pa_context * c,
                                                 int success,
                                                 void */*pThis*/)
{
    if (!success)
    {
        LOG(LS_ERROR) << "failed to set volume";
    }
}

void AudioMixerManagerLinuxPulse::PaSinkInfoCallbackHandler(
    const pa_sink_info *i,
    int eol)
{
    if (eol)
    {
        // Signal that we are done
        LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
        return;
    }

    _paChannels = i->channel_map.channels; // Get number of channels
    pa_volume_t paVolume = PA_VOLUME_MUTED; // Minimum possible value.
    for (int j = 0; j < _paChannels; ++j)
    {
        if (paVolume < i->volume.values[j])
        {
            paVolume = i->volume.values[j];
        }
    }
    _paVolume = paVolume; // get the max volume for any channel
    _paMute = i->mute; // get mute status

    // supported since PA 0.9.15
    //_paVolSteps = i->n_volume_steps; // get the number of volume steps
    // default value is PA_VOLUME_NORM+1
    _paVolSteps = PA_VOLUME_NORM + 1;
}

void AudioMixerManagerLinuxPulse::PaSinkInputInfoCallbackHandler(
    const pa_sink_input_info *i,
    int eol)
{
    if (eol)
    {
        // Signal that we are done
        LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
        return;
    }

    _paChannels = i->channel_map.channels; // Get number of channels
    pa_volume_t paVolume = PA_VOLUME_MUTED; // Minimum possible value.
    for (int j = 0; j < _paChannels; ++j)
    {
        if (paVolume < i->volume.values[j])
        {
            paVolume = i->volume.values[j];
        }
    }
    _paVolume = paVolume; // Get the max volume for any channel
    _paMute = i->mute; // Get mute status
}

void AudioMixerManagerLinuxPulse::PaSourceInfoCallbackHandler(
    const pa_source_info *i,
    int eol)
{
    if (eol)
    {
        // Signal that we are done
        LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
        return;
    }

    _paChannels = i->channel_map.channels; // Get number of channels
    pa_volume_t paVolume = PA_VOLUME_MUTED; // Minimum possible value.
    for (int j = 0; j < _paChannels; ++j)
    {
        if (paVolume < i->volume.values[j])
        {
            paVolume = i->volume.values[j];
        }
    }
    _paVolume = paVolume; // Get the max volume for any channel
    _paMute = i->mute; // Get mute status

    // supported since PA 0.9.15
    //_paVolSteps = i->n_volume_steps; // Get the number of volume steps
    // default value is PA_VOLUME_NORM+1
    _paVolSteps = PA_VOLUME_NORM + 1;
}

void AudioMixerManagerLinuxPulse::WaitForOperationCompletion(
    pa_operation* paOperation) const
{
    while (LATE(pa_operation_get_state)(paOperation) == PA_OPERATION_RUNNING)
    {
        LATE(pa_threaded_mainloop_wait)(_paMainloop);
    }

    LATE(pa_operation_unref)(paOperation);
}

bool AudioMixerManagerLinuxPulse::GetSinkInputInfo() const {
  pa_operation* paOperation = NULL;

  AutoPulseLock auto_lock(_paMainloop);
  // Get info for this stream (sink input).
  paOperation = LATE(pa_context_get_sink_input_info)(
      _paContext,
      LATE(pa_stream_get_index)(_paPlayStream),
      PaSinkInputInfoCallback,
      (void*) this);

  WaitForOperationCompletion(paOperation);
  return true;
}

bool AudioMixerManagerLinuxPulse::GetSinkInfoByIndex(
    int device_index) const {
  pa_operation* paOperation = NULL;

  AutoPulseLock auto_lock(_paMainloop);
  paOperation = LATE(pa_context_get_sink_info_by_index)(_paContext,
      device_index, PaSinkInfoCallback, (void*) this);

  WaitForOperationCompletion(paOperation);
  return true;
}

bool AudioMixerManagerLinuxPulse::GetSourceInfoByIndex(
    int device_index) const {
  pa_operation* paOperation = NULL;

  AutoPulseLock auto_lock(_paMainloop);
  paOperation  = LATE(pa_context_get_source_info_by_index)(
      _paContext, device_index, PaSourceInfoCallback, (void*) this);

  WaitForOperationCompletion(paOperation);
  return true;
}

}
