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