3 * Copyright 2010, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "talk/sound/pulseaudiosoundsystem.h"
32 #include "talk/sound/sounddevicelocator.h"
33 #include "talk/sound/soundinputstreaminterface.h"
34 #include "talk/sound/soundoutputstreaminterface.h"
35 #include "webrtc/base/common.h"
36 #include "webrtc/base/fileutils.h" // for GetApplicationName()
37 #include "webrtc/base/logging.h"
38 #include "webrtc/base/timeutils.h"
39 #include "webrtc/base/worker.h"
43 // First PulseAudio protocol version that supports PA_STREAM_ADJUST_LATENCY.
44 static const uint32_t kAdjustLatencyProtocolVersion = 13;
46 // Lookup table from the cricket format enum in soundsysteminterface.h to
48 static const pa_sample_format_t kCricketFormatToPulseFormatTable[] = {
49 // The order here must match the order in soundsysteminterface.h
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.
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 static const int kPlaybackLatencyMinimumMsecs = 20;
66 // Every time a playback stream underflows, we will reconfigure it with target
67 // latency that is greater by this amount.
68 static const int kPlaybackLatencyIncrementMsecs = 20;
69 // We also need to configure a suitable request size. Too small and we'd burn
70 // CPU from the overhead of transfering small amounts of data at once. Too large
71 // and the amount of data remaining in the buffer right before refilling it
72 // would be a buffer underflow risk. We set it to half of the buffer size.
73 static const int kPlaybackRequestFactor = 2;
77 // For capture, low latency is not a buffer overflow risk, but it makes us burn
78 // CPU from the overhead of transfering small amounts of data at once, so we set
79 // a recommended value that we use for the kLowLatency constant (but if the user
80 // explicitly requests something lower then we will honour it).
81 // 1ms takes about 6-7% CPU. 5ms takes about 5%. 10ms takes about 4.x%.
82 static const int kLowCaptureLatencyMsecs = 10;
83 // There is a round-trip delay to ack the data to the server, so the
84 // server-side buffer needs extra space to prevent buffer overflow. 20ms is
85 // sufficient, but there is no penalty to making it bigger, so we make it huge.
86 // (750ms is libpulse's default value for the _total_ buffer size in the
87 // kNoLatencyRequirements case.)
88 static const int kCaptureBufferExtraMsecs = 750;
90 static void FillPlaybackBufferAttr(int latency,
91 pa_buffer_attr *attr) {
92 attr->maxlength = latency;
93 attr->tlength = latency;
94 attr->minreq = latency / kPlaybackRequestFactor;
95 attr->prebuf = attr->tlength - attr->minreq;
96 LOG(LS_VERBOSE) << "Configuring latency = " << attr->tlength << ", minreq = "
97 << attr->minreq << ", minfill = " << attr->prebuf;
100 static pa_volume_t CricketVolumeToPulseVolume(int volume) {
101 // PA's volume space goes from 0% at PA_VOLUME_MUTED (value 0) to 100% at
102 // PA_VOLUME_NORM (value 0x10000). It can also go beyond 100% up to
103 // PA_VOLUME_MAX (value UINT32_MAX-1), but using that is probably unwise.
104 // We just linearly map the 0-255 scale of SoundSystemInterface onto
105 // PA_VOLUME_MUTED-PA_VOLUME_NORM. If the programmer exceeds kMaxVolume then
106 // they can access the over-100% features of PA.
107 return PA_VOLUME_MUTED + (PA_VOLUME_NORM - PA_VOLUME_MUTED) *
108 volume / SoundSystemInterface::kMaxVolume;
111 static int PulseVolumeToCricketVolume(pa_volume_t pa_volume) {
112 return SoundSystemInterface::kMinVolume +
113 (SoundSystemInterface::kMaxVolume - SoundSystemInterface::kMinVolume) *
114 pa_volume / PA_VOLUME_NORM;
117 static pa_volume_t MaxChannelVolume(pa_cvolume *channel_volumes) {
118 pa_volume_t pa_volume = PA_VOLUME_MUTED; // Minimum possible value.
119 for (int i = 0; i < channel_volumes->channels; ++i) {
120 if (pa_volume < channel_volumes->values[i]) {
121 pa_volume = channel_volumes->values[i];
127 class PulseAudioDeviceLocator : public SoundDeviceLocator {
129 PulseAudioDeviceLocator(const std::string &name,
130 const std::string &device_name)
131 : SoundDeviceLocator(name, device_name) {
134 virtual SoundDeviceLocator *Copy() const {
135 return new PulseAudioDeviceLocator(*this);
139 // Functionality that is common to both PulseAudioInputStream and
140 // PulseAudioOutputStream.
141 class PulseAudioStream {
143 PulseAudioStream(PulseAudioSoundSystem *pulse, pa_stream *stream, int flags)
144 : pulse_(pulse), stream_(stream), flags_(flags) {
147 ~PulseAudioStream() {
148 // Close() should have been called during the containing class's destructor.
149 ASSERT(stream_ == NULL);
152 // Must be called with the lock held.
155 // Unset this here so that we don't get a TERMINATED callback.
156 symbol_table()->pa_stream_set_state_callback()(stream_, NULL, NULL);
157 if (symbol_table()->pa_stream_disconnect()(stream_) != 0) {
158 LOG(LS_ERROR) << "Can't disconnect stream";
159 // Continue and return true anyways.
161 symbol_table()->pa_stream_unref()(stream_);
167 // Must be called with the lock held.
169 if (!(flags_ & SoundSystemInterface::FLAG_REPORT_LATENCY)) {
176 int re = symbol_table()->pa_stream_get_latency()(stream_, &latency,
180 LOG(LS_ERROR) << "Can't query latency";
181 // We'd rather continue playout/capture with an incorrect delay than stop
182 // it altogether, so return a valid value.
186 // The delay can be negative for monitoring streams if the captured
187 // samples haven't been played yet. In such a case, "latency" contains the
188 // magnitude, so we must negate it to get the real value.
195 PulseAudioSoundSystem *pulse() {
199 PulseAudioSymbolTable *symbol_table() {
200 return &pulse()->symbol_table_;
203 pa_stream *stream() {
204 ASSERT(stream_ != NULL);
209 return stream_ == NULL;
221 PulseAudioSoundSystem *pulse_;
225 DISALLOW_COPY_AND_ASSIGN(PulseAudioStream);
228 // Implementation of an input stream. See soundinputstreaminterface.h regarding
230 class PulseAudioInputStream :
231 public SoundInputStreamInterface,
232 private rtc::Worker {
234 struct GetVolumeCallbackData {
235 PulseAudioInputStream *instance;
236 pa_cvolume *channel_volumes;
239 struct GetSourceChannelCountCallbackData {
240 PulseAudioInputStream *instance;
245 PulseAudioInputStream(PulseAudioSoundSystem *pulse,
248 : stream_(pulse, stream, flags),
249 temp_sample_data_(NULL),
250 temp_sample_data_size_(0) {
251 // This callback seems to never be issued, but let's set it anyways.
252 symbol_table()->pa_stream_set_overflow_callback()(stream, &OverflowCallback,
256 virtual ~PulseAudioInputStream() {
257 bool success = Close();
258 // We need that to live.
262 virtual bool StartReading() {
266 virtual bool StopReading() {
270 virtual bool GetVolume(int *volume) {
275 // Unlike output streams, input streams have no concept of a stream volume,
276 // only a device volume. So we have to retrieve the volume of the device
279 pa_cvolume channel_volumes;
281 GetVolumeCallbackData data;
282 data.instance = this;
283 data.channel_volumes = &channel_volumes;
285 pa_operation *op = symbol_table()->pa_context_get_source_info_by_index()(
286 stream_.pulse()->context_,
287 symbol_table()->pa_stream_get_device_index()(stream_.stream()),
288 &GetVolumeCallbackThunk,
290 if (!stream_.pulse()->FinishOperation(op)) {
294 if (data.channel_volumes) {
295 // This pointer was never unset by the callback, so we must have received
296 // an empty list of infos. This probably never happens, but we code for it
298 LOG(LS_ERROR) << "Did not receive GetVolumeCallback";
302 // We now have the volume for each channel. Each channel could have a
303 // different volume if, e.g., the user went and changed the volumes in the
304 // PA UI. To get a single volume for SoundSystemInterface we just take the
305 // maximum. Ideally we'd do so with pa_cvolume_max, but it doesn't exist in
306 // Hardy, so we do it manually.
307 pa_volume_t pa_volume;
308 pa_volume = MaxChannelVolume(&channel_volumes);
309 // Now map onto the SoundSystemInterface range.
310 *volume = PulseVolumeToCricketVolume(pa_volume);
318 virtual bool SetVolume(int volume) {
320 pa_volume_t pa_volume = CricketVolumeToPulseVolume(volume);
324 // Unlike output streams, input streams have no concept of a stream volume,
325 // only a device volume. So we have to change the volume of the device
328 // The device may have a different number of channels than the stream and
329 // their mapping may be different, so we don't want to use the channel count
330 // from our sample spec. We could use PA_CHANNELS_MAX to cover our bases,
331 // and the server allows that even if the device's channel count is lower,
332 // but some buggy PA clients don't like that (the pavucontrol on Hardy dies
333 // in an assert if the channel count is different). So instead we look up
334 // the actual number of channels that the device has.
338 GetSourceChannelCountCallbackData data;
339 data.instance = this;
340 data.channels = &channels;
342 uint32_t device_index = symbol_table()->pa_stream_get_device_index()(
345 pa_operation *op = symbol_table()->pa_context_get_source_info_by_index()(
346 stream_.pulse()->context_,
348 &GetSourceChannelCountCallbackThunk,
350 if (!stream_.pulse()->FinishOperation(op)) {
355 // This pointer was never unset by the callback, so we must have received
356 // an empty list of infos. This probably never happens, but we code for it
358 LOG(LS_ERROR) << "Did not receive GetSourceChannelCountCallback";
362 pa_cvolume channel_volumes;
363 symbol_table()->pa_cvolume_set()(&channel_volumes, channels, pa_volume);
365 op = symbol_table()->pa_context_set_source_volume_by_index()(
366 stream_.pulse()->context_,
369 // This callback merely logs errors.
373 LOG(LS_ERROR) << "pa_context_set_source_volume_by_index()";
376 // Don't need to wait for this to complete.
377 symbol_table()->pa_operation_unref()(op);
385 virtual bool Close() {
386 if (!StopReading()) {
390 if (!stream_.IsClosed()) {
392 ret = stream_.Close();
398 virtual int LatencyUsecs() {
399 return stream_.LatencyUsecs();
411 PulseAudioSymbolTable *symbol_table() {
412 return stream_.symbol_table();
415 void EnableReadCallback() {
416 symbol_table()->pa_stream_set_read_callback()(
422 void DisableReadCallback() {
423 symbol_table()->pa_stream_set_read_callback()(
429 static void ReadCallbackThunk(pa_stream *unused1,
432 PulseAudioInputStream *instance =
433 static_cast<PulseAudioInputStream *>(userdata);
434 instance->OnReadCallback();
437 void OnReadCallback() {
438 // We get the data pointer and size now in order to save one Lock/Unlock
440 if (symbol_table()->pa_stream_peek()(stream_.stream(),
442 &temp_sample_data_size_) != 0) {
443 LOG(LS_ERROR) << "Can't read data!";
446 // Since we consume the data asynchronously on a different thread, we have
447 // to temporarily disable the read callback or else Pulse will call it
448 // continuously until we consume the data. We re-enable it below.
449 DisableReadCallback();
453 // Inherited from Worker.
454 virtual void OnStart() {
456 EnableReadCallback();
460 // Inherited from Worker.
461 virtual void OnHaveWork() {
462 ASSERT(temp_sample_data_ && temp_sample_data_size_);
463 SignalSamplesRead(temp_sample_data_,
464 temp_sample_data_size_,
466 temp_sample_data_ = NULL;
467 temp_sample_data_size_ = 0;
471 // Ack the last thing we read.
472 if (symbol_table()->pa_stream_drop()(stream_.stream()) != 0) {
473 LOG(LS_ERROR) << "Can't ack read data";
476 if (symbol_table()->pa_stream_readable_size()(stream_.stream()) <= 0) {
477 // Then that was all the data.
482 const void *sample_data;
483 size_t sample_data_size;
484 if (symbol_table()->pa_stream_peek()(stream_.stream(),
486 &sample_data_size) != 0) {
487 LOG(LS_ERROR) << "Can't read data!";
491 // Drop lock for sigslot dispatch, which could take a while.
493 SignalSamplesRead(sample_data, sample_data_size, this);
496 // Return to top of loop for the ack and the check for more data.
498 EnableReadCallback();
502 // Inherited from Worker.
503 virtual void OnStop() {
505 DisableReadCallback();
509 static void OverflowCallback(pa_stream *stream,
511 LOG(LS_WARNING) << "Buffer overflow on capture stream " << stream;
514 static void GetVolumeCallbackThunk(pa_context *unused,
515 const pa_source_info *info,
518 GetVolumeCallbackData *data =
519 static_cast<GetVolumeCallbackData *>(userdata);
520 data->instance->OnGetVolumeCallback(info, eol, &data->channel_volumes);
523 void OnGetVolumeCallback(const pa_source_info *info,
525 pa_cvolume **channel_volumes) {
527 // List is over. Wake GetVolume().
528 stream_.pulse()->Signal();
532 if (*channel_volumes) {
533 **channel_volumes = info->volume;
534 // Unset the pointer so that we know that we have have already copied the
536 *channel_volumes = NULL;
538 // We have received an additional callback after the first one, which
539 // doesn't make sense for a single source. This probably never happens,
540 // but we code for it anyway.
541 LOG(LS_WARNING) << "Ignoring extra GetVolumeCallback";
545 static void GetSourceChannelCountCallbackThunk(pa_context *unused,
546 const pa_source_info *info,
549 GetSourceChannelCountCallbackData *data =
550 static_cast<GetSourceChannelCountCallbackData *>(userdata);
551 data->instance->OnGetSourceChannelCountCallback(info, eol, &data->channels);
554 void OnGetSourceChannelCountCallback(const pa_source_info *info,
556 uint8_t **channels) {
558 // List is over. Wake SetVolume().
559 stream_.pulse()->Signal();
564 **channels = info->channel_map.channels;
565 // Unset the pointer so that we know that we have have already copied the
569 // We have received an additional callback after the first one, which
570 // doesn't make sense for a single source. This probably never happens,
571 // but we code for it anyway.
572 LOG(LS_WARNING) << "Ignoring extra GetSourceChannelCountCallback";
576 static void SetVolumeCallback(pa_context *unused1,
580 LOG(LS_ERROR) << "Failed to change capture volume";
584 PulseAudioStream stream_;
585 // Temporary storage for passing data between threads.
586 const void *temp_sample_data_;
587 size_t temp_sample_data_size_;
589 DISALLOW_COPY_AND_ASSIGN(PulseAudioInputStream);
592 // Implementation of an output stream. See soundoutputstreaminterface.h
593 // regarding thread-safety.
594 class PulseAudioOutputStream :
595 public SoundOutputStreamInterface,
596 private rtc::Worker {
598 struct GetVolumeCallbackData {
599 PulseAudioOutputStream *instance;
600 pa_cvolume *channel_volumes;
604 PulseAudioOutputStream(PulseAudioSoundSystem *pulse,
608 : stream_(pulse, stream, flags),
609 configured_latency_(latency),
610 temp_buffer_space_(0) {
611 symbol_table()->pa_stream_set_underflow_callback()(stream,
612 &UnderflowCallbackThunk,
616 virtual ~PulseAudioOutputStream() {
617 bool success = Close();
618 // We need that to live.
622 virtual bool EnableBufferMonitoring() {
626 virtual bool DisableBufferMonitoring() {
630 virtual bool WriteSamples(const void *sample_data,
634 if (symbol_table()->pa_stream_write()(stream_.stream(),
639 PA_SEEK_RELATIVE) != 0) {
640 LOG(LS_ERROR) << "Unable to write";
647 virtual bool GetVolume(int *volume) {
652 pa_cvolume channel_volumes;
654 GetVolumeCallbackData data;
655 data.instance = this;
656 data.channel_volumes = &channel_volumes;
658 pa_operation *op = symbol_table()->pa_context_get_sink_input_info()(
659 stream_.pulse()->context_,
660 symbol_table()->pa_stream_get_index()(stream_.stream()),
661 &GetVolumeCallbackThunk,
663 if (!stream_.pulse()->FinishOperation(op)) {
667 if (data.channel_volumes) {
668 // This pointer was never unset by the callback, so we must have received
669 // an empty list of infos. This probably never happens, but we code for it
671 LOG(LS_ERROR) << "Did not receive GetVolumeCallback";
675 // We now have the volume for each channel. Each channel could have a
676 // different volume if, e.g., the user went and changed the volumes in the
677 // PA UI. To get a single volume for SoundSystemInterface we just take the
678 // maximum. Ideally we'd do so with pa_cvolume_max, but it doesn't exist in
679 // Hardy, so we do it manually.
680 pa_volume_t pa_volume;
681 pa_volume = MaxChannelVolume(&channel_volumes);
682 // Now map onto the SoundSystemInterface range.
683 *volume = PulseVolumeToCricketVolume(pa_volume);
691 virtual bool SetVolume(int volume) {
693 pa_volume_t pa_volume = CricketVolumeToPulseVolume(volume);
697 const pa_sample_spec *spec = symbol_table()->pa_stream_get_sample_spec()(
700 LOG(LS_ERROR) << "pa_stream_get_sample_spec()";
704 pa_cvolume channel_volumes;
705 symbol_table()->pa_cvolume_set()(&channel_volumes, spec->channels,
709 op = symbol_table()->pa_context_set_sink_input_volume()(
710 stream_.pulse()->context_,
711 symbol_table()->pa_stream_get_index()(stream_.stream()),
713 // This callback merely logs errors.
717 LOG(LS_ERROR) << "pa_context_set_sink_input_volume()";
720 // Don't need to wait for this to complete.
721 symbol_table()->pa_operation_unref()(op);
729 virtual bool Close() {
730 if (!DisableBufferMonitoring()) {
734 if (!stream_.IsClosed()) {
736 symbol_table()->pa_stream_set_underflow_callback()(stream_.stream(),
739 ret = stream_.Close();
745 virtual int LatencyUsecs() {
746 return stream_.LatencyUsecs();
750 // TODO: Versions 0.9.16 and later of Pulse have a new API for
751 // zero-copy writes, but Hardy is not new enough to have that so we can't
752 // rely on it. Perhaps auto-detect if it's present or not and use it if we
755 virtual bool GetWriteBuffer(void **buffer, size_t *size) {
758 if (symbol_table()->pa_stream_begin_write()(stream_.stream(), buffer, size)
760 LOG(LS_ERROR) << "Can't get write buffer";
767 // Releases the caller's hold on the write buffer. "written" must be the
768 // amount of data that was written.
769 virtual bool ReleaseWriteBuffer(void *buffer, size_t written) {
773 if (symbol_table()->pa_stream_cancel_write()(stream_.stream()) != 0) {
774 LOG(LS_ERROR) << "Can't cancel write";
778 if (symbol_table()->pa_stream_write()(stream_.stream(),
783 PA_SEEK_RELATIVE) != 0) {
784 LOG(LS_ERROR) << "Unable to write";
802 PulseAudioSymbolTable *symbol_table() {
803 return stream_.symbol_table();
806 void EnableWriteCallback() {
807 pa_stream_state_t state = symbol_table()->pa_stream_get_state()(
809 if (state == PA_STREAM_READY) {
810 // May already have available space. Must check.
811 temp_buffer_space_ = symbol_table()->pa_stream_writable_size()(
813 if (temp_buffer_space_ > 0) {
814 // Yup, there is already space available, so if we register a write
815 // callback then it will not receive any event. So dispatch one ourself
821 symbol_table()->pa_stream_set_write_callback()(
827 void DisableWriteCallback() {
828 symbol_table()->pa_stream_set_write_callback()(
834 static void WriteCallbackThunk(pa_stream *unused,
837 PulseAudioOutputStream *instance =
838 static_cast<PulseAudioOutputStream *>(userdata);
839 instance->OnWriteCallback(buffer_space);
842 void OnWriteCallback(size_t buffer_space) {
843 temp_buffer_space_ = buffer_space;
844 // Since we write the data asynchronously on a different thread, we have
845 // to temporarily disable the write callback or else Pulse will call it
846 // continuously until we write the data. We re-enable it below.
847 DisableWriteCallback();
851 // Inherited from Worker.
852 virtual void OnStart() {
854 EnableWriteCallback();
858 // Inherited from Worker.
859 virtual void OnHaveWork() {
860 ASSERT(temp_buffer_space_ > 0);
862 SignalBufferSpace(temp_buffer_space_, this);
864 temp_buffer_space_ = 0;
866 EnableWriteCallback();
870 // Inherited from Worker.
871 virtual void OnStop() {
873 DisableWriteCallback();
877 static void UnderflowCallbackThunk(pa_stream *unused,
879 PulseAudioOutputStream *instance =
880 static_cast<PulseAudioOutputStream *>(userdata);
881 instance->OnUnderflowCallback();
884 void OnUnderflowCallback() {
885 LOG(LS_WARNING) << "Buffer underflow on playback stream "
888 if (configured_latency_ == SoundSystemInterface::kNoLatencyRequirements) {
889 // We didn't configure a pa_buffer_attr before, so switching to one now
890 // would be questionable.
894 // Otherwise reconfigure the stream with a higher target latency.
896 const pa_sample_spec *spec = symbol_table()->pa_stream_get_sample_spec()(
899 LOG(LS_ERROR) << "pa_stream_get_sample_spec()";
903 size_t bytes_per_sec = symbol_table()->pa_bytes_per_second()(spec);
905 int new_latency = configured_latency_ +
906 bytes_per_sec * kPlaybackLatencyIncrementMsecs /
907 rtc::kNumMicrosecsPerSec;
909 pa_buffer_attr new_attr = {0};
910 FillPlaybackBufferAttr(new_latency, &new_attr);
912 pa_operation *op = symbol_table()->pa_stream_set_buffer_attr()(
919 LOG(LS_ERROR) << "pa_stream_set_buffer_attr()";
922 // Don't need to wait for this to complete.
923 symbol_table()->pa_operation_unref()(op);
925 // Save the new latency in case we underflow again.
926 configured_latency_ = new_latency;
929 static void GetVolumeCallbackThunk(pa_context *unused,
930 const pa_sink_input_info *info,
933 GetVolumeCallbackData *data =
934 static_cast<GetVolumeCallbackData *>(userdata);
935 data->instance->OnGetVolumeCallback(info, eol, &data->channel_volumes);
938 void OnGetVolumeCallback(const pa_sink_input_info *info,
940 pa_cvolume **channel_volumes) {
942 // List is over. Wake GetVolume().
943 stream_.pulse()->Signal();
947 if (*channel_volumes) {
948 **channel_volumes = info->volume;
949 // Unset the pointer so that we know that we have have already copied the
951 *channel_volumes = NULL;
953 // We have received an additional callback after the first one, which
954 // doesn't make sense for a single sink input. This probably never
955 // happens, but we code for it anyway.
956 LOG(LS_WARNING) << "Ignoring extra GetVolumeCallback";
960 static void SetVolumeCallback(pa_context *unused1,
964 LOG(LS_ERROR) << "Failed to change playback volume";
968 PulseAudioStream stream_;
969 int configured_latency_;
970 // Temporary storage for passing data between threads.
971 size_t temp_buffer_space_;
973 DISALLOW_COPY_AND_ASSIGN(PulseAudioOutputStream);
976 PulseAudioSoundSystem::PulseAudioSoundSystem()
977 : mainloop_(NULL), context_(NULL) {
980 PulseAudioSoundSystem::~PulseAudioSoundSystem() {
984 bool PulseAudioSoundSystem::Init() {
985 if (IsInitialized()) {
990 if (!symbol_table_.Load()) {
991 // Most likely the Pulse library and sound server are not installed on
993 LOG(LS_WARNING) << "Failed to load symbol table";
997 // Now create and start the Pulse event thread.
998 mainloop_ = symbol_table_.pa_threaded_mainloop_new()();
1000 LOG(LS_ERROR) << "Can't create mainloop";
1004 if (symbol_table_.pa_threaded_mainloop_start()(mainloop_) != 0) {
1005 LOG(LS_ERROR) << "Can't start mainloop";
1010 context_ = CreateNewConnection();
1017 // Otherwise we're now ready!
1021 symbol_table_.pa_threaded_mainloop_stop()(mainloop_);
1023 symbol_table_.pa_threaded_mainloop_free()(mainloop_);
1029 void PulseAudioSoundSystem::Terminate() {
1030 if (!IsInitialized()) {
1035 symbol_table_.pa_context_disconnect()(context_);
1036 symbol_table_.pa_context_unref()(context_);
1039 symbol_table_.pa_threaded_mainloop_stop()(mainloop_);
1040 symbol_table_.pa_threaded_mainloop_free()(mainloop_);
1043 // We do not unload the symbol table because we may need it again soon if
1044 // Init() is called again.
1047 bool PulseAudioSoundSystem::EnumeratePlaybackDevices(
1048 SoundDeviceLocatorList *devices) {
1049 return EnumerateDevices<pa_sink_info>(
1051 symbol_table_.pa_context_get_sink_info_list(),
1052 &EnumeratePlaybackDevicesCallbackThunk);
1055 bool PulseAudioSoundSystem::EnumerateCaptureDevices(
1056 SoundDeviceLocatorList *devices) {
1057 return EnumerateDevices<pa_source_info>(
1059 symbol_table_.pa_context_get_source_info_list(),
1060 &EnumerateCaptureDevicesCallbackThunk);
1063 bool PulseAudioSoundSystem::GetDefaultPlaybackDevice(
1064 SoundDeviceLocator **device) {
1065 return GetDefaultDevice<&pa_server_info::default_sink_name>(device);
1068 bool PulseAudioSoundSystem::GetDefaultCaptureDevice(
1069 SoundDeviceLocator **device) {
1070 return GetDefaultDevice<&pa_server_info::default_source_name>(device);
1073 SoundOutputStreamInterface *PulseAudioSoundSystem::OpenPlaybackDevice(
1074 const SoundDeviceLocator *device,
1075 const OpenParams ¶ms) {
1076 return OpenDevice<SoundOutputStreamInterface>(
1080 &PulseAudioSoundSystem::ConnectOutputStream);
1083 SoundInputStreamInterface *PulseAudioSoundSystem::OpenCaptureDevice(
1084 const SoundDeviceLocator *device,
1085 const OpenParams ¶ms) {
1086 return OpenDevice<SoundInputStreamInterface>(
1090 &PulseAudioSoundSystem::ConnectInputStream);
1093 const char *PulseAudioSoundSystem::GetName() const {
1094 return "PulseAudio";
1097 inline bool PulseAudioSoundSystem::IsInitialized() {
1098 return mainloop_ != NULL;
1101 struct ConnectToPulseCallbackData {
1102 PulseAudioSoundSystem *instance;
1106 void PulseAudioSoundSystem::ConnectToPulseCallbackThunk(
1107 pa_context *context, void *userdata) {
1108 ConnectToPulseCallbackData *data =
1109 static_cast<ConnectToPulseCallbackData *>(userdata);
1110 data->instance->OnConnectToPulseCallback(context, &data->connect_done);
1113 void PulseAudioSoundSystem::OnConnectToPulseCallback(
1114 pa_context *context, bool *connect_done) {
1115 pa_context_state_t state = symbol_table_.pa_context_get_state()(context);
1116 if (state == PA_CONTEXT_READY ||
1117 state == PA_CONTEXT_FAILED ||
1118 state == PA_CONTEXT_TERMINATED) {
1119 // Connection process has reached a terminal state. Wake ConnectToPulse().
1120 *connect_done = true;
1125 // Must be called with the lock held.
1126 bool PulseAudioSoundSystem::ConnectToPulse(pa_context *context) {
1128 ConnectToPulseCallbackData data;
1129 // Have to put this up here to satisfy the compiler.
1130 pa_context_state_t state;
1132 data.instance = this;
1133 data.connect_done = false;
1135 symbol_table_.pa_context_set_state_callback()(context,
1136 &ConnectToPulseCallbackThunk,
1139 // Connect to PulseAudio sound server.
1140 if (symbol_table_.pa_context_connect()(
1142 NULL, // Default server
1143 PA_CONTEXT_NOAUTOSPAWN,
1144 NULL) != 0) { // No special fork handling needed
1145 LOG(LS_ERROR) << "Can't start connection to PulseAudio sound server";
1150 // Wait for the connection state machine to reach a terminal state.
1153 } while (!data.connect_done);
1155 // Now check to see what final state we reached.
1156 state = symbol_table_.pa_context_get_state()(context);
1158 if (state != PA_CONTEXT_READY) {
1159 if (state == PA_CONTEXT_FAILED) {
1160 LOG(LS_ERROR) << "Failed to connect to PulseAudio sound server";
1161 } else if (state == PA_CONTEXT_TERMINATED) {
1162 LOG(LS_ERROR) << "PulseAudio connection terminated early";
1164 // Shouldn't happen, because we only signal on one of those three states.
1165 LOG(LS_ERROR) << "Unknown problem connecting to PulseAudio";
1171 // We unset our callback for safety just in case the state might somehow
1172 // change later, because the pointer to "data" will be invalid after return
1173 // from this function.
1174 symbol_table_.pa_context_set_state_callback()(context, NULL, NULL);
1178 // Must be called with the lock held.
1179 pa_context *PulseAudioSoundSystem::CreateNewConnection() {
1180 // Create connection context.
1181 std::string app_name;
1182 // TODO: Pulse etiquette says this name should be localized. Do
1184 rtc::Filesystem::GetApplicationName(&app_name);
1185 pa_context *context = symbol_table_.pa_context_new()(
1186 symbol_table_.pa_threaded_mainloop_get_api()(mainloop_),
1189 LOG(LS_ERROR) << "Can't create context";
1194 if (!ConnectToPulse(context)) {
1198 // Otherwise the connection succeeded and is ready.
1202 symbol_table_.pa_context_unref()(context);
1207 struct EnumerateDevicesCallbackData {
1208 PulseAudioSoundSystem *instance;
1209 SoundSystemInterface::SoundDeviceLocatorList *devices;
1212 void PulseAudioSoundSystem::EnumeratePlaybackDevicesCallbackThunk(
1214 const pa_sink_info *info,
1217 EnumerateDevicesCallbackData *data =
1218 static_cast<EnumerateDevicesCallbackData *>(userdata);
1219 data->instance->OnEnumeratePlaybackDevicesCallback(data->devices, info, eol);
1222 void PulseAudioSoundSystem::EnumerateCaptureDevicesCallbackThunk(
1224 const pa_source_info *info,
1227 EnumerateDevicesCallbackData *data =
1228 static_cast<EnumerateDevicesCallbackData *>(userdata);
1229 data->instance->OnEnumerateCaptureDevicesCallback(data->devices, info, eol);
1232 void PulseAudioSoundSystem::OnEnumeratePlaybackDevicesCallback(
1233 SoundDeviceLocatorList *devices,
1234 const pa_sink_info *info,
1237 // List is over. Wake EnumerateDevices().
1242 // Else this is the next device.
1244 new PulseAudioDeviceLocator(info->description, info->name));
1247 void PulseAudioSoundSystem::OnEnumerateCaptureDevicesCallback(
1248 SoundDeviceLocatorList *devices,
1249 const pa_source_info *info,
1252 // List is over. Wake EnumerateDevices().
1257 if (info->monitor_of_sink != PA_INVALID_INDEX) {
1258 // We don't want to list monitor sources, since they are almost certainly
1259 // not what the user wants for voice conferencing.
1263 // Else this is the next device.
1265 new PulseAudioDeviceLocator(info->description, info->name));
1268 template <typename InfoStruct>
1269 bool PulseAudioSoundSystem::EnumerateDevices(
1270 SoundDeviceLocatorList *devices,
1271 pa_operation *(*enumerate_fn)(
1273 void (*callback_fn)(
1275 const InfoStruct *i,
1279 void (*callback_fn)(
1281 const InfoStruct *i,
1284 ClearSoundDeviceLocatorList(devices);
1285 if (!IsInitialized()) {
1289 EnumerateDevicesCallbackData data;
1290 data.instance = this;
1291 data.devices = devices;
1294 pa_operation *op = (*enumerate_fn)(
1298 bool ret = FinishOperation(op);
1303 struct GetDefaultDeviceCallbackData {
1304 PulseAudioSoundSystem *instance;
1305 SoundDeviceLocator **device;
1308 template <const char *(pa_server_info::*field)>
1309 void PulseAudioSoundSystem::GetDefaultDeviceCallbackThunk(
1311 const pa_server_info *info,
1313 GetDefaultDeviceCallbackData *data =
1314 static_cast<GetDefaultDeviceCallbackData *>(userdata);
1315 data->instance->OnGetDefaultDeviceCallback<field>(info, data->device);
1318 template <const char *(pa_server_info::*field)>
1319 void PulseAudioSoundSystem::OnGetDefaultDeviceCallback(
1320 const pa_server_info *info,
1321 SoundDeviceLocator **device) {
1323 const char *dev = info->*field;
1325 *device = new PulseAudioDeviceLocator("Default device", dev);
1331 template <const char *(pa_server_info::*field)>
1332 bool PulseAudioSoundSystem::GetDefaultDevice(SoundDeviceLocator **device) {
1333 if (!IsInitialized()) {
1338 GetDefaultDeviceCallbackData data;
1339 data.instance = this;
1340 data.device = device;
1342 pa_operation *op = symbol_table_.pa_context_get_server_info()(
1344 &GetDefaultDeviceCallbackThunk<field>,
1346 ret = FinishOperation(op);
1348 return ret && (*device != NULL);
1351 void PulseAudioSoundSystem::StreamStateChangedCallbackThunk(
1354 PulseAudioSoundSystem *instance =
1355 static_cast<PulseAudioSoundSystem *>(userdata);
1356 instance->OnStreamStateChangedCallback(stream);
1359 void PulseAudioSoundSystem::OnStreamStateChangedCallback(pa_stream *stream) {
1360 pa_stream_state_t state = symbol_table_.pa_stream_get_state()(stream);
1361 if (state == PA_STREAM_READY) {
1362 LOG(LS_INFO) << "Pulse stream " << stream << " ready";
1363 } else if (state == PA_STREAM_FAILED ||
1364 state == PA_STREAM_TERMINATED ||
1365 state == PA_STREAM_UNCONNECTED) {
1366 LOG(LS_ERROR) << "Pulse stream " << stream << " failed to connect: "
1371 template <typename StreamInterface>
1372 StreamInterface *PulseAudioSoundSystem::OpenDevice(
1373 const SoundDeviceLocator *device,
1374 const OpenParams ¶ms,
1375 const char *stream_name,
1376 StreamInterface *(PulseAudioSoundSystem::*connect_fn)(
1380 pa_stream_flags_t pa_flags,
1382 const pa_sample_spec &spec)) {
1383 if (!IsInitialized()) {
1387 const char *dev = static_cast<const PulseAudioDeviceLocator *>(device)->
1388 device_name().c_str();
1390 StreamInterface *stream_interface = NULL;
1392 ASSERT(params.format < ARRAY_SIZE(kCricketFormatToPulseFormatTable));
1394 pa_sample_spec spec;
1395 spec.format = kCricketFormatToPulseFormatTable[params.format];
1396 spec.rate = params.freq;
1397 spec.channels = params.channels;
1400 if (params.flags & FLAG_REPORT_LATENCY) {
1401 pa_flags |= PA_STREAM_INTERPOLATE_TIMING |
1402 PA_STREAM_AUTO_TIMING_UPDATE;
1405 if (params.latency != kNoLatencyRequirements) {
1406 // If configuring a specific latency then we want to specify
1407 // PA_STREAM_ADJUST_LATENCY to make the server adjust parameters
1408 // automatically to reach that target latency. However, that flag doesn't
1409 // exist in Ubuntu 8.04 and many people still use that, so we have to check
1410 // the protocol version of libpulse.
1411 if (symbol_table_.pa_context_get_protocol_version()(context_) >=
1412 kAdjustLatencyProtocolVersion) {
1413 pa_flags |= PA_STREAM_ADJUST_LATENCY;
1419 pa_stream *stream = symbol_table_.pa_stream_new()(context_, stream_name,
1422 LOG(LS_ERROR) << "Can't create pa_stream";
1426 // Set a state callback to log errors.
1427 symbol_table_.pa_stream_set_state_callback()(stream,
1428 &StreamStateChangedCallbackThunk,
1431 stream_interface = (this->*connect_fn)(
1435 static_cast<pa_stream_flags_t>(pa_flags),
1438 if (!stream_interface) {
1439 LOG(LS_ERROR) << "Can't connect stream to " << dev;
1440 symbol_table_.pa_stream_unref()(stream);
1445 return stream_interface;
1448 // Must be called with the lock held.
1449 SoundOutputStreamInterface *PulseAudioSoundSystem::ConnectOutputStream(
1453 pa_stream_flags_t pa_flags,
1455 const pa_sample_spec &spec) {
1456 pa_buffer_attr attr = {0};
1457 pa_buffer_attr *pattr = NULL;
1458 if (latency != kNoLatencyRequirements) {
1459 // kLowLatency is 0, so we treat it the same as a request for zero latency.
1460 ssize_t bytes_per_sec = symbol_table_.pa_bytes_per_second()(&spec);
1461 latency = rtc::_max(
1464 bytes_per_sec * kPlaybackLatencyMinimumMsecs /
1465 rtc::kNumMicrosecsPerSec));
1466 FillPlaybackBufferAttr(latency, &attr);
1469 if (symbol_table_.pa_stream_connect_playback()(
1474 // Let server choose volume
1476 // Not synchronized to any other playout
1480 return new PulseAudioOutputStream(this, stream, flags, latency);
1483 // Must be called with the lock held.
1484 SoundInputStreamInterface *PulseAudioSoundSystem::ConnectInputStream(
1488 pa_stream_flags_t pa_flags,
1490 const pa_sample_spec &spec) {
1491 pa_buffer_attr attr = {0};
1492 pa_buffer_attr *pattr = NULL;
1493 if (latency != kNoLatencyRequirements) {
1494 size_t bytes_per_sec = symbol_table_.pa_bytes_per_second()(&spec);
1495 if (latency == kLowLatency) {
1496 latency = bytes_per_sec * kLowCaptureLatencyMsecs /
1497 rtc::kNumMicrosecsPerSec;
1499 // Note: fragsize specifies a maximum transfer size, not a minimum, so it is
1500 // not possible to force a high latency setting, only a low one.
1501 attr.fragsize = latency;
1502 attr.maxlength = latency + bytes_per_sec * kCaptureBufferExtraMsecs /
1503 rtc::kNumMicrosecsPerSec;
1504 LOG(LS_VERBOSE) << "Configuring latency = " << attr.fragsize
1505 << ", maxlength = " << attr.maxlength;
1508 if (symbol_table_.pa_stream_connect_record()(stream,
1514 return new PulseAudioInputStream(this, stream, flags);
1517 // Must be called with the lock held.
1518 bool PulseAudioSoundSystem::FinishOperation(pa_operation *op) {
1520 LOG(LS_ERROR) << "Failed to start operation";
1526 } while (symbol_table_.pa_operation_get_state()(op) == PA_OPERATION_RUNNING);
1528 symbol_table_.pa_operation_unref()(op);
1533 inline void PulseAudioSoundSystem::Lock() {
1534 symbol_table_.pa_threaded_mainloop_lock()(mainloop_);
1537 inline void PulseAudioSoundSystem::Unlock() {
1538 symbol_table_.pa_threaded_mainloop_unlock()(mainloop_);
1541 // Must be called with the lock held.
1542 inline void PulseAudioSoundSystem::Wait() {
1543 symbol_table_.pa_threaded_mainloop_wait()(mainloop_);
1546 // Must be called with the lock held.
1547 inline void PulseAudioSoundSystem::Signal() {
1548 symbol_table_.pa_threaded_mainloop_signal()(mainloop_, 0);
1551 // Must be called with the lock held.
1552 const char *PulseAudioSoundSystem::LastError() {
1553 return symbol_table_.pa_strerror()(symbol_table_.pa_context_errno()(
1557 } // namespace cricket
1559 #endif // HAVE_LIBPULSE