fast_interleave/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3#[cfg(feature = "std")]
4use std::{num::NonZeroUsize, ops::Range};
5
6#[cfg(not(feature = "std"))]
7use core::{num::NonZeroUsize, ops::Range};
8
9/// Interleave the given channels into the output buffer.
10///
11/// * `input` - The de-interleaved input channels.
12/// * `input_range` - The range in each input channel to read from.
13/// * `output` - The interleaved output buffer to write to.
14///
15/// # Example
16///
17/// ```
18/// # use fast_interleave::*;
19/// let input: Vec<Vec<i32>> = vec![vec![1, 3, 5, 7], vec![2, 4, 6, 8]];
20/// let mut output: Vec<i32> = vec![0; 8];
21///
22/// interleave::<_, _, 2>(&input, 0..4, &mut output);
23///
24/// assert_eq!(&output, &[1, 2, 3, 4, 5, 6, 7, 8]);
25///
26/// // Interleave range in input:
27/// interleave::<_, _, 2>(&input, 2..4, &mut output[0..4]);
28///
29/// assert_eq!(&output, &[5, 6, 7, 8, 5, 6, 7, 8]);
30/// ```
31///
32/// # Panics
33/// Panics when any of the following are true:
34/// * `input.len() < CHANNELS`
35/// * `input_range` is out-of-bounds for any input channel
36/// * `output.len() < (input_range.end - input_range.start) * CHANNELS`
37/// * `CHANNELS` == 0
38pub fn interleave<T: Copy, Vin: AsRef<[T]>, const CHANNELS: usize>(
39    input: &[Vin],
40    input_range: Range<usize>,
41    output: &mut [T],
42) {
43    assert!(CHANNELS > 0);
44    assert!(input.len() >= CHANNELS);
45
46    if input_range.is_empty() {
47        return;
48    }
49
50    assert!(output.len() >= (input_range.end - input_range.start) * CHANNELS);
51
52    for ch in input.iter() {
53        let ch = ch.as_ref();
54        assert!(input_range.start <= ch.len());
55        assert!(input_range.end <= ch.len());
56    }
57
58    // SAFETY: All of the required safety conditions were checked above.
59    unsafe {
60        interleave_unchecked::<T, _, CHANNELS>(input, input_range, output);
61    }
62}
63
64/// Interleave the given channels into the output buffer.
65///
66/// No bounds checking will occur.
67///
68/// * `input` - The de-interleaved input channels.
69/// * `input_range` - The range in each input channel to read from.
70/// * `output` - The interleaved output buffer to write to.
71///
72/// # Example
73///
74/// ```
75/// # use fast_interleave::*;
76/// let input: Vec<Vec<i32>> = vec![vec![1, 3, 5, 7], vec![2, 4, 6, 8]];
77/// let mut output: Vec<i32> = vec![0; 8];
78///
79/// unsafe { interleave_unchecked::<_, _, 2>(&input, 0..4, &mut output); }
80///
81/// assert_eq!(&output, &[1, 2, 3, 4, 5, 6, 7, 8]);
82///
83/// // Interleave range in input:
84/// unsafe { interleave_unchecked::<_, _, 2>(&input, 2..4, &mut output[0..4]); }
85///
86/// assert_eq!(&output, &[5, 6, 7, 8, 5, 6, 7, 8]);
87/// ```
88///
89/// # Safety
90/// The caller must uphold that all of the following conditions are true:
91/// * `input.len() >= CHANNELS`
92/// * `input_range` is within bounds for every input channel
93/// * `output.len() >= (input_range.end - input_range.start) * CHANNELS`
94/// * `CHANNELS` > 0
95pub unsafe fn interleave_unchecked<T: Copy, Vin: AsRef<[T]>, const CHANNELS: usize>(
96    input: &[Vin],
97    input_range: Range<usize>,
98    output: &mut [T],
99) {
100    if input_range.is_empty() {
101        return;
102    }
103
104    unsafe {
105        for i in 0..(input_range.end - input_range.start) {
106            for ch_i in 0..CHANNELS {
107                *output.get_unchecked_mut((i * CHANNELS) + ch_i) = *input
108                    .get_unchecked(ch_i)
109                    .as_ref()
110                    .get_unchecked(input_range.start + i);
111            }
112        }
113    }
114}
115
116/// De-interleave the given data into the output buffer channels.
117///
118/// * `input` - The interleaved input channels.
119/// * `output` - The de-interleaved output channels to write to.
120/// * `output_range` - The range in each output channel to write to.
121///
122/// # Example
123///
124/// ```
125/// # use fast_interleave::*;
126/// let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
127/// let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
128///
129/// deinterleave::<_, _, 2>(&input, &mut output, 0..4);
130///
131/// assert_eq!(&output[0], &[1, 3, 5, 7]);
132/// assert_eq!(&output[1], &[2, 4, 6, 8]);
133///
134/// // Deinterleave into a range in output:
135/// deinterleave::<_, _, 2>(&input[0..4], &mut output, 2..4);
136///
137/// assert_eq!(&output[0], &[1, 3, 1, 3]);
138/// assert_eq!(&output[1], &[2, 4, 2, 4]);
139/// ```
140///
141/// # Panics
142/// Panics when any of the following are true:
143/// * `output.len() < CHANNELS`
144/// * `output_range` is out-of-bounds for any output channel
145/// * `input.len() < (output_range.end - output_range.start) * CHANNELS`
146/// * `CHANNELS` == 0
147pub fn deinterleave<T: Copy, Vout: AsMut<[T]>, const CHANNELS: usize>(
148    input: &[T],
149    output: &mut [Vout],
150    output_range: Range<usize>,
151) {
152    assert!(CHANNELS > 0);
153    assert!(output.len() >= CHANNELS);
154
155    if output_range.is_empty() {
156        return;
157    }
158
159    assert!(input.len() >= (output_range.end - output_range.start) * CHANNELS);
160
161    for ch in output.iter_mut() {
162        let ch = ch.as_mut();
163        assert!(output_range.start <= ch.len());
164        assert!(output_range.end <= ch.len());
165    }
166
167    // SAFETY: All of the required safety conditions were checked above.
168    unsafe {
169        deinterleave_unchecked::<T, _, CHANNELS>(input, output, output_range);
170    }
171}
172
173/// De-interleave the given channels into the output buffer.
174///
175/// No bounds checking will occur.
176///
177/// * `input` - The interleaved input channels.
178/// * `output` - The de-interleaved output channels to write to.
179/// * `output_range` - The range in each output channel to write to.
180///
181/// # Example
182///
183/// ```
184/// # use fast_interleave::*;
185/// let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
186/// let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
187///
188/// unsafe { deinterleave_unchecked::<_, _, 2>(&input, &mut output, 0..4); }
189///
190/// assert_eq!(&output[0], &[1, 3, 5, 7]);
191/// assert_eq!(&output[1], &[2, 4, 6, 8]);
192///
193/// // Deinterleave into a range in output:
194/// unsafe { deinterleave_unchecked::<_, _, 2>(&input[0..4], &mut output, 2..4); }
195///
196/// assert_eq!(&output[0], &[1, 3, 1, 3]);
197/// assert_eq!(&output[1], &[2, 4, 2, 4]);
198/// ```
199///
200/// # Safety
201/// The caller must uphold that all of the following conditions are true:
202/// * `output.len() >= CHANNELS`
203/// * `output_range` is within bounds for every output channel
204/// * `input.len() >= (output_range.end - output_range.start) * CHANNELS`
205/// * `CHANNELS` > 0
206pub unsafe fn deinterleave_unchecked<T: Copy, Vout: AsMut<[T]>, const CHANNELS: usize>(
207    input: &[T],
208    output: &mut [Vout],
209    output_range: Range<usize>,
210) {
211    if output_range.is_empty() {
212        return;
213    }
214
215    unsafe {
216        for i in 0..(output_range.end - output_range.start) {
217            for ch_i in 0..CHANNELS {
218                *output
219                    .get_unchecked_mut(ch_i)
220                    .as_mut()
221                    .get_unchecked_mut(output_range.start + i) =
222                    *input.get_unchecked((i * CHANNELS) + ch_i)
223            }
224        }
225    }
226}
227
228/// Interleave a variable number of input channels into the output buffer
229/// with a variable number of channels.
230///
231/// * `input` - The input channels.
232/// * `input_range` - The range in each channel in `input` to read from.
233/// * `output` - The interleaved output buffer to write to.
234/// * `num_out_channels` - The number of interleaved channels in `output`.
235///
236/// Note, if `num_out_channels.get() > input.len()`, then the extra samples in
237/// each output frame will be left untouched.
238///
239/// # Example
240///
241/// ```
242/// # use fast_interleave::*;
243/// # use std::num::NonZeroUsize;
244/// let input: Vec<Vec<i32>> = vec![vec![1, 3, 5, 7], vec![2, 4, 6, 8]];
245/// let mut output: Vec<i32> = vec![0; 12];
246///
247/// interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(3).unwrap());
248///
249/// assert_eq!(&output, &[1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0]);
250/// ```
251///
252/// # Panics
253/// Panics when any of the following are true:
254/// * `input_range` is out-of-bounds for any input channel
255/// * `output.len() < (input_range.end - input_range.start) * num_out_channels.get()`
256pub fn interleave_variable<T: Copy, Vin: AsRef<[T]>>(
257    input: &[Vin],
258    input_range: Range<usize>,
259    output: &mut [T],
260    num_out_channels: NonZeroUsize,
261) {
262    if input_range.is_empty() || input.is_empty() {
263        return;
264    }
265
266    let in_frames = input_range.end - input_range.start;
267
268    if num_out_channels.get() == 1 {
269        // Mono, no need to interleave.
270        output[..in_frames].copy_from_slice(&input[0].as_ref()[input_range.clone()]);
271
272        return;
273    }
274
275    if num_out_channels.get() == 2 && input.len() >= 2 {
276        // Provide an optimized loop for stereo since it is a common case.
277        interleave::<T, _, 2>(input, input_range, output);
278        return;
279    }
280
281    assert!(output.len() >= (input_range.end - input_range.start) * num_out_channels.get());
282
283    for (ch_i, in_ch) in (0..num_out_channels.get()).zip(input.iter()) {
284        let in_ch = in_ch.as_ref();
285
286        assert!(input_range.start < in_ch.len() && input_range.end <= in_ch.len());
287
288        // SAFETY: We have checked that the output slice has sufficient length and that
289        // the `input_range` is within bounds of the input channel slice.
290        unsafe {
291            for i in 0..(input_range.end - input_range.start) {
292                *output.get_unchecked_mut((i * num_out_channels.get()) + ch_i) =
293                    *in_ch.get_unchecked(input_range.start + i);
294            }
295        }
296    }
297}
298
299/// Deinterleave the given data with a variable number of channels into
300/// the output buffers with a variable number of channels.
301///
302/// * `input` - The interleaved input data.
303/// * `num_in_channels` - The number of interleaved channels in `input`.
304/// * `output` - The de-interleaved output buffer to write to.
305/// * `out_range` - The range in each channel in `output` to write to.
306///
307/// Note, if `output.len() > num_in_channels.get()`, then the extra output channels
308/// will be left untouched.
309///
310/// # Example
311///
312/// ```
313/// # use fast_interleave::*;
314/// # use std::num::NonZeroUsize;
315/// let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
316/// let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4], vec![0; 4]];
317///
318/// deinterleave_variable(&input, NonZeroUsize::new(2).unwrap(), &mut output, 0..4);
319///
320/// assert_eq!(&output[0], &[1, 3, 5, 7]);
321/// assert_eq!(&output[1], &[2, 4, 6, 8]);
322/// assert_eq!(&output[2], &[0, 0, 0, 0]);
323/// ```
324///
325/// # Panics
326/// Panics when any of the following are true:
327/// * `output_range` is out-of-bounds for any output channel
328/// * `input.len() < (output_range.end - output_range.start) * num_in_channels.get()`
329pub fn deinterleave_variable<T: Copy, Vout: AsMut<[T]>>(
330    input: &[T],
331    num_in_channels: NonZeroUsize,
332    output: &mut [Vout],
333    output_range: Range<usize>,
334) {
335    if output_range.is_empty() || output.is_empty() {
336        return;
337    }
338
339    let out_frames = output_range.end - output_range.start;
340
341    if num_in_channels.get() == 1 {
342        // Mono, no need to deinterleave.
343        output[0].as_mut()[output_range.clone()].copy_from_slice(&input[..out_frames]);
344
345        return;
346    }
347
348    if num_in_channels.get() == 2 && output.len() >= 2 {
349        // Provide an optimized loop for stereo since it is a common case.
350        deinterleave::<T, _, 2>(input, output, output_range);
351        return;
352    }
353
354    assert!(input.len() >= (output_range.end - output_range.start) * num_in_channels.get());
355
356    for (ch_i, out_ch) in (0..num_in_channels.get()).zip(output.iter_mut()) {
357        let out_ch = out_ch.as_mut();
358
359        assert!(output_range.start < out_ch.len() && output_range.end <= out_ch.len());
360
361        // SAFETY: We have checked that the input slice has sufficient length and that
362        // the `output_range` is within bounds of the output channel slice.
363        unsafe {
364            for i in 0..(output_range.end - output_range.start) {
365                *out_ch.get_unchecked_mut(output_range.start + i) =
366                    *input.get_unchecked((i * num_in_channels.get()) + ch_i);
367            }
368        }
369    }
370}
371
372#[cfg(test)]
373mod tests {
374    use super::*;
375
376    #[test]
377    fn test_interleave() {
378        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
379        let mut output: Vec<i32> = vec![0; 4];
380        interleave::<_, _, 1>(&input, 1..4, &mut output);
381        assert_eq!(&output, &[2, 3, 4, 0]);
382
383        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
384        let mut output: Vec<i32> = vec![0; 8];
385        interleave::<_, _, 2>(&input, 1..4, &mut output);
386        assert_eq!(&output, &[2, 6, 3, 7, 4, 8, 0, 0]);
387
388        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
389        let mut output: Vec<i32> = vec![0; 12];
390        interleave::<_, _, 3>(&input, 1..4, &mut output);
391        assert_eq!(&output, &[2, 6, 10, 3, 7, 11, 4, 8, 12, 0, 0, 0]);
392    }
393
394    #[test]
395    fn test_deinterleave() {
396        let input: Vec<i32> = vec![1, 2, 3, 4];
397        let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
398        deinterleave::<_, _, 1>(&input, &mut output, 1..4);
399        assert_eq!(&output[0], &[0, 1, 2, 3]);
400
401        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
402        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
403        deinterleave::<_, _, 2>(&input, &mut output, 1..4);
404        assert_eq!(&output[0], &[0, 1, 3, 5]);
405        assert_eq!(&output[1], &[0, 2, 4, 6]);
406
407        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
408        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4], vec![0; 4]];
409        deinterleave::<_, _, 3>(&input, &mut output, 1..4);
410        assert_eq!(&output[0], &[0, 1, 4, 7]);
411        assert_eq!(&output[1], &[0, 2, 5, 8]);
412        assert_eq!(&output[2], &[0, 3, 6, 9]);
413    }
414
415    #[test]
416    fn test_interleave_variable() {
417        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
418        let mut output: Vec<i32> = vec![0; 4];
419        interleave_variable(&input, 1..4, &mut output, NonZeroUsize::new(1).unwrap());
420        assert_eq!(&output, &[2, 3, 4, 0]);
421
422        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
423        let mut output: Vec<i32> = vec![0; 8];
424        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(1).unwrap());
425        assert_eq!(&output, &[1, 2, 3, 4, 0, 0, 0, 0]);
426
427        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
428        let mut output: Vec<i32> = vec![0; 8];
429        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(2).unwrap());
430        assert_eq!(&output, &[1, 0, 2, 0, 3, 0, 4, 0]);
431
432        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
433        let mut output: Vec<i32> = vec![0; 8];
434        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(2).unwrap());
435        assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
436
437        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
438        let mut output: Vec<i32> = vec![0; 12];
439        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(3).unwrap());
440        assert_eq!(&output, &[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]);
441    }
442
443    #[test]
444    fn test_deinterleave_variable() {
445        let input: Vec<i32> = vec![1, 2, 3, 4];
446        let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
447        deinterleave_variable(&input, NonZeroUsize::new(1).unwrap(), &mut output, 1..4);
448        assert_eq!(&output[0], &[0, 1, 2, 3]);
449
450        let input: Vec<i32> = vec![1, 2, 3, 4];
451        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
452        deinterleave_variable(&input, NonZeroUsize::new(1).unwrap(), &mut output, 0..4);
453        assert_eq!(&output[0], &[1, 2, 3, 4]);
454        assert_eq!(&output[1], &[0, 0, 0, 0]);
455
456        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
457        let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
458        deinterleave_variable(&input, NonZeroUsize::new(2).unwrap(), &mut output, 0..4);
459        assert_eq!(&output[0], &[1, 3, 5, 7]);
460
461        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
462        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
463        deinterleave_variable(&input, NonZeroUsize::new(2).unwrap(), &mut output, 0..4);
464        assert_eq!(&output[0], &[1, 3, 5, 7]);
465        assert_eq!(&output[1], &[2, 4, 6, 8]);
466
467        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
468        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4], vec![0; 4]];
469        deinterleave_variable(&input, NonZeroUsize::new(3).unwrap(), &mut output, 0..4);
470        assert_eq!(&output[0], &[1, 4, 7, 10]);
471        assert_eq!(&output[1], &[2, 5, 8, 11]);
472        assert_eq!(&output[2], &[3, 6, 9, 12]);
473    }
474}