1#![allow(dead_code)]
2
3use std::{any::TypeId, borrow::Cow, slice};
4
5use resampler::Resampler;
6use sampletypes::SampleType;
7use downmixer::{Downmixer, DownmixerParams};
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum AudioConvError {
11 InvalidArguments(String),
12 FrameChannelsNotSame,
13 ChannelsNotInSameSize,
14 TruncatedSamples,
15}
16
17pub fn stereos_to_dual_monos<S>(stereos: &[(S, S)]) -> (Vec<S>, Vec<S>)
19where
20 S: SampleType,
21{
22 let l = stereos.iter().map(|(l, _r): &(S, S)| -> S { *l }).collect();
23 let r = stereos.iter().map(|(_l, r): &(S, S)| -> S { *r }).collect();
24 (l, r)
25}
26
27pub fn is_same_len<S>(data: &[Vec<S>]) -> Option<(bool, usize)> {
29 if data.is_empty() {
30 None
31 } else {
32 let lengths: Vec<usize> = data.iter().map(|item| item.len()).collect();
33 let first = lengths[0];
34 Some((lengths.iter().all(|&item| item == first), first))
35 }
36}
37
38pub fn frames_to_stereos<S>(channel_mask: u32, frames: &[Vec<S>]) -> Result<Vec<(S, S)>, AudioConvError>
40where
41 S: SampleType,
42{
43 match is_same_len(frames) {
44 None => Ok(Vec::<(S, S)>::new()),
45 Some((equal, _channels)) => match equal {
46 false => Err(AudioConvError::FrameChannelsNotSame),
47 true => {
48 let downmixer = Downmixer::new(channel_mask, DownmixerParams::default());
49 Ok(frames.iter().map(|frame: &Vec<S>| -> (S, S) {downmixer.downmix_frame_to_stereo(frame)}).collect())
50 }
51 },
52 }
53}
54
55pub fn frames_to_dual_mono<S>(channel_mask: u32, frames: &[Vec<S>]) -> Result<(Vec<S>, Vec<S>), AudioConvError>
57where
58 S: SampleType,
59{
60 Ok(stereos_to_dual_monos(&frames_to_stereos(channel_mask, frames)?))
61}
62
63pub fn frames_to_monos<S>(
66 frames: &[Vec<S>],
67) -> Result<Vec<Vec<S>>, AudioConvError>
68where
69 S: SampleType,
70{
71 match is_same_len(frames) {
72 None => Ok(Vec::<Vec<S>>::new()),
73 Some((equal, length)) => match equal {
74 false => Err(AudioConvError::FrameChannelsNotSame),
75 true => Ok((0..length)
76 .map(|channel| -> Vec<S> {
77 frames
78 .iter()
79 .map(|frame: &Vec<S>| -> S { frame[channel] })
80 .collect()
81 })
82 .collect()),
83 },
84 }
85}
86
87pub fn monos_to_frames<S>(monos: &[Vec<S>]) -> Result<Vec<Vec<S>>, AudioConvError>
89where
90 S: SampleType,
91{
92 match is_same_len(monos) {
93 None => Ok(Vec::<Vec<S>>::new()),
94 Some((equal, length)) => match equal {
95 false => Err(AudioConvError::ChannelsNotInSameSize),
96 true => Ok((0..length)
97 .map(|position: usize| -> Vec<S> {
98 monos
99 .iter()
100 .map(|channel: &Vec<S>| -> S { channel[position] })
101 .collect()
102 })
103 .collect()),
104 },
105 }
106}
107
108pub fn monos_to_interleaved_samples<S>(monos: &[Vec<S>]) -> Result<Vec<S>, AudioConvError>
110where
111 S: SampleType,
112{
113 Ok(monos_to_frames(monos)?.into_iter().flatten().collect())
114}
115
116pub fn frames_to_interleaved_samples<S>(
118 frames: &[Vec<S>]
119) -> Result<Vec<S>, AudioConvError>
120where
121 S: SampleType,
122{
123 monos_to_interleaved_samples(&frames_to_monos(frames)?)
124}
125
126pub fn interleaved_samples_to_frames<S>(
128 samples: &[S],
129 channels: u16,
130) -> Result<Vec<Vec<S>>, AudioConvError>
131where
132 S: SampleType,
133{
134 monos_to_frames(&interleaved_samples_to_monos(samples, channels)?)
135}
136
137pub fn stereos_to_interleaved_samples<S>(stereos: &[(S, S)]) -> Vec<S>
139where
140 S: SampleType,
141{
142 stereos
143 .iter()
144 .flat_map(|(l, r): &(S, S)| -> [S; 2] { [*l, *r] })
145 .collect()
146}
147
148pub fn interleaved_samples_to_monos<S>(
150 samples: &[S],
151 channels: u16,
152) -> Result<Vec<Vec<S>>, AudioConvError>
153where
154 S: SampleType,
155{
156 if channels == 0 {
157 Err(AudioConvError::InvalidArguments(
158 "Channels must not be zero".to_owned(),
159 ))
160 } else {
161 Ok((0..channels)
162 .map(|channel| -> Vec<S> {
163 samples
164 .iter()
165 .skip(channel as usize)
166 .step_by(channels as usize)
167 .copied()
168 .collect()
169 })
170 .collect())
171 }
172}
173
174pub fn dual_monos_to_stereos<S>(
176 dual_monos: &(Vec<S>, Vec<S>),
177) -> Result<Vec<(S, S)>, AudioConvError>
178where
179 S: SampleType,
180{
181 let (l, r) = dual_monos;
182 if l.len() != r.len() {
183 Err(AudioConvError::ChannelsNotInSameSize)
184 } else {
185 Ok(l.iter()
186 .zip(r)
187 .map(|(l, r): (&S, &S)| -> (S, S) { (*l, *r) })
188 .collect())
189 }
190}
191
192pub fn interleaved_samples_to_stereos<S>(samples: &[S]) -> Result<Vec<(S, S)>, AudioConvError>
194where
195 S: SampleType,
196{
197 if (samples.len() & 1) != 0 {
198 Err(AudioConvError::TruncatedSamples)
199 } else {
200 Ok((0..(samples.len() / 2))
201 .map(|position| -> (S, S) { (samples[position * 2], samples[position * 2 + 1]) })
202 .collect())
203 }
204}
205
206pub fn dual_monos_to_monos<S>(dual_monos: &(Vec<S>, Vec<S>)) -> Result<Vec<S>, AudioConvError>
208where
209 S: SampleType,
210{
211 let (l, r) = dual_monos;
212 if l.len() != r.len() {
213 Err(AudioConvError::ChannelsNotInSameSize)
214 } else {
215 Ok(l.iter()
216 .zip(r)
217 .map(|(l, r): (&S, &S)| -> S { S::average(*l, *r) })
218 .collect())
219 }
220}
221
222pub fn monos_to_dual_monos<S>(monos: &[S]) -> (Vec<S>, Vec<S>)
224where
225 S: SampleType,
226{
227 (monos.to_vec(), monos.to_vec())
228}
229
230pub fn stereos_to_mono_channel<S>(stereos: &[(S, S)]) -> Vec<S>
232where
233 S: SampleType,
234{
235 stereos
236 .iter()
237 .map(|(l, r): &(S, S)| -> S { S::average(*l, *r) })
238 .collect()
239}
240
241pub fn monos_to_stereos<S>(monos: &[S]) -> Vec<(S, S)>
243where
244 S: SampleType,
245{
246 monos.iter().map(|s| (*s, *s)).collect()
247}
248
249#[inline(always)]
251pub fn stereo_conv<S, D>(frame: (S, S)) -> (D, D)
252where
253 S: SampleType,
254 D: SampleType,
255{
256 let (l, r) = frame;
257 (D::scale_from(l), D::scale_from(r))
258}
259
260pub fn sample_conv<S, D>(frame: &[S]) -> Cow<'_, [D]>
264where
265 S: SampleType,
266 D: SampleType,
267{
268 if TypeId::of::<S>() == TypeId::of::<D>() {
269 Cow::Borrowed(unsafe { slice::from_raw_parts(frame.as_ptr() as *const D, frame.len()) })
270 } else {
271 Cow::Owned(
272 frame
273 .iter()
274 .map(|sample: &S| -> D { D::scale_from(*sample) })
275 .collect(),
276 )
277 }
278}
279
280pub fn stereos_conv<S, D>(stereos: &[(S, S)]) -> Cow<'_, [(D, D)]>
282where
283 S: SampleType,
284 D: SampleType,
285{
286 if TypeId::of::<S>() == TypeId::of::<D>() {
287 Cow::Borrowed(unsafe {
288 slice::from_raw_parts(stereos.as_ptr() as *const (D, D), stereos.len())
289 })
290 } else {
291 Cow::Owned(
292 stereos
293 .iter()
294 .map(|stereo: &(S, S)| -> (D, D) { stereo_conv(*stereo) })
295 .collect(),
296 )
297 }
298}
299
300pub fn sample_conv_batch<S, D>(frames: &[Vec<S>]) -> Cow<'_, [Vec<D>]>
302where
303 S: SampleType,
304 D: SampleType,
305{
306 if TypeId::of::<S>() == TypeId::of::<D>() {
307 Cow::Borrowed(unsafe {
308 slice::from_raw_parts(frames.as_ptr() as *const Vec<D>, frames.len())
309 })
310 } else {
311 Cow::Owned(
312 frames
313 .iter()
314 .map(|frames: &Vec<S>| -> Vec<D> { sample_conv(frames).to_vec() })
315 .collect(),
316 )
317 }
318}
319
320pub fn do_resample_mono<S>(
322 resampler: &Resampler,
323 input: &[S],
324 src_sample_rate: u32,
325 dst_sample_rate: u32,
326) -> Vec<S>
327where
328 S: SampleType,
329{
330 let input = sample_conv::<S, f32>(input);
331 let result = resampler
332 .resample(&input, src_sample_rate, dst_sample_rate)
333 .unwrap();
334 sample_conv::<f32, S>(&result).to_vec()
335}
336
337pub fn do_resample_stereo<S>(
339 resampler: &Resampler,
340 input: &[(S, S)],
341 src_sample_rate: u32,
342 dst_sample_rate: u32,
343) -> Vec<(S, S)>
344where
345 S: SampleType,
346{
347 let block = stereos_to_dual_monos(input);
348 let l = do_resample_mono(resampler, &block.0, src_sample_rate, dst_sample_rate);
349 let r = do_resample_mono(resampler, &block.1, src_sample_rate, dst_sample_rate);
350 dual_monos_to_stereos(&(l, r)).unwrap()
351}
352
353pub fn do_resample_frames<S>(
355 resampler: &Resampler,
356 input: &[Vec<S>],
357 src_sample_rate: u32,
358 dst_sample_rate: u32,
359) -> Vec<Vec<S>>
360where
361 S: SampleType,
362{
363 let monos = frames_to_monos(input).unwrap();
364 let monos: Vec<Vec<S>> = monos
365 .into_iter()
366 .map(|mono| do_resample_mono(resampler, &mono, src_sample_rate, dst_sample_rate))
367 .collect();
368 monos_to_frames(&monos).unwrap()
369}