cubeb_core/
builders.rs

1// Copyright © 2017-2018 Mozilla Foundation
2//
3// This program is made available under an ISC-style license.  See the
4// accompanying file LICENSE for details.
5
6use ffi;
7use {ChannelLayout, SampleFormat, StreamParams, StreamPrefs};
8
9#[derive(Debug)]
10pub struct StreamParamsBuilder(ffi::cubeb_stream_params);
11
12impl Default for StreamParamsBuilder {
13    fn default() -> Self {
14        StreamParamsBuilder(ffi::cubeb_stream_params {
15            format: ffi::CUBEB_SAMPLE_S16NE,
16            ..Default::default()
17        })
18    }
19}
20
21impl StreamParamsBuilder {
22    pub fn new() -> Self {
23        Default::default()
24    }
25
26    pub fn format(mut self, format: SampleFormat) -> Self {
27        self.0.format = format.into();
28        self
29    }
30
31    pub fn rate(mut self, rate: u32) -> Self {
32        self.0.rate = rate;
33        self
34    }
35
36    pub fn channels(mut self, channels: u32) -> Self {
37        self.0.channels = channels;
38        self
39    }
40
41    pub fn layout(mut self, layout: ChannelLayout) -> Self {
42        self.0.layout = layout.into();
43        self
44    }
45
46    pub fn prefs(mut self, prefs: StreamPrefs) -> Self {
47        self.0.prefs = prefs.bits();
48        self
49    }
50
51    pub fn take(&self) -> StreamParams {
52        StreamParams::from(self.0)
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use SampleFormat;
59    use {ffi, StreamParamsBuilder, StreamPrefs};
60
61    #[test]
62    fn stream_params_builder_channels() {
63        let params = StreamParamsBuilder::new().channels(2).take();
64        assert_eq!(params.channels(), 2);
65    }
66
67    #[test]
68    fn stream_params_builder_format() {
69        macro_rules! check(
70            ($($real:ident),*) => (
71                $(let params = StreamParamsBuilder::new()
72                  .format(super::SampleFormat::$real)
73                  .take();
74                assert_eq!(params.format(), super::SampleFormat::$real);
75                )*
76            ) );
77
78        check!(S16LE, S16BE, Float32LE, Float32BE);
79    }
80
81    #[test]
82    fn stream_params_builder_format_native_endian() {
83        let params = StreamParamsBuilder::new()
84            .format(SampleFormat::S16NE)
85            .take();
86        assert_eq!(
87            params.format(),
88            if cfg!(target_endian = "little") {
89                super::SampleFormat::S16LE
90            } else {
91                super::SampleFormat::S16BE
92            }
93        );
94
95        let params = StreamParamsBuilder::new()
96            .format(SampleFormat::Float32NE)
97            .take();
98        assert_eq!(
99            params.format(),
100            if cfg!(target_endian = "little") {
101                SampleFormat::Float32LE
102            } else {
103                SampleFormat::Float32BE
104            }
105        );
106    }
107
108    #[test]
109    fn stream_params_builder_layout() {
110        macro_rules! check(
111            ($($real:ident),*) => (
112                $(let params = StreamParamsBuilder::new()
113                  .layout(super::ChannelLayout::$real)
114                  .take();
115                assert_eq!(params.layout(), super::ChannelLayout::$real);
116                )*
117            ) );
118
119        check!(
120            UNDEFINED,
121            MONO,
122            MONO_LFE,
123            STEREO,
124            STEREO_LFE,
125            _3F,
126            _3F_LFE,
127            _2F1,
128            _2F1_LFE,
129            _3F1,
130            _3F1_LFE,
131            _2F2,
132            _2F2_LFE,
133            QUAD,
134            QUAD_LFE,
135            _3F2,
136            _3F2_LFE,
137            _3F2_BACK,
138            _3F2_LFE_BACK,
139            _3F3R_LFE,
140            _3F4_LFE
141        );
142    }
143
144    #[test]
145    fn stream_params_builder_rate() {
146        let params = StreamParamsBuilder::new().rate(44100).take();
147        assert_eq!(params.rate(), 44100);
148    }
149
150    #[test]
151    fn stream_params_builder_to_raw_channels() {
152        let params = StreamParamsBuilder::new().channels(2).take();
153        let raw = unsafe { &*params.as_ptr() };
154        assert_eq!(raw.channels, 2);
155    }
156
157    #[test]
158    fn stream_params_builder_to_raw_format() {
159        macro_rules! check(
160            ($($real:ident => $raw:ident),*) => (
161                $(let params = super::StreamParamsBuilder::new()
162                  .format(SampleFormat::$real)
163                  .take();
164                  let raw = unsafe { &*params.as_ptr() };
165                  assert_eq!(raw.format, ffi::$raw);
166                )*
167            ) );
168
169        check!(S16LE => CUBEB_SAMPLE_S16LE,
170               S16BE => CUBEB_SAMPLE_S16BE,
171               Float32LE => CUBEB_SAMPLE_FLOAT32LE,
172               Float32BE => CUBEB_SAMPLE_FLOAT32BE);
173    }
174
175    #[test]
176    fn stream_params_builder_format_to_raw_native_endian() {
177        let params = StreamParamsBuilder::new()
178            .format(SampleFormat::S16NE)
179            .take();
180        let raw = unsafe { &*params.as_ptr() };
181        assert_eq!(
182            raw.format,
183            if cfg!(target_endian = "little") {
184                ffi::CUBEB_SAMPLE_S16LE
185            } else {
186                ffi::CUBEB_SAMPLE_S16BE
187            }
188        );
189
190        let params = StreamParamsBuilder::new()
191            .format(SampleFormat::Float32NE)
192            .take();
193        let raw = unsafe { &*params.as_ptr() };
194        assert_eq!(
195            raw.format,
196            if cfg!(target_endian = "little") {
197                ffi::CUBEB_SAMPLE_FLOAT32LE
198            } else {
199                ffi::CUBEB_SAMPLE_FLOAT32BE
200            }
201        );
202    }
203
204    #[test]
205    fn stream_params_builder_to_raw_layout() {
206        macro_rules! check(
207            ($($real:ident => $raw:ident),*) => (
208                $(let params = super::StreamParamsBuilder::new()
209                  .layout(super::ChannelLayout::$real)
210                  .take();
211                  let raw = unsafe { &*params.as_ptr() };
212                  assert_eq!(raw.layout, ffi::$raw);
213                )*
214            ) );
215
216        check!(UNDEFINED => CUBEB_LAYOUT_UNDEFINED,
217               MONO => CUBEB_LAYOUT_MONO,
218               MONO_LFE => CUBEB_LAYOUT_MONO_LFE,
219               STEREO => CUBEB_LAYOUT_STEREO,
220               STEREO_LFE => CUBEB_LAYOUT_STEREO_LFE,
221               _3F => CUBEB_LAYOUT_3F,
222               _3F_LFE => CUBEB_LAYOUT_3F_LFE,
223               _2F1 => CUBEB_LAYOUT_2F1,
224               _2F1_LFE=> CUBEB_LAYOUT_2F1_LFE,
225               _3F1 => CUBEB_LAYOUT_3F1,
226               _3F1_LFE =>  CUBEB_LAYOUT_3F1_LFE,
227               _2F2 => CUBEB_LAYOUT_2F2,
228               _2F2_LFE => CUBEB_LAYOUT_2F2_LFE,
229               QUAD => CUBEB_LAYOUT_QUAD,
230               QUAD_LFE => CUBEB_LAYOUT_QUAD_LFE,
231               _3F2 => CUBEB_LAYOUT_3F2,
232               _3F2_LFE => CUBEB_LAYOUT_3F2_LFE,
233               _3F2_BACK => CUBEB_LAYOUT_3F2_BACK,
234               _3F2_LFE_BACK => CUBEB_LAYOUT_3F2_LFE_BACK,
235               _3F3R_LFE => CUBEB_LAYOUT_3F3R_LFE,
236               _3F4_LFE => CUBEB_LAYOUT_3F4_LFE);
237    }
238
239    #[test]
240    fn stream_params_builder_to_raw_rate() {
241        let params = StreamParamsBuilder::new().rate(44100).take();
242        let raw = unsafe { &*params.as_ptr() };
243        assert_eq!(raw.rate, 44100);
244    }
245
246    #[test]
247    fn stream_params_builder_prefs_default() {
248        let params = StreamParamsBuilder::new().take();
249        assert_eq!(params.prefs(), StreamPrefs::NONE);
250    }
251
252    #[test]
253    fn stream_params_builder_prefs() {
254        let params = StreamParamsBuilder::new()
255            .prefs(StreamPrefs::LOOPBACK)
256            .take();
257        assert_eq!(params.prefs(), StreamPrefs::LOOPBACK);
258    }
259}