Skip to main content

wayle_audio/types/
stream.rs

1use std::collections::HashMap;
2
3use super::format::{ChannelMap, SampleSpec};
4use crate::volume::types::Volume;
5
6/// Stream state enumeration
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum StreamState {
9    /// Stream is creating.
10    Creating,
11    /// Stream is ready.
12    Ready,
13    /// Stream is actively playing or recording.
14    Running,
15    /// Stream is paused (corked in PulseAudio).
16    Corked,
17    /// Stream has failed.
18    Failed,
19    /// Stream has been terminated.
20    Terminated,
21    /// Stream has been unlinked.
22    Unlinked,
23}
24
25/// Stream type enumeration
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
27pub enum StreamType {
28    /// Playback stream (sink input)
29    Playback,
30    /// Recording stream (source output)
31    Record,
32}
33
34/// Stream key for unique identification
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
36pub struct StreamKey {
37    /// Stream index
38    pub index: u32,
39    /// Stream type
40    pub stream_type: StreamType,
41}
42
43impl StreamKey {
44    /// Create a new stream key
45    pub fn new(index: u32, stream_type: StreamType) -> Self {
46        Self { index, stream_type }
47    }
48}
49
50/// Media information for a stream
51#[derive(Debug, Clone, PartialEq)]
52pub struct MediaInfo {
53    /// Track title
54    pub title: Option<String>,
55    /// Artist name
56    pub artist: Option<String>,
57    /// Album name
58    pub album: Option<String>,
59    /// Icon name
60    pub icon_name: Option<String>,
61}
62
63#[derive(Debug, Clone, PartialEq)]
64pub(crate) struct StreamInfo {
65    pub index: u32,
66    pub stream_type: StreamType,
67    pub name: String,
68    pub application_name: Option<String>,
69    pub binary: Option<String>,
70    pub pid: Option<u32>,
71    pub owner_module: Option<u32>,
72    pub client: Option<u32>,
73    pub device_index: u32,
74    pub volume: Volume,
75    pub muted: bool,
76    pub corked: bool,
77    pub has_volume: bool,
78    pub volume_writable: bool,
79    pub state: StreamState,
80    pub sample_spec: SampleSpec,
81    pub channel_map: ChannelMap,
82    pub properties: HashMap<String, String>,
83    pub media: MediaInfo,
84    pub buffer_latency: u64,
85    pub device_latency: u64,
86    pub resample_method: Option<String>,
87    pub driver: String,
88    pub format: Option<String>,
89}
90
91impl StreamInfo {
92    pub(crate) fn key(&self) -> StreamKey {
93        StreamKey {
94            index: self.index,
95            stream_type: self.stream_type,
96        }
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    fn create_test_stream_info(
105        stream_type: StreamType,
106        properties: HashMap<String, String>,
107    ) -> StreamInfo {
108        use crate::{
109            types::format::{ChannelMap, SampleFormat, SampleSpec},
110            volume::types::Volume,
111        };
112
113        StreamInfo {
114            index: 0,
115            stream_type,
116            name: String::from("test"),
117            application_name: None,
118            binary: None,
119            pid: None,
120            owner_module: None,
121            client: None,
122            device_index: 0,
123            volume: Volume::mono(1.0),
124            muted: false,
125            corked: false,
126            has_volume: true,
127            volume_writable: true,
128            state: StreamState::Running,
129            sample_spec: SampleSpec {
130                format: SampleFormat::S16LE,
131                rate: 44100,
132                channels: 2,
133            },
134            channel_map: ChannelMap {
135                channels: 2,
136                positions: vec![],
137            },
138            properties,
139            media: MediaInfo {
140                title: None,
141                artist: None,
142                album: None,
143                icon_name: None,
144            },
145            buffer_latency: 0,
146            device_latency: 0,
147            resample_method: None,
148            driver: String::from("test-driver"),
149            format: None,
150        }
151    }
152
153    #[test]
154    fn key_returns_correct_stream_key_for_record_stream() {
155        let mut info = create_test_stream_info(StreamType::Record, HashMap::new());
156        info.index = 42;
157
158        let key = info.key();
159
160        assert_eq!(key.index, 42);
161        assert_eq!(key.stream_type, StreamType::Record);
162    }
163
164    #[test]
165    fn key_returns_correct_stream_key_for_playback_stream() {
166        let mut info = create_test_stream_info(StreamType::Playback, HashMap::new());
167        info.index = 123;
168
169        let key = info.key();
170
171        assert_eq!(key.index, 123);
172        assert_eq!(key.stream_type, StreamType::Playback);
173    }
174}