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