Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
pulseaudio_sink.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Roc authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_sink.h
10 //! @brief PulseAudio sink.
11 
12 #ifndef ROC_SNDIO_PULSEAUDIO_SINK_H_
13 #define ROC_SNDIO_PULSEAUDIO_SINK_H_
14 
15 #include <pulse/pulseaudio.h>
16 
17 #include "roc_core/noncopyable.h"
18 #include "roc_core/rate_limiter.h"
19 #include "roc_core/stddefs.h"
20 #include "roc_packet/units.h"
21 #include "roc_sndio/config.h"
22 #include "roc_sndio/isink.h"
23 
24 namespace roc {
25 namespace sndio {
26 
27 //! PulseAudio sink,
28 class PulseaudioSink : public ISink, public core::NonCopyable<> {
29 public:
30  //! Initialize.
31  PulseaudioSink(const Config& config);
32 
33  ~PulseaudioSink();
34 
35  //! Open output device.
36  bool open(const char* device);
37 
38  //! Get sample rate of the sink.
39  virtual size_t sample_rate() const;
40 
41  //! Check if the sink has own clock.
42  virtual bool has_clock() const;
43 
44  //! Write audio frame.
45  virtual void write(audio::Frame& frame);
46 
47 private:
48  static void context_state_cb_(pa_context* context, void* userdata);
49 
50  static void
51  sink_info_cb_(pa_context* context, const pa_sink_info* info, int eol, void* userdata);
52 
53  static void stream_state_cb_(pa_stream* stream, void* userdata);
54  static void stream_write_cb_(pa_stream* stream, size_t length, void* userdata);
55  static void stream_latency_cb_(pa_stream* stream, void* userdata);
56 
57  static void timer_cb_(pa_mainloop_api* mainloop,
58  pa_time_event* timer,
59  const struct timeval* tv,
60  void* userdata);
61 
62  bool write_frame_(audio::Frame& frame);
63 
64  bool check_params_() const;
65 
66  void ensure_started_() const;
67  void ensure_opened_() const;
68 
69  bool start_mainloop_();
70  void stop_mainloop_();
71 
72  bool open_();
73  void close_();
74  void set_opened_(bool opened);
75 
76  bool open_context_();
77  void close_context_();
78 
79  bool start_sink_info_op_();
80  void cancel_sink_info_op_();
81 
82  void init_stream_params_(const pa_sink_info& info);
83  bool open_stream_();
84  void close_stream_();
85  ssize_t write_stream_(const audio::sample_t* data, size_t size);
86  ssize_t wait_stream_();
87 
88  void start_timer_(core::nanoseconds_t timeout);
89  bool stop_timer_();
90 
91  const char* device_;
92  size_t sample_rate_;
93  const size_t num_channels_;
94  const size_t frame_size_;
95 
96  core::nanoseconds_t latency_;
97  core::nanoseconds_t timeout_;
98 
99  bool open_done_;
100  bool opened_;
101 
102  pa_threaded_mainloop* mainloop_;
103  pa_context* context_;
104  pa_operation* sink_info_op_;
105  pa_stream* stream_;
106  pa_time_event* timer_;
107 
108  core::nanoseconds_t timer_deadline_;
109 
110  pa_sample_spec sample_spec_;
111  pa_buffer_attr buffer_attrs_;
112 
113  core::RateLimiter rate_limiter_;
114 };
115 
116 } // namespace sndio
117 } // namespace roc
118 
119 #endif // ROC_SNDIO_PULSEAUDIO_SINK_H_
Sink interface.
Definition: isink.h:21
Sink interface.
PulseaudioSink(const Config &config)
Initialize.
Rate limiter.
Definition: rate_limiter.h:22
Root namespace.
virtual bool has_clock() const
Check if the sink has own clock.
float sample_t
Audio sample.
Definition: units.h:21
Rate limiter.
Sink and source config.
int64_t nanoseconds_t
Nanoseconds.
Definition: time.h:21
Audio frame.
Definition: frame.h:22
Commonly used types and functions.
Sink and source config.
Definition: config.h:22
Base class for non-copyable objects.
Definition: noncopyable.h:23
virtual void write(audio::Frame &frame)
Write audio frame.
bool open(const char *device)
Open output device.
Various units used in packets.
Non-copyable object.
virtual size_t sample_rate() const
Get sample rate of the sink.