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