1 // Copyright 2017 Lyndon Brown
2 //
3 // This file is part of the PulseAudio Rust language linking library.
4 //
5 // Licensed under the MIT license or the Apache license (version 2.0), at your option. You may not
6 // copy, modify, or distribute this file except in compliance with said license. You can find copies
7 // of these licenses either in the LICENSE-MIT and LICENSE-APACHE files, or alternatively at
8 // <http://opensource.org/licenses/MIT> and <http://www.apache.org/licenses/LICENSE-2.0>
9 // respectively.
10 //
11 // Portions of documentation are copied from the LGPL 2.1+ licensed PulseAudio C headers on a
12 // fair-use basis, as discussed in the overall project readme (available in the git repository).
13 
14 //! Audio streams for input, output and sample upload.
15 
16 use std::os::raw::{c_char, c_void};
17 use num_derive::{FromPrimitive, ToPrimitive};
18 use crate::sample::{pa_sample_spec, pa_usec_t};
19 use crate::def::{pa_buffer_attr, pa_timing_info, pa_free_cb_t};
20 use crate::proplist::{pa_proplist, pa_update_mode_t};
21 use crate::{context::pa_context, channelmap::pa_channel_map, format::pa_format_info};
22 use crate::{volume::pa_cvolume, operation::pa_operation};
23 
24 /// An opaque stream for playback or recording.
25 #[repr(C)] pub struct pa_stream { _private: [u8; 0] }
26 
27 #[repr(C)]
28 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
29 #[derive(FromPrimitive, ToPrimitive)]
30 pub enum pa_stream_state_t {
31     Unconnected,
32     Creating,
33     Ready,
34     Failed,
35     Terminated,
36 }
37 
38 pub const PA_STREAM_UNCONNECTED: pa_stream_state_t = pa_stream_state_t::Unconnected;
39 pub const PA_STREAM_CREATING:    pa_stream_state_t = pa_stream_state_t::Creating;
40 pub const PA_STREAM_READY:       pa_stream_state_t = pa_stream_state_t::Ready;
41 pub const PA_STREAM_FAILED:      pa_stream_state_t = pa_stream_state_t::Failed;
42 pub const PA_STREAM_TERMINATED:  pa_stream_state_t = pa_stream_state_t::Terminated;
43 
44 /// Checks if the passed state is one of the connected states (returns `true` if so).
45 #[inline(always)]
pa_stream_is_good(state: pa_stream_state_t) -> bool46 pub fn pa_stream_is_good(state: pa_stream_state_t) -> bool {
47     state == pa_stream_state_t::Creating || state == pa_stream_state_t::Ready
48 }
49 
50 /// Stream direction.
51 #[repr(C)]
52 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
53 #[derive(FromPrimitive, ToPrimitive)]
54 pub enum pa_stream_direction_t {
55     /// Invalid.
56     Invalid,
57     /// Playback.
58     Playback,
59     /// Record.
60     Record,
61     /// Upload.
62     Upload,
63 }
64 
65 pub const PA_STREAM_NODIRECTION: pa_stream_direction_t = pa_stream_direction_t::Invalid;
66 pub const PA_STREAM_PLAYBACK:    pa_stream_direction_t = pa_stream_direction_t::Playback;
67 pub const PA_STREAM_RECORD:      pa_stream_direction_t = pa_stream_direction_t::Record;
68 pub const PA_STREAM_UPLOAD:      pa_stream_direction_t = pa_stream_direction_t::Upload;
69 
70 pub type pa_stream_flags_t = u32;
71 
72 pub use self::flags::*;
73 
74 /// Some special flags for stream connections.
75 pub mod flags {
76     use super::pa_stream_flags_t;
77 
78     pub const PA_STREAM_NOFLAGS:                   pa_stream_flags_t = 0;
79     pub const PA_STREAM_START_CORKED:              pa_stream_flags_t = 1 << 0;
80     pub const PA_STREAM_INTERPOLATE_TIMING:        pa_stream_flags_t = 1 << 1;
81     pub const PA_STREAM_NOT_MONOTONIC:             pa_stream_flags_t = 1 << 2;
82     pub const PA_STREAM_AUTO_TIMING_UPDATE:        pa_stream_flags_t = 1 << 3;
83     pub const PA_STREAM_NO_REMAP_CHANNELS:         pa_stream_flags_t = 1 << 4;
84     pub const PA_STREAM_NO_REMIX_CHANNELS:         pa_stream_flags_t = 1 << 5;
85     pub const PA_STREAM_FIX_FORMAT:                pa_stream_flags_t = 1 << 6;
86     pub const PA_STREAM_FIX_RATE:                  pa_stream_flags_t = 1 << 7;
87     pub const PA_STREAM_FIX_CHANNELS:              pa_stream_flags_t = 1 << 8;
88     pub const PA_STREAM_DONT_MOVE:                 pa_stream_flags_t = 1 << 9;
89     pub const PA_STREAM_VARIABLE_RATE:             pa_stream_flags_t = 1 << 10;
90     pub const PA_STREAM_PEAK_DETECT:               pa_stream_flags_t = 1 << 11;
91     pub const PA_STREAM_START_MUTED:               pa_stream_flags_t = 1 << 12;
92     pub const PA_STREAM_ADJUST_LATENCY:            pa_stream_flags_t = 1 << 13;
93     pub const PA_STREAM_EARLY_REQUESTS:            pa_stream_flags_t = 1 << 14;
94     pub const PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND: pa_stream_flags_t = 1 << 15;
95     pub const PA_STREAM_START_UNMUTED:             pa_stream_flags_t = 1 << 16;
96     pub const PA_STREAM_FAIL_ON_SUSPEND:           pa_stream_flags_t = 1 << 17;
97     pub const PA_STREAM_RELATIVE_VOLUME:           pa_stream_flags_t = 1 << 18;
98     pub const PA_STREAM_PASSTHROUGH:               pa_stream_flags_t = 1 << 19;
99 }
100 
101 /// Seek mode.
102 #[repr(C)]
103 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
104 #[derive(FromPrimitive, ToPrimitive)]
105 pub enum pa_seek_mode_t {
106     /// Seek relatively to the write index.
107     Relative = 0,
108     /// Seek relatively to the start of the buffer queue.
109     Absolute = 1,
110     /// Seek relatively to the read index.
111     RelativeOnRead = 2,
112     /// Seek relatively to the current end of the buffer queue.
113     RelativeEnd = 3,
114 }
115 
116 pub const PA_SEEK_RELATIVE:         pa_seek_mode_t = pa_seek_mode_t::Relative;
117 pub const PA_SEEK_ABSOLUTE:         pa_seek_mode_t = pa_seek_mode_t::Absolute;
118 pub const PA_SEEK_RELATIVE_ON_READ: pa_seek_mode_t = pa_seek_mode_t::RelativeOnRead;
119 pub const PA_SEEK_RELATIVE_END:     pa_seek_mode_t = pa_seek_mode_t::RelativeEnd;
120 
121 pub const PA_STREAM_EVENT_REQUEST_CORK:   &str = "request-cork";
122 pub const PA_STREAM_EVENT_REQUEST_UNCORK: &str = "request-uncork";
123 pub const PA_STREAM_EVENT_FORMAT_LOST:    &str = "format-lost";
124 
125 #[rustfmt::skip]
126 pub type pa_stream_success_cb_t = Option<extern "C" fn(s: *mut pa_stream, success: i32, userdata: *mut c_void)>;
127 
128 #[rustfmt::skip]
129 pub type pa_stream_request_cb_t = Option<extern "C" fn(p: *mut pa_stream, nbytes: usize, userdata: *mut c_void)>;
130 
131 #[rustfmt::skip]
132 pub type pa_stream_notify_cb_t = Option<extern "C" fn(p: *mut pa_stream, userdata: *mut c_void)>;
133 
134 #[rustfmt::skip]
135 pub type pa_stream_event_cb_t = Option<extern "C" fn(p: *mut pa_stream, name: *const c_char, pl: *mut pa_proplist, userdata: *mut c_void)>;
136 
137 #[rustfmt::skip]
138 #[link(name = "pulse")]
139 extern "C" {
pa_stream_connect_upload(s: *mut pa_stream, length: usize) -> i32140     pub fn pa_stream_connect_upload(s: *mut pa_stream, length: usize) -> i32;
pa_stream_finish_upload(s: *mut pa_stream) -> i32141     pub fn pa_stream_finish_upload(s: *mut pa_stream) -> i32;
142 
pa_stream_new(c: *mut pa_context, name: *const c_char, ss: *const pa_sample_spec, map: *const pa_channel_map) -> *mut pa_stream143     pub fn pa_stream_new(c: *mut pa_context, name: *const c_char, ss: *const pa_sample_spec, map: *const pa_channel_map) -> *mut pa_stream;
pa_stream_new_with_proplist(c: *mut pa_context, name: *const c_char, ss: *const pa_sample_spec, map: *const pa_channel_map, p: *mut pa_proplist) -> *mut pa_stream144     pub fn pa_stream_new_with_proplist(c: *mut pa_context, name: *const c_char, ss: *const pa_sample_spec, map: *const pa_channel_map, p: *mut pa_proplist) -> *mut pa_stream;
pa_stream_new_extended(c: *mut pa_context, name: *const c_char, formats: *const *const pa_format_info, n_formats: u32, p: *mut pa_proplist) -> *mut pa_stream145     pub fn pa_stream_new_extended(c: *mut pa_context, name: *const c_char, formats: *const *const pa_format_info, n_formats: u32, p: *mut pa_proplist) -> *mut pa_stream;
pa_stream_unref(s: *mut pa_stream)146     pub fn pa_stream_unref(s: *mut pa_stream);
pa_stream_ref(s: *mut pa_stream) -> *mut pa_stream147     pub fn pa_stream_ref(s: *mut pa_stream) -> *mut pa_stream;
pa_stream_get_state(s: *const pa_stream) -> pa_stream_state_t148     pub fn pa_stream_get_state(s: *const pa_stream) -> pa_stream_state_t;
pa_stream_get_context(s: *const pa_stream) -> *mut pa_context149     pub fn pa_stream_get_context(s: *const pa_stream) -> *mut pa_context;
pa_stream_get_index(s: *const pa_stream) -> u32150     pub fn pa_stream_get_index(s: *const pa_stream) -> u32;
pa_stream_get_device_index(s: *const pa_stream) -> u32151     pub fn pa_stream_get_device_index(s: *const pa_stream) -> u32;
pa_stream_get_device_name(s: *const pa_stream) -> *const c_char152     pub fn pa_stream_get_device_name(s: *const pa_stream) -> *const c_char;
pa_stream_is_suspended(s: *const pa_stream) -> i32153     pub fn pa_stream_is_suspended(s: *const pa_stream) -> i32;
pa_stream_is_corked(s: *const pa_stream) -> i32154     pub fn pa_stream_is_corked(s: *const pa_stream) -> i32;
pa_stream_connect_playback(s: *mut pa_stream, dev: *const c_char, attr: *const pa_buffer_attr, flags: pa_stream_flags_t, volume: *const pa_cvolume, sync_stream: *mut pa_stream) -> i32155     pub fn pa_stream_connect_playback(s: *mut pa_stream, dev: *const c_char, attr: *const pa_buffer_attr, flags: pa_stream_flags_t, volume: *const pa_cvolume, sync_stream: *mut pa_stream) -> i32;
pa_stream_connect_record(s: *mut pa_stream, dev: *const c_char, attr: *const pa_buffer_attr, flags: pa_stream_flags_t) -> i32156     pub fn pa_stream_connect_record(s: *mut pa_stream, dev: *const c_char, attr: *const pa_buffer_attr, flags: pa_stream_flags_t) -> i32;
pa_stream_disconnect(s: *mut pa_stream) -> i32157     pub fn pa_stream_disconnect(s: *mut pa_stream) -> i32;
pa_stream_begin_write(s: *mut pa_stream, data: *mut *mut c_void, nbytes: *mut usize) -> i32158     pub fn pa_stream_begin_write(s: *mut pa_stream, data: *mut *mut c_void, nbytes: *mut usize) -> i32;
pa_stream_cancel_write(s: *mut pa_stream) -> i32159     pub fn pa_stream_cancel_write(s: *mut pa_stream) -> i32;
pa_stream_write(s: *mut pa_stream, data: *const c_void, nbytes: usize, free_cb: pa_free_cb_t, offset: i64, seek: pa_seek_mode_t) -> i32160     pub fn pa_stream_write(s: *mut pa_stream, data: *const c_void, nbytes: usize, free_cb: pa_free_cb_t, offset: i64, seek: pa_seek_mode_t) -> i32;
161     #[cfg(any(doc, feature = "pa_v6"))]
162     #[cfg_attr(docsrs, doc(cfg(feature = "pa_v6")))]
pa_stream_write_ext_free(s: *mut pa_stream, data: *const c_void, nbytes: usize, free_cb: pa_free_cb_t, free_cb_data: *mut c_void, offset: i64, seek: pa_seek_mode_t) -> i32163     pub fn pa_stream_write_ext_free(s: *mut pa_stream, data: *const c_void, nbytes: usize, free_cb: pa_free_cb_t, free_cb_data: *mut c_void, offset: i64, seek: pa_seek_mode_t) -> i32;
pa_stream_peek(s: *mut pa_stream, data: *mut *const c_void, nbytes: *mut usize) -> i32164     pub fn pa_stream_peek(s: *mut pa_stream, data: *mut *const c_void, nbytes: *mut usize) -> i32;
pa_stream_drop(s: *mut pa_stream) -> i32165     pub fn pa_stream_drop(s: *mut pa_stream) -> i32;
pa_stream_writable_size(s: *const pa_stream) -> usize166     pub fn pa_stream_writable_size(s: *const pa_stream) -> usize;
pa_stream_readable_size(s: *const pa_stream) -> usize167     pub fn pa_stream_readable_size(s: *const pa_stream) -> usize;
pa_stream_drain(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation168     pub fn pa_stream_drain(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_update_timing_info(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation169     pub fn pa_stream_update_timing_info(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_set_state_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void)170     pub fn pa_stream_set_state_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void);
pa_stream_set_write_callback(s: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void)171     pub fn pa_stream_set_write_callback(s: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void);
pa_stream_set_read_callback(s: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void)172     pub fn pa_stream_set_read_callback(s: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void);
pa_stream_set_overflow_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void)173     pub fn pa_stream_set_overflow_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void);
pa_stream_get_underflow_index(s: *const pa_stream) -> i64174     pub fn pa_stream_get_underflow_index(s: *const pa_stream) -> i64;
pa_stream_set_underflow_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void)175     pub fn pa_stream_set_underflow_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void);
pa_stream_set_started_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void)176     pub fn pa_stream_set_started_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void);
pa_stream_set_latency_update_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void)177     pub fn pa_stream_set_latency_update_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void);
pa_stream_set_moved_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void)178     pub fn pa_stream_set_moved_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void);
pa_stream_set_suspended_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void)179     pub fn pa_stream_set_suspended_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void);
pa_stream_set_event_callback(s: *mut pa_stream, cb: pa_stream_event_cb_t, userdata: *mut c_void)180     pub fn pa_stream_set_event_callback(s: *mut pa_stream, cb: pa_stream_event_cb_t, userdata: *mut c_void);
pa_stream_set_buffer_attr_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void)181     pub fn pa_stream_set_buffer_attr_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void);
pa_stream_cork(s: *mut pa_stream, b: i32, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation182     pub fn pa_stream_cork(s: *mut pa_stream, b: i32, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_flush(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation183     pub fn pa_stream_flush(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_prebuf(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation184     pub fn pa_stream_prebuf(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_trigger(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation185     pub fn pa_stream_trigger(s: *mut pa_stream, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_set_name(s: *mut pa_stream, name: *const c_char, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation186     pub fn pa_stream_set_name(s: *mut pa_stream, name: *const c_char, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_get_time(s: *mut pa_stream, r_usec: *mut pa_usec_t) -> i32187     pub fn pa_stream_get_time(s: *mut pa_stream, r_usec: *mut pa_usec_t) -> i32;
pa_stream_get_latency(s: *mut pa_stream, r_usec: *mut pa_usec_t, negative: *mut i32) -> i32188     pub fn pa_stream_get_latency(s: *mut pa_stream, r_usec: *mut pa_usec_t, negative: *mut i32) -> i32;
pa_stream_get_timing_info(s: *mut pa_stream) -> *const pa_timing_info189     pub fn pa_stream_get_timing_info(s: *mut pa_stream) -> *const pa_timing_info;
pa_stream_get_sample_spec(s: *mut pa_stream) -> *const pa_sample_spec190     pub fn pa_stream_get_sample_spec(s: *mut pa_stream) -> *const pa_sample_spec;
pa_stream_get_channel_map(s: *mut pa_stream) -> *const pa_channel_map191     pub fn pa_stream_get_channel_map(s: *mut pa_stream) -> *const pa_channel_map;
pa_stream_get_format_info(s: *const pa_stream) -> *mut pa_format_info192     pub fn pa_stream_get_format_info(s: *const pa_stream) -> *mut pa_format_info;
pa_stream_get_buffer_attr(s: *mut pa_stream) -> *const pa_buffer_attr193     pub fn pa_stream_get_buffer_attr(s: *mut pa_stream) -> *const pa_buffer_attr;
pa_stream_set_buffer_attr(s: *mut pa_stream, attr: *const pa_buffer_attr, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation194     pub fn pa_stream_set_buffer_attr(s: *mut pa_stream, attr: *const pa_buffer_attr, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_update_sample_rate(s: *mut pa_stream, rate: u32, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation195     pub fn pa_stream_update_sample_rate(s: *mut pa_stream, rate: u32, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_proplist_update(s: *mut pa_stream, mode: pa_update_mode_t, p: *mut pa_proplist, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation196     pub fn pa_stream_proplist_update(s: *mut pa_stream, mode: pa_update_mode_t, p: *mut pa_proplist, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_proplist_remove(s: *mut pa_stream, keys: *const *const c_char, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation197     pub fn pa_stream_proplist_remove(s: *mut pa_stream, keys: *const *const c_char, cb: pa_stream_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_stream_set_monitor_stream(s: *mut pa_stream, sink_input_idx: u32) -> i32198     pub fn pa_stream_set_monitor_stream(s: *mut pa_stream, sink_input_idx: u32) -> i32;
pa_stream_get_monitor_stream(s: *const pa_stream) -> u32199     pub fn pa_stream_get_monitor_stream(s: *const pa_stream) -> u32;
200 }
201