1use 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}