Home | History | Annotate | Download | only in linux
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_PULSE_LINUX_H
     12 #define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_PULSE_LINUX_H
     13 
     14 #include "webrtc/modules/audio_device/audio_device_generic.h"
     15 #include "webrtc/modules/audio_device/linux/audio_mixer_manager_pulse_linux.h"
     16 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     17 
     18 #include <X11/Xlib.h>
     19 #include <pulse/pulseaudio.h>
     20 
     21 // We define this flag if it's missing from our headers, because we want to be
     22 // able to compile against old headers but still use PA_STREAM_ADJUST_LATENCY
     23 // if run against a recent version of the library.
     24 #ifndef PA_STREAM_ADJUST_LATENCY
     25 #define PA_STREAM_ADJUST_LATENCY 0x2000U
     26 #endif
     27 #ifndef PA_STREAM_START_MUTED
     28 #define PA_STREAM_START_MUTED 0x1000U
     29 #endif
     30 
     31 // Set this constant to 0 to disable latency reading
     32 const uint32_t WEBRTC_PA_REPORT_LATENCY = 1;
     33 
     34 // Constants from implementation by Tristan Schmelcher [tschmelcher (at) google.com]
     35 
     36 // First PulseAudio protocol version that supports PA_STREAM_ADJUST_LATENCY.
     37 const uint32_t WEBRTC_PA_ADJUST_LATENCY_PROTOCOL_VERSION = 13;
     38 
     39 // Some timing constants for optimal operation. See
     40 // https://tango.0pointer.de/pipermail/pulseaudio-discuss/2008-January/001170.html
     41 // for a good explanation of some of the factors that go into this.
     42 
     43 // Playback.
     44 
     45 // For playback, there is a round-trip delay to fill the server-side playback
     46 // buffer, so setting too low of a latency is a buffer underflow risk. We will
     47 // automatically increase the latency if a buffer underflow does occur, but we
     48 // also enforce a sane minimum at start-up time. Anything lower would be
     49 // virtually guaranteed to underflow at least once, so there's no point in
     50 // allowing lower latencies.
     51 const uint32_t WEBRTC_PA_PLAYBACK_LATENCY_MINIMUM_MSECS = 20;
     52 
     53 // Every time a playback stream underflows, we will reconfigure it with target
     54 // latency that is greater by this amount.
     55 const uint32_t WEBRTC_PA_PLAYBACK_LATENCY_INCREMENT_MSECS = 20;
     56 
     57 // We also need to configure a suitable request size. Too small and we'd burn
     58 // CPU from the overhead of transfering small amounts of data at once. Too large
     59 // and the amount of data remaining in the buffer right before refilling it
     60 // would be a buffer underflow risk. We set it to half of the buffer size.
     61 const uint32_t WEBRTC_PA_PLAYBACK_REQUEST_FACTOR = 2;
     62 
     63 // Capture.
     64 
     65 // For capture, low latency is not a buffer overflow risk, but it makes us burn
     66 // CPU from the overhead of transfering small amounts of data at once, so we set
     67 // a recommended value that we use for the kLowLatency constant (but if the user
     68 // explicitly requests something lower then we will honour it).
     69 // 1ms takes about 6-7% CPU. 5ms takes about 5%. 10ms takes about 4.x%.
     70 const uint32_t WEBRTC_PA_LOW_CAPTURE_LATENCY_MSECS = 10;
     71 
     72 // There is a round-trip delay to ack the data to the server, so the
     73 // server-side buffer needs extra space to prevent buffer overflow. 20ms is
     74 // sufficient, but there is no penalty to making it bigger, so we make it huge.
     75 // (750ms is libpulse's default value for the _total_ buffer size in the
     76 // kNoLatencyRequirements case.)
     77 const uint32_t WEBRTC_PA_CAPTURE_BUFFER_EXTRA_MSECS = 750;
     78 
     79 const uint32_t WEBRTC_PA_MSECS_PER_SEC = 1000;
     80 
     81 // Init _configuredLatencyRec/Play to this value to disable latency requirements
     82 const int32_t WEBRTC_PA_NO_LATENCY_REQUIREMENTS = -1;
     83 
     84 // Set this const to 1 to account for peeked and used data in latency calculation
     85 const uint32_t WEBRTC_PA_CAPTURE_BUFFER_LATENCY_ADJUSTMENT = 0;
     86 
     87 namespace webrtc
     88 {
     89 class EventWrapper;
     90 class ThreadWrapper;
     91 
     92 class AudioDeviceLinuxPulse: public AudioDeviceGeneric
     93 {
     94 public:
     95     AudioDeviceLinuxPulse(const int32_t id);
     96     virtual ~AudioDeviceLinuxPulse();
     97 
     98     // Retrieve the currently utilized audio layer
     99     virtual int32_t ActiveAudioLayer(
    100         AudioDeviceModule::AudioLayer& audioLayer) const OVERRIDE;
    101 
    102     // Main initializaton and termination
    103     virtual int32_t Init() OVERRIDE;
    104     virtual int32_t Terminate() OVERRIDE;
    105     virtual bool Initialized() const OVERRIDE;
    106 
    107     // Device enumeration
    108     virtual int16_t PlayoutDevices() OVERRIDE;
    109     virtual int16_t RecordingDevices() OVERRIDE;
    110     virtual int32_t PlayoutDeviceName(
    111         uint16_t index,
    112         char name[kAdmMaxDeviceNameSize],
    113         char guid[kAdmMaxGuidSize]) OVERRIDE;
    114     virtual int32_t RecordingDeviceName(
    115         uint16_t index,
    116         char name[kAdmMaxDeviceNameSize],
    117         char guid[kAdmMaxGuidSize]) OVERRIDE;
    118 
    119     // Device selection
    120     virtual int32_t SetPlayoutDevice(uint16_t index) OVERRIDE;
    121     virtual int32_t SetPlayoutDevice(
    122         AudioDeviceModule::WindowsDeviceType device) OVERRIDE;
    123     virtual int32_t SetRecordingDevice(uint16_t index) OVERRIDE;
    124     virtual int32_t SetRecordingDevice(
    125         AudioDeviceModule::WindowsDeviceType device) OVERRIDE;
    126 
    127     // Audio transport initialization
    128     virtual int32_t PlayoutIsAvailable(bool& available) OVERRIDE;
    129     virtual int32_t InitPlayout() OVERRIDE;
    130     virtual bool PlayoutIsInitialized() const OVERRIDE;
    131     virtual int32_t RecordingIsAvailable(bool& available) OVERRIDE;
    132     virtual int32_t InitRecording() OVERRIDE;
    133     virtual bool RecordingIsInitialized() const OVERRIDE;
    134 
    135     // Audio transport control
    136     virtual int32_t StartPlayout() OVERRIDE;
    137     virtual int32_t StopPlayout() OVERRIDE;
    138     virtual bool Playing() const OVERRIDE;
    139     virtual int32_t StartRecording() OVERRIDE;
    140     virtual int32_t StopRecording() OVERRIDE;
    141     virtual bool Recording() const OVERRIDE;
    142 
    143     // Microphone Automatic Gain Control (AGC)
    144     virtual int32_t SetAGC(bool enable) OVERRIDE;
    145     virtual bool AGC() const OVERRIDE;
    146 
    147     // Volume control based on the Windows Wave API (Windows only)
    148     virtual int32_t SetWaveOutVolume(uint16_t volumeLeft,
    149                                      uint16_t volumeRight) OVERRIDE;
    150     virtual int32_t WaveOutVolume(uint16_t& volumeLeft,
    151                                   uint16_t& volumeRight) const OVERRIDE;
    152 
    153     // Audio mixer initialization
    154     virtual int32_t InitSpeaker() OVERRIDE;
    155     virtual bool SpeakerIsInitialized() const OVERRIDE;
    156     virtual int32_t InitMicrophone() OVERRIDE;
    157     virtual bool MicrophoneIsInitialized() const OVERRIDE;
    158 
    159     // Speaker volume controls
    160     virtual int32_t SpeakerVolumeIsAvailable(bool& available) OVERRIDE;
    161     virtual int32_t SetSpeakerVolume(uint32_t volume) OVERRIDE;
    162     virtual int32_t SpeakerVolume(uint32_t& volume) const OVERRIDE;
    163     virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const OVERRIDE;
    164     virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const OVERRIDE;
    165     virtual int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const OVERRIDE;
    166 
    167     // Microphone volume controls
    168     virtual int32_t MicrophoneVolumeIsAvailable(bool& available) OVERRIDE;
    169     virtual int32_t SetMicrophoneVolume(uint32_t volume) OVERRIDE;
    170     virtual int32_t MicrophoneVolume(uint32_t& volume) const OVERRIDE;
    171     virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const OVERRIDE;
    172     virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const OVERRIDE;
    173     virtual int32_t MicrophoneVolumeStepSize(
    174         uint16_t& stepSize) const OVERRIDE;
    175 
    176     // Speaker mute control
    177     virtual int32_t SpeakerMuteIsAvailable(bool& available) OVERRIDE;
    178     virtual int32_t SetSpeakerMute(bool enable) OVERRIDE;
    179     virtual int32_t SpeakerMute(bool& enabled) const OVERRIDE;
    180 
    181     // Microphone mute control
    182     virtual int32_t MicrophoneMuteIsAvailable(bool& available) OVERRIDE;
    183     virtual int32_t SetMicrophoneMute(bool enable) OVERRIDE;
    184     virtual int32_t MicrophoneMute(bool& enabled) const OVERRIDE;
    185 
    186     // Microphone boost control
    187     virtual int32_t MicrophoneBoostIsAvailable(bool& available) OVERRIDE;
    188     virtual int32_t SetMicrophoneBoost(bool enable) OVERRIDE;
    189     virtual int32_t MicrophoneBoost(bool& enabled) const OVERRIDE;
    190 
    191     // Stereo support
    192     virtual int32_t StereoPlayoutIsAvailable(bool& available) OVERRIDE;
    193     virtual int32_t SetStereoPlayout(bool enable) OVERRIDE;
    194     virtual int32_t StereoPlayout(bool& enabled) const OVERRIDE;
    195     virtual int32_t StereoRecordingIsAvailable(bool& available) OVERRIDE;
    196     virtual int32_t SetStereoRecording(bool enable) OVERRIDE;
    197     virtual int32_t StereoRecording(bool& enabled) const OVERRIDE;
    198 
    199     // Delay information and control
    200     virtual int32_t
    201         SetPlayoutBuffer(const AudioDeviceModule::BufferType type,
    202                          uint16_t sizeMS) OVERRIDE;
    203     virtual int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type,
    204                                   uint16_t& sizeMS) const OVERRIDE;
    205     virtual int32_t PlayoutDelay(uint16_t& delayMS) const OVERRIDE;
    206     virtual int32_t RecordingDelay(uint16_t& delayMS) const OVERRIDE;
    207 
    208     // CPU load
    209     virtual int32_t CPULoad(uint16_t& load) const OVERRIDE;
    210 
    211 public:
    212     virtual bool PlayoutWarning() const OVERRIDE;
    213     virtual bool PlayoutError() const OVERRIDE;
    214     virtual bool RecordingWarning() const OVERRIDE;
    215     virtual bool RecordingError() const OVERRIDE;
    216     virtual void ClearPlayoutWarning() OVERRIDE;
    217     virtual void ClearPlayoutError() OVERRIDE;
    218     virtual void ClearRecordingWarning() OVERRIDE;
    219     virtual void ClearRecordingError() OVERRIDE;
    220 
    221 public:
    222     virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) OVERRIDE;
    223 
    224 private:
    225     void Lock() EXCLUSIVE_LOCK_FUNCTION(_critSect) {
    226         _critSect.Enter();
    227     }
    228     void UnLock() UNLOCK_FUNCTION(_critSect) {
    229         _critSect.Leave();
    230     }
    231     void WaitForOperationCompletion(pa_operation* paOperation) const;
    232     void WaitForSuccess(pa_operation* paOperation) const;
    233 
    234 private:
    235     bool KeyPressed() const;
    236 
    237 private:
    238     static void PaContextStateCallback(pa_context *c, void *pThis);
    239     static void PaSinkInfoCallback(pa_context *c, const pa_sink_info *i,
    240                                    int eol, void *pThis);
    241     static void PaSourceInfoCallback(pa_context *c, const pa_source_info *i,
    242                                      int eol, void *pThis);
    243     static void PaServerInfoCallback(pa_context *c, const pa_server_info *i,
    244                                      void *pThis);
    245     static void PaStreamStateCallback(pa_stream *p, void *pThis);
    246     void PaContextStateCallbackHandler(pa_context *c);
    247     void PaSinkInfoCallbackHandler(const pa_sink_info *i, int eol);
    248     void PaSourceInfoCallbackHandler(const pa_source_info *i, int eol);
    249     void PaServerInfoCallbackHandler(const pa_server_info *i);
    250     void PaStreamStateCallbackHandler(pa_stream *p);
    251 
    252     void EnableWriteCallback();
    253     void DisableWriteCallback();
    254     static void PaStreamWriteCallback(pa_stream *unused, size_t buffer_space,
    255                                       void *pThis);
    256     void PaStreamWriteCallbackHandler(size_t buffer_space);
    257     static void PaStreamUnderflowCallback(pa_stream *unused, void *pThis);
    258     void PaStreamUnderflowCallbackHandler();
    259     void EnableReadCallback();
    260     void DisableReadCallback();
    261     static void PaStreamReadCallback(pa_stream *unused1, size_t unused2,
    262                                      void *pThis);
    263     void PaStreamReadCallbackHandler();
    264     static void PaStreamOverflowCallback(pa_stream *unused, void *pThis);
    265     void PaStreamOverflowCallbackHandler();
    266     int32_t LatencyUsecs(pa_stream *stream);
    267     int32_t ReadRecordedData(const void* bufferData, size_t bufferSize);
    268     int32_t ProcessRecordedData(int8_t *bufferData,
    269                                 uint32_t bufferSizeInSamples,
    270                                 uint32_t recDelay);
    271 
    272     int32_t CheckPulseAudioVersion();
    273     int32_t InitSamplingFrequency();
    274     int32_t GetDefaultDeviceInfo(bool recDevice, char* name, uint16_t& index);
    275     int32_t InitPulseAudio();
    276     int32_t TerminatePulseAudio();
    277 
    278     void PaLock();
    279     void PaUnLock();
    280 
    281     static bool RecThreadFunc(void*);
    282     static bool PlayThreadFunc(void*);
    283     bool RecThreadProcess();
    284     bool PlayThreadProcess();
    285 
    286 private:
    287     AudioDeviceBuffer* _ptrAudioBuffer;
    288 
    289     CriticalSectionWrapper& _critSect;
    290     EventWrapper& _timeEventRec;
    291     EventWrapper& _timeEventPlay;
    292     EventWrapper& _recStartEvent;
    293     EventWrapper& _playStartEvent;
    294 
    295     ThreadWrapper* _ptrThreadPlay;
    296     ThreadWrapper* _ptrThreadRec;
    297     uint32_t _recThreadID;
    298     uint32_t _playThreadID;
    299     int32_t _id;
    300 
    301     AudioMixerManagerLinuxPulse _mixerManager;
    302 
    303     uint16_t _inputDeviceIndex;
    304     uint16_t _outputDeviceIndex;
    305     bool _inputDeviceIsSpecified;
    306     bool _outputDeviceIsSpecified;
    307 
    308     int sample_rate_hz_;
    309     uint8_t _recChannels;
    310     uint8_t _playChannels;
    311 
    312     AudioDeviceModule::BufferType _playBufType;
    313 
    314 private:
    315     bool _initialized;
    316     bool _recording;
    317     bool _playing;
    318     bool _recIsInitialized;
    319     bool _playIsInitialized;
    320     bool _startRec;
    321     bool _stopRec;
    322     bool _startPlay;
    323     bool _stopPlay;
    324     bool _AGC;
    325     bool update_speaker_volume_at_startup_;
    326 
    327 private:
    328     uint16_t _playBufDelayFixed; // fixed playback delay
    329 
    330     uint32_t _sndCardPlayDelay;
    331     uint32_t _sndCardRecDelay;
    332 
    333     int32_t _writeErrors;
    334     uint16_t _playWarning;
    335     uint16_t _playError;
    336     uint16_t _recWarning;
    337     uint16_t _recError;
    338 
    339     uint16_t _deviceIndex;
    340     int16_t _numPlayDevices;
    341     int16_t _numRecDevices;
    342     char* _playDeviceName;
    343     char* _recDeviceName;
    344     char* _playDisplayDeviceName;
    345     char* _recDisplayDeviceName;
    346     char _paServerVersion[32];
    347 
    348     int8_t* _playBuffer;
    349     size_t _playbackBufferSize;
    350     size_t _playbackBufferUnused;
    351     size_t _tempBufferSpace;
    352     int8_t* _recBuffer;
    353     size_t _recordBufferSize;
    354     size_t _recordBufferUsed;
    355     const void* _tempSampleData;
    356     size_t _tempSampleDataSize;
    357     int32_t _configuredLatencyPlay;
    358     int32_t _configuredLatencyRec;
    359 
    360     // PulseAudio
    361     uint16_t _paDeviceIndex;
    362     bool _paStateChanged;
    363 
    364     pa_threaded_mainloop* _paMainloop;
    365     pa_mainloop_api* _paMainloopApi;
    366     pa_context* _paContext;
    367 
    368     pa_stream* _recStream;
    369     pa_stream* _playStream;
    370     uint32_t _recStreamFlags;
    371     uint32_t _playStreamFlags;
    372     pa_buffer_attr _playBufferAttr;
    373     pa_buffer_attr _recBufferAttr;
    374 
    375     char _oldKeyState[32];
    376     Display* _XDisplay;
    377 };
    378 
    379 }
    380 
    381 #endif  // MODULES_AUDIO_DEVICE_MAIN_SOURCE_LINUX_AUDIO_DEVICE_PULSE_LINUX_H_
    382