Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
pulseaudio_device.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Roc Streaming 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_device.h
10 //! @brief PulseAudio device.
11 
12 #ifndef ROC_SNDIO_PULSEAUDIO_DEVICE_H_
13 #define ROC_SNDIO_PULSEAUDIO_DEVICE_H_
14 
15 #include <pulse/pulseaudio.h>
16 
17 #include "roc_audio/frame.h"
18 #include "roc_core/noncopyable.h"
19 #include "roc_core/rate_limiter.h"
20 #include "roc_core/stddefs.h"
21 #include "roc_core/time.h"
22 #include "roc_packet/units.h"
23 #include "roc_sndio/config.h"
24 #include "roc_sndio/device_state.h"
25 #include "roc_sndio/device_type.h"
26 
27 namespace roc {
28 namespace sndio {
29 
30 //! PulseAudio device.
31 //! Base class for PulseAudio source and sink.
33 public:
34  //! Open output device.
35  bool open(const char* device);
36 
37 protected:
38  //! Initialize.
39  PulseaudioDevice(const Config& config, DeviceType device_type);
41 
42  //! Get device state.
43  DeviceState state() const;
44 
45  //! Pause reading.
46  void pause();
47 
48  //! Resume paused reading.
49  bool resume();
50 
51  //! Restart reading from the beginning.
52  bool restart();
53 
54  //! Get sample specification of the sink.
56 
57  //! Get latency of the sink.
59 
60  //! Process audio frame.
61  bool request(audio::Frame& frame);
62 
63 private:
64  static void context_state_cb_(pa_context* context, void* userdata);
65 
66  static void
67  device_info_cb_(pa_context* context, const void* info, int eol, void* userdata);
68 
69  static void stream_state_cb_(pa_stream* stream, void* userdata);
70  static void stream_request_cb_(pa_stream* stream, size_t length, void* userdata);
71 
72  static void timer_cb_(pa_mainloop_api* mainloop,
73  pa_time_event* timer,
74  const struct timeval* tv,
75  void* userdata);
76 
77  bool request_frame_(audio::Frame& frame);
78 
79  void want_mainloop_() const;
80  bool start_mainloop_();
81  void stop_mainloop_();
82 
83  bool open_();
84  void close_();
85  void set_opened_(bool opened);
86 
87  bool open_context_();
88  void close_context_();
89 
90  bool start_device_info_op_();
91  void cancel_device_info_op_();
92 
93  void init_stream_params_(const pa_sample_spec& device_sample_spec);
94  bool check_stream_params_() const;
95  bool open_stream_();
96  void close_stream_();
97  ssize_t request_stream_(audio::sample_t* data, size_t size);
98  ssize_t write_stream_(const audio::sample_t* data, size_t size);
99  ssize_t read_stream_(audio::sample_t* data, size_t size);
100  ssize_t wait_stream_();
101 
102  bool get_latency_(core::nanoseconds_t& latency) const;
103  void report_latency_();
104 
105  void start_timer_(core::nanoseconds_t timeout);
106  bool stop_timer_();
107 
108  const DeviceType device_type_;
109  const char* device_;
110 
111  Config config_;
112  size_t frame_size_;
113 
114  const audio::sample_t* record_frag_data_;
115  size_t record_frag_size_;
116  bool record_frag_flag_;
117 
118  core::nanoseconds_t target_latency_;
119  core::nanoseconds_t timeout_;
120 
121  bool open_done_;
122  bool opened_;
123 
124  pa_threaded_mainloop* mainloop_;
125  pa_context* context_;
126  pa_operation* device_info_op_;
127  pa_stream* stream_;
128  pa_time_event* timer_;
129 
130  core::nanoseconds_t timer_deadline_;
131 
132  pa_sample_spec sample_spec_;
133  pa_buffer_attr buffer_attrs_;
134 
135  core::RateLimiter rate_limiter_;
136 };
137 
138 } // namespace sndio
139 } // namespace roc
140 
141 #endif // ROC_SNDIO_PULSEAUDIO_DEVICE_H_
Audio frame.
Definition: frame.h:25
Sample specification. Describes sample rate and channels.
Definition: sample_spec.h:26
Base class for non-copyable objects.
Definition: noncopyable.h:23
PulseAudio device. Base class for PulseAudio source and sink.
DeviceState state() const
Get device state.
void pause()
Pause reading.
audio::SampleSpec sample_spec() const
Get sample specification of the sink.
core::nanoseconds_t latency() const
Get latency of the sink.
bool open(const char *device)
Open output device.
bool restart()
Restart reading from the beginning.
PulseaudioDevice(const Config &config, DeviceType device_type)
Initialize.
bool resume()
Resume paused reading.
bool request(audio::Frame &frame)
Process audio frame.
Device state.
Device type.
Audio frame.
float sample_t
Audio sample.
Definition: sample.h:22
int64_t nanoseconds_t
Nanoseconds.
Definition: time.h:58
DeviceType
Device type.
Definition: device_type.h:19
DeviceState
Device state.
Definition: device_state.h:19
Root namespace.
Non-copyable object.
Rate limiter.
Sink and source config.
Commonly used types and functions.
Sink and source config.
Definition: config.h:29
Time definitions.
Various units used in packets.