audioutils/
audioutils.rs

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    /// * The parameters are invalid
12    InvalidArguments(String),
13
14    /// * When the input audio is an array of audio frames, each frame should have the same channels, otherwise, this error occurs.
15    FrameChannelsNotSame,
16
17    /// * When the input audio is an array of individual waveforms, each waveform should have the same length.
18    ChannelsNotInSameSize,
19
20    /// * When the input audio is the interleaved sample array, the number of samples must be divisible by the number of channels
21    TruncatedSamples,
22}
23
24/// * Turns a stereo audio into two individual mono waveforms.
25pub fn stereos_to_dual_monos<S>(stereos: &[(S, S)]) -> (Vec<S>, Vec<S>)
26where
27    S: SampleType,
28{
29    let l = stereos.iter().map(|(l, _r): &(S, S)| -> S { *l }).collect();
30    let r = stereos.iter().map(|(_l, r): &(S, S)| -> S { *r }).collect();
31    (l, r)
32}
33
34/// * Check every element in the data has the same length. The length will be returned.
35pub fn is_same_len<S>(data: &[Vec<S>]) -> Option<(bool, usize)>
36where
37    S: SampleType,
38{
39    if data.is_empty() {
40        None
41    } else {
42        let lengths: Vec<usize> = data.iter().map(|item| item.len()).collect();
43        let first = lengths[0];
44        Some((lengths.iter().all(|&item| item == first), first))
45    }
46}
47
48/// * Convert audio frames into stereo audio. Mono audio will be converted to stereo by duplicating samples. Only support 1 or 2 channels of audio.
49pub fn frames_to_stereos<S>(channel_mask: u32, frames: &[Vec<S>]) -> Result<Vec<(S, S)>, AudioConvError>
50where
51    S: SampleType,
52{
53    match is_same_len(frames) {
54        None => Ok(Vec::<(S, S)>::new()),
55        Some((equal, _channels)) => match equal {
56            false => Err(AudioConvError::FrameChannelsNotSame),
57            true => {
58                let downmixer = Downmixer::new(channel_mask, DownmixerParams::default());
59                Ok(frames.iter().map(|frame: &Vec<S>| -> (S, S) {downmixer.downmix_frame_to_stereo(frame)}).collect())
60            }
61        },
62    }
63}
64
65/// * Convert audio frames into two individual mono waveforms. Only support two-channel audio.
66pub fn frames_to_dual_mono<S>(channel_mask: u32, frames: &[Vec<S>]) -> Result<(Vec<S>, Vec<S>), AudioConvError>
67where
68    S: SampleType,
69{
70    Ok(stereos_to_dual_monos(&frames_to_stereos(channel_mask, frames)?))
71}
72
73/// * Convert audio frames into every individual mono waveform. Support any channels.
74/// * The param `channels` is optional, if you provide it, the conversion will be a little faster than if you just give it a `None.`
75pub fn frames_to_monos<S>(
76    frames: &[Vec<S>],
77) -> Result<Vec<Vec<S>>, AudioConvError>
78where
79    S: SampleType,
80{
81    match is_same_len(frames) {
82        None => Ok(Vec::<Vec<S>>::new()),
83        Some((equal, length)) => match equal {
84            false => Err(AudioConvError::FrameChannelsNotSame),
85            true => Ok((0..length)
86                    .map(|channel| -> Vec<S> {
87                        frames
88                            .iter()
89                            .map(|frame: &Vec<S>| -> S { frame[channel] })
90                            .collect()
91                    })
92                    .collect()),
93        },
94    }
95}
96
97/// * Convert every individual mono waveform into an audio frame array. Support any channels.
98pub fn monos_to_frames<S>(monos: &[Vec<S>]) -> Result<Vec<Vec<S>>, AudioConvError>
99where
100    S: SampleType,
101{
102    match is_same_len(monos) {
103        None => Ok(Vec::<Vec<S>>::new()),
104        Some((equal, length)) => match equal {
105            false => Err(AudioConvError::ChannelsNotInSameSize),
106            true => Ok((0..length)
107                .map(|position: usize| -> Vec<S> {
108                    monos
109                        .iter()
110                        .map(|channel: &Vec<S>| -> S { channel[position] })
111                        .collect()
112                })
113                .collect()),
114        },
115    }
116}
117
118/// * Convert every individual mono waveform into the interleaved samples of audio interleaved by channels. The WAV file stores PCM samples in this form.
119pub fn monos_to_interleaved_samples<S>(monos: &[Vec<S>]) -> Result<Vec<S>, AudioConvError>
120where
121    S: SampleType,
122{
123    Ok(monos_to_frames(monos)?.into_iter().flatten().collect())
124}
125
126/// * Convert audio frames into the interleaved samples of audio interleaved by channels. The WAV file stores PCM samples in this form.
127pub fn frames_to_interleaved_samples<S>(
128    frames: &[Vec<S>]
129) -> Result<Vec<S>, AudioConvError>
130where
131    S: SampleType,
132{
133    monos_to_interleaved_samples(&frames_to_monos(frames)?)
134}
135
136/// * Convert the interleaved samples of audio interleaved by channels into audio frames.
137pub fn interleaved_samples_to_frames<S>(
138    samples: &[S],
139    channels: u16,
140) -> Result<Vec<Vec<S>>, AudioConvError>
141where
142    S: SampleType,
143{
144    monos_to_frames(&interleaved_samples_to_monos(samples, channels)?)
145}
146
147/// * Convert stereo audio into the interleaved samples of audio interleaved by channels. The WAV file stores PCM samples in this form.
148pub fn stereos_to_interleaved_samples<S>(stereos: &[(S, S)]) -> Vec<S>
149where
150    S: SampleType,
151{
152    stereos
153        .iter()
154        .flat_map(|(l, r): &(S, S)| -> [S; 2] { [*l, *r] })
155        .collect()
156}
157
158/// * Convert interleaved samples into individual mono waveforms by the specified channels.
159pub fn interleaved_samples_to_monos<S>(
160    samples: &[S],
161    channels: u16,
162) -> Result<Vec<Vec<S>>, AudioConvError>
163where
164    S: SampleType,
165{
166    if channels == 0 {
167        Err(AudioConvError::InvalidArguments(
168            "Channels must not be zero".to_owned(),
169        ))
170    } else {
171        Ok((0..channels)
172            .map(|channel| -> Vec<S> {
173                samples
174                    .iter()
175                    .skip(channel as usize)
176                    .step_by(channels as usize)
177                    .copied()
178                    .collect()
179            })
180            .collect())
181    }
182}
183
184/// * Convert two individual mono waveforms into a stereo audio form.
185pub fn dual_monos_to_stereos<S>(
186    dual_monos: &(Vec<S>, Vec<S>),
187) -> Result<Vec<(S, S)>, AudioConvError>
188where
189    S: SampleType,
190{
191    let (l, r) = dual_monos;
192    if l.len() != r.len() {
193        Err(AudioConvError::ChannelsNotInSameSize)
194    } else {
195        Ok(l.iter()
196            .zip(r)
197            .map(|(l, r): (&S, &S)| -> (S, S) { (*l, *r) })
198            .collect())
199    }
200}
201
202/// * Convert interleaved samples into a stereo audio form. The interleaved samples are treated as a two-channel audio.
203pub fn interleaved_samples_to_stereos<S>(samples: &[S]) -> Result<Vec<(S, S)>, AudioConvError>
204where
205    S: SampleType,
206{
207    if (samples.len() & 1) != 0 {
208        Err(AudioConvError::TruncatedSamples)
209    } else {
210        Ok((0..(samples.len() / 2))
211            .map(|position| -> (S, S) { (samples[position * 2], samples[position * 2 + 1]) })
212            .collect())
213    }
214}
215
216/// * Convert two individual mono waveforms into one mono waveform. Stereo to mono conversion.
217pub fn dual_monos_to_monos<S>(dual_monos: &(Vec<S>, Vec<S>)) -> Result<Vec<S>, AudioConvError>
218where
219    S: SampleType,
220{
221    let (l, r) = dual_monos;
222    if l.len() != r.len() {
223        Err(AudioConvError::ChannelsNotInSameSize)
224    } else {
225        Ok(l.iter()
226            .zip(r)
227            .map(|(l, r): (&S, &S)| -> S { S::average(*l, *r) })
228            .collect())
229    }
230}
231
232/// * Convert a mono waveform to two individual mono waveforms by duplication. Mono to stereo conversion.
233pub fn monos_to_dual_monos<S>(monos: &[S]) -> (Vec<S>, Vec<S>)
234where
235    S: SampleType,
236{
237    (monos.to_vec(), monos.to_vec())
238}
239
240/// * Convert stereo audio to a mono waveform. Stereo to mono conversion.
241pub fn stereos_to_mono_channel<S>(stereos: &[(S, S)]) -> Vec<S>
242where
243    S: SampleType,
244{
245    stereos
246        .iter()
247        .map(|(l, r): &(S, S)| -> S { S::average(*l, *r) })
248        .collect()
249}
250
251/// * Convert mono waveform to a stereo audio form by duplication. Mono to stereo conversion.
252pub fn monos_to_stereos<S>(monos: &[S]) -> Vec<(S, S)>
253where
254    S: SampleType,
255{
256    monos.iter().map(|s| (*s, *s)).collect()
257}
258
259/// * Convert one stereo sample to another format by scaling, see `sample_conv()`.
260#[inline(always)]
261pub fn stereo_conv<S, D>(frame: (S, S)) -> (D, D)
262where
263    S: SampleType,
264    D: SampleType,
265{
266    let (l, r) = frame;
267    (D::scale_from(l), D::scale_from(r))
268}
269
270/// * Convert samples to another format by scaling. e.g. `u8` to `i16` conversion is to scale `[0, 255]` into `[-32768, +32767]`
271/// * Upscaling is lossless. Beware, the precision of `f32` is roughly the same as `i24`. Convert `i32` to `f32` is lossy.
272/// * `i32` to `f64` is lossless but `f64` for audio processing consumes lots of memory.
273pub fn sample_conv<S, D>(frame: &[S]) -> Cow<'_, [D]>
274where
275    S: SampleType,
276    D: SampleType,
277{
278    if TypeId::of::<S>() == TypeId::of::<D>() {
279        Cow::Borrowed(unsafe { slice::from_raw_parts(frame.as_ptr() as *const D, frame.len()) })
280    } else {
281        Cow::Owned(
282            frame
283                .iter()
284                .map(|sample: &S| -> D { D::scale_from(*sample) })
285                .collect(),
286        )
287    }
288}
289
290/// * Convert multiple stereo samples to another format by scaling, see `sample_conv()`.
291pub fn stereos_conv<S, D>(stereos: &[(S, S)]) -> Cow<'_, [(D, D)]>
292where
293    S: SampleType,
294    D: SampleType,
295{
296    if TypeId::of::<S>() == TypeId::of::<D>() {
297        Cow::Borrowed(unsafe {
298            slice::from_raw_parts(stereos.as_ptr() as *const (D, D), stereos.len())
299        })
300    } else {
301        Cow::Owned(
302            stereos
303                .iter()
304                .map(|stereo: &(S, S)| -> (D, D) { stereo_conv(*stereo) })
305                .collect(),
306        )
307    }
308}
309
310/// * Convert 2D audio e.g. Audio frames or multiple mono waveforms, to another format by scaling, see `sample_conv()`.
311pub fn sample_conv_batch<S, D>(frames: &[Vec<S>]) -> Cow<'_, [Vec<D>]>
312where
313    S: SampleType,
314    D: SampleType,
315{
316    if TypeId::of::<S>() == TypeId::of::<D>() {
317        Cow::Borrowed(unsafe {
318            slice::from_raw_parts(frames.as_ptr() as *const Vec<D>, frames.len())
319        })
320    } else {
321        Cow::Owned(
322            frames
323                .iter()
324                .map(|frames: &Vec<S>| -> Vec<D> { sample_conv(frames).to_vec() })
325                .collect(),
326        )
327    }
328}
329
330/// * Use the `Resampler` to resample a mono waveform from original sample rate to a specific sample rate.
331pub fn do_resample_mono<S>(
332    resampler: &Resampler,
333    input: &[S],
334    src_sample_rate: u32,
335    dst_sample_rate: u32,
336) -> Vec<S>
337where
338    S: SampleType,
339{
340    let input = sample_conv::<S, f32>(input);
341    let result = resampler
342        .resample(&input, src_sample_rate, dst_sample_rate)
343        .unwrap();
344    sample_conv::<f32, S>(&result).to_vec()
345}
346
347/// * Use the `Resampler` to resample a stereo audio from the original sample rate to a specific sample rate.
348pub fn do_resample_stereo<S>(
349    resampler: &Resampler,
350    input: &[(S, S)],
351    src_sample_rate: u32,
352    dst_sample_rate: u32,
353) -> Vec<(S, S)>
354where
355    S: SampleType,
356{
357    let block = stereos_to_dual_monos(input);
358    let l = do_resample_mono(resampler, &block.0, src_sample_rate, dst_sample_rate);
359    let r = do_resample_mono(resampler, &block.1, src_sample_rate, dst_sample_rate);
360    dual_monos_to_stereos(&(l, r)).unwrap()
361}
362
363/// * Use the `Resampler` to resample audio frames from the original sample rate to a specific sample rate.
364pub fn do_resample_frames<S>(
365    resampler: &Resampler,
366    input: &[Vec<S>],
367    src_sample_rate: u32,
368    dst_sample_rate: u32,
369) -> Vec<Vec<S>>
370where
371    S: SampleType,
372{
373    let monos = frames_to_monos(input).unwrap();
374    let monos: Vec<Vec<S>> = monos
375        .into_iter()
376        .map(|mono| do_resample_mono(resampler, &mono, src_sample_rate, dst_sample_rate))
377        .collect();
378    monos_to_frames(&monos).unwrap()
379}