audioadapter/
audio.rs

1//! # [audio](https://crates.io/crates/audio)  crate compatibility
2//!
3//! This module implements the `audioadapter` traits
4//! for `ExactSizeBuf` buffers from the [audio](https://crates.io/crates/audio) crate.
5
6use crate::{Adapter, AdapterMut};
7
8use audio_core::{Buf, BufMut, Channel, ChannelMut, ExactSizeBuf, Sample};
9
10impl<'a, T, U> Adapter<'a, T> for U
11where
12    T: Clone + Sample + 'a,
13    U: Buf<Sample = T> + ExactSizeBuf<Sample = T>,
14{
15    fn channels(&self) -> usize {
16        self.channels()
17    }
18
19    fn frames(&self) -> usize {
20        self.frames()
21    }
22
23    unsafe fn read_sample_unchecked(&self, channel: usize, frame: usize) -> T {
24        self.get_channel(channel).unwrap().get(frame).unwrap()
25    }
26
27    fn write_from_channel_to_slice(&self, channel: usize, skip: usize, slice: &mut [T]) -> usize {
28        if channel >= self.channels() || skip >= self.frames() {
29            return 0;
30        }
31        let frames_to_write = if (self.frames() - skip) < slice.len() {
32            self.frames() - skip
33        } else {
34            slice.len()
35        };
36        let chan = self.get_channel(channel).unwrap();
37        chan.iter()
38            .skip(skip)
39            .take(frames_to_write)
40            .zip(slice.iter_mut())
41            .for_each(|(s, o)| *o = s);
42        frames_to_write
43    }
44}
45
46impl<'a, T, U> AdapterMut<'a, T> for U
47where
48    T: Clone + Sample + 'a,
49    U: BufMut<Sample = T> + ExactSizeBuf<Sample = T>,
50{
51    unsafe fn write_sample_unchecked(&mut self, channel: usize, frame: usize, value: &T) -> bool {
52        *self
53            .get_channel_mut(channel)
54            .unwrap()
55            .get_mut(frame)
56            .unwrap() = *value;
57        false
58    }
59
60    fn write_from_slice_to_channel(
61        &mut self,
62        channel: usize,
63        skip: usize,
64        slice: &[T],
65    ) -> (usize, usize) {
66        if channel >= Adapter::channels(self) || skip >= Adapter::frames(self) {
67            return (0, 0);
68        }
69        let frames_to_read = if (Adapter::frames(self) - skip) < slice.len() {
70            Adapter::frames(self) - skip
71        } else {
72            slice.len()
73        };
74        let mut chan = self.get_channel_mut(channel).unwrap();
75        chan.iter_mut()
76            .skip(skip)
77            .take(frames_to_read)
78            .zip(slice.iter())
79            .for_each(|(s, o)| *s = *o);
80        (frames_to_read, 0)
81    }
82}
83
84//   _____         _
85//  |_   _|__  ___| |_ ___
86//    | |/ _ \/ __| __/ __|
87//    | |  __/\__ \ |_\__ \
88//    |_|\___||___/\__|___/
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93    use crate::adapter_to_float::ConvertNumbers;
94    use crate::byte_slice_as_type;
95    use crate::sample::RawSample;
96    use crate::sample::I16LE;
97    use audio::wrap;
98
99    #[test]
100    fn read_indirect() {
101        let buf = wrap::interleaved(&[1, 2, 3, 4, 5, 6, 7, 8], 2);
102        assert_eq!(unsafe { buf.read_sample_unchecked(0, 0) }, 1);
103        assert_eq!(unsafe { buf.read_sample_unchecked(1, 0) }, 2);
104        assert_eq!(unsafe { buf.read_sample_unchecked(0, 1) }, 3);
105        assert_eq!(unsafe { buf.read_sample_unchecked(1, 1) }, 4);
106    }
107
108    #[test]
109    fn write_indirect() {
110        let mut buf = audio::buf::Interleaved::<i32>::with_topology(2, 4);
111        unsafe {
112            buf.write_sample_unchecked(0, 0, &1);
113            buf.write_sample_unchecked(1, 0, &2);
114            buf.write_sample_unchecked(0, 1, &3);
115            buf.write_sample_unchecked(1, 1, &4);
116        }
117        assert_eq!(buf.get_channel(0).unwrap().get(0).unwrap(), 1);
118        assert_eq!(buf.get_channel(1).unwrap().get(0).unwrap(), 2);
119        assert_eq!(buf.get_channel(0).unwrap().get(1).unwrap(), 3);
120        assert_eq!(buf.get_channel(1).unwrap().get(1).unwrap(), 4);
121    }
122
123    #[cfg(feature = "std")]
124    #[test]
125    fn read_to_slice() {
126        let mut other = vec![0; 3];
127        let buf = wrap::interleaved(&[1, 2, 3, 4, 5, 6, 7, 8], 2);
128        buf.write_from_channel_to_slice(0, 1, &mut other);
129        assert_eq!(other[0], 3);
130        assert_eq!(other[1], 5);
131        assert_eq!(other[2], 7);
132    }
133
134    #[cfg(feature = "std")]
135    #[test]
136    fn write_to_slice() {
137        let other = vec![1, 2, 3];
138        let mut buf = audio::buf::Interleaved::<i32>::with_topology(2, 4);
139        buf.write_from_slice_to_channel(0, 1, &other);
140        assert_eq!(buf.get_channel(0).unwrap().get(0).unwrap(), 0);
141        assert_eq!(buf.get_channel(0).unwrap().get(1).unwrap(), 1);
142        assert_eq!(buf.get_channel(0).unwrap().get(2).unwrap(), 2);
143        assert_eq!(buf.get_channel(0).unwrap().get(3).unwrap(), 3);
144    }
145
146    #[test]
147    fn read_direct() {
148        let buf = wrap::interleaved(&[1, 2, 3, 4, 5, 6, 7, 8], 2);
149        assert_eq!(buf.read_sample(0, 0), Some(1));
150        assert_eq!(buf.read_sample(1, 0), Some(2));
151        assert_eq!(buf.read_sample(0, 1), Some(3));
152        assert_eq!(buf.read_sample(1, 1), Some(4));
153    }
154
155    #[test]
156    fn write_direct() {
157        let mut buf = audio::buf::Interleaved::<i32>::with_topology(2, 4);
158        buf.write_sample(0, 0, &1).unwrap();
159        buf.write_sample(1, 0, &2).unwrap();
160        buf.write_sample(0, 1, &3).unwrap();
161        buf.write_sample(1, 1, &4).unwrap();
162        assert_eq!(buf.get_channel(0).unwrap().get(0).unwrap(), 1);
163        assert_eq!(buf.get_channel(1).unwrap().get(0).unwrap(), 2);
164        assert_eq!(buf.get_channel(0).unwrap().get(1).unwrap(), 3);
165        assert_eq!(buf.get_channel(1).unwrap().get(1).unwrap(), 4);
166    }
167
168    #[test]
169    fn test_convert_i16() {
170        let data: [i16; 6] = [0, i16::MIN, 1 << 14, -(1 << 14), 1 << 13, -(1 << 13)];
171        let buffer = wrap::interleaved(&data, 2);
172        let converter = ConvertNumbers::<_, f32>::new(&buffer as &dyn Adapter<i16>);
173        assert_eq!(converter.read_sample(0, 0).unwrap(), 0.0);
174        assert_eq!(converter.read_sample(1, 0).unwrap(), -1.0);
175        assert_eq!(converter.read_sample(0, 1).unwrap(), 0.5);
176        assert_eq!(converter.read_sample(1, 1).unwrap(), -0.5);
177        assert_eq!(converter.read_sample(0, 2).unwrap(), 0.25);
178        assert_eq!(converter.read_sample(1, 2).unwrap(), -0.25);
179    }
180
181    #[test]
182    fn test_convert_i16_bytes_with_converter() {
183        let data: [u8; 12] = [0, 0, 0, 128, 0, 64, 0, 192, 0, 32, 0, 224];
184        let data_view = byte_slice_as_type!(data, I16LE);
185        let buffer = wrap::interleaved(data_view, 2);
186        let converter =
187            ConvertNumbers::<&dyn Adapter<I16LE>, f32>::new(&buffer as &dyn Adapter<I16LE>);
188        assert_eq!(converter.read_sample(0, 0).unwrap(), 0.0);
189        assert_eq!(converter.read_sample(1, 0).unwrap(), -1.0);
190        assert_eq!(converter.read_sample(0, 1).unwrap(), 0.5);
191        assert_eq!(converter.read_sample(1, 1).unwrap(), -0.5);
192        assert_eq!(converter.read_sample(0, 2).unwrap(), 0.25);
193        assert_eq!(converter.read_sample(1, 2).unwrap(), -0.25);
194    }
195
196    #[test]
197    fn test_convert_i16_bytes_with_rawsample() {
198        let data: [u8; 12] = [0, 0, 0, 128, 0, 64, 0, 192, 0, 32, 0, 224];
199        let data_view = byte_slice_as_type!(data, I16LE);
200        let buffer = wrap::interleaved(data_view, 2);
201        assert_eq!(
202            buffer.read_sample(0, 0).unwrap().to_scaled_float::<f32>(),
203            0.0
204        );
205        assert_eq!(
206            buffer.read_sample(1, 0).unwrap().to_scaled_float::<f32>(),
207            -1.0
208        );
209        assert_eq!(
210            buffer.read_sample(0, 1).unwrap().to_scaled_float::<f32>(),
211            0.5
212        );
213        assert_eq!(
214            buffer.read_sample(1, 1).unwrap().to_scaled_float::<f32>(),
215            -0.5
216        );
217        assert_eq!(
218            buffer.read_sample(0, 2).unwrap().to_scaled_float::<f32>(),
219            0.25
220        );
221        assert_eq!(
222            buffer.read_sample(1, 2).unwrap().to_scaled_float::<f32>(),
223            -0.25
224        );
225    }
226}