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    InvalidArguments(String),
12    FrameChannelsNotSame,
13    ChannelsNotInSameSize,
14    TruncatedSamples,
15}
16
17/// * Turns a stereo audio into two individual mono waveforms.
18pub 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
27/// * Check every element in the data has the same length. The length will be returned.
28pub 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
38/// * Convert audio frames into stereo audio. Mono audio will be converted to stereo by duplicating samples. Only support 1 or 2 channels of audio.
39pub 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
55/// * Convert audio frames into two individual mono waveforms. Only support two-channel audio.
56pub 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
63/// * Convert audio frames into every individual mono waveform. Support any channels.
64/// * The param `channels` is optional, if you provide it, the conversion will be a little faster than if you just give it a `None.`
65pub 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
87/// * Convert every individual mono waveform into an audio frame array. Support any channels.
88pub 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
108/// * Convert every individual mono waveform into the interleaved samples of audio interleaved by channels. The WAV file stores PCM samples in this form.
109pub 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
116/// * Convert audio frames into the interleaved samples of audio interleaved by channels. The WAV file stores PCM samples in this form.
117pub 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
126/// * Convert the interleaved samples of audio interleaved by channels into audio frames.
127pub 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
137/// * Convert stereo audio into the interleaved samples of audio interleaved by channels. The WAV file stores PCM samples in this form.
138pub 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
148/// * Convert interleaved samples into individual mono waveforms by the specified channels.
149pub 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
174/// * Convert two individual mono waveforms into a stereo audio form.
175pub 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
192/// * Convert interleaved samples into a stereo audio form. The interleaved samples are treated as a two-channel audio.
193pub 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
206/// * Convert two individual mono waveforms into one mono waveform. Stereo to mono conversion.
207pub 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
222/// * Convert a mono waveform to two individual mono waveforms by duplication. Mono to stereo conversion.
223pub 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
230/// * Convert stereo audio to a mono waveform. Stereo to mono conversion.
231pub 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
241/// * Convert mono waveform to a stereo audio form by duplication. Mono to stereo conversion.
242pub 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/// * Convert one stereo sample to another format by scaling, see `sample_conv()`.
250#[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
260/// * Convert samples to another format by scaling. e.g. `u8` to `i16` conversion is to scale `[0, 255]` into `[-32768, +32767]`
261/// * Upscaling is lossless. Beware, the precision of `f32` is roughly the same as `i24`. Convert `i32` to `f32` is lossy.
262/// * `i32` to `f64` is lossless but `f64` for audio processing consumes lots of memory.
263pub 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
280/// * Convert multiple stereo samples to another format by scaling, see `sample_conv()`.
281pub 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
300/// * Convert 2D audio e.g. Audio frames or multiple mono waveforms, to another format by scaling, see `sample_conv()`.
301pub 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
320/// * Use the `Resampler` to resample a mono waveform from original sample rate to a specific sample rate.
321pub 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
337/// * Use the `Resampler` to resample a stereo audio from the original sample rate to a specific sample rate.
338pub 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
353/// * Use the `Resampler` to resample audio frames from the original sample rate to a specific sample rate.
354pub 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}