rabu/
buffer.rs

1//! This module contains a `Buffer` struct that is useful for many audio related tasks.
2//! It contains functions for iterating in audio specific ways and manipulating the sample data.
3
4use std::cmp::min;
5use std::ops::Range;
6
7use crate::units::{Channels, Samples};
8
9/// Multi-channel buffer for any type of audio. It has some utility
10/// functions that make common audio related tasks simpler.
11#[derive(Clone, Debug)]
12pub struct Buffer<T> {
13    data: Vec<T>,
14    num_channels: Channels,
15    num_samples: Samples,
16}
17
18impl<T> Buffer<T>
19where
20    T: Copy + Default + PartialEq,
21{
22    /// Tells you whether the buffer is filled with the default value of the contained type.
23    /// This is useful to check if the complete buffer is silent for example.
24    pub fn is_default_filled(&self) -> bool {
25        self.data.iter().all(|s| *s == T::default())
26    }
27}
28
29impl<T> Buffer<T>
30where
31    T: Copy + Default,
32{
33    /// Allocates a new buffer with the given number of channels and samples.
34    pub fn allocate(num_channels: Channels, num_samples: Samples) -> Self {
35        let total_num_samples = num_samples.as_usize() * num_channels.as_usize();
36        let mut data = Vec::with_capacity(total_num_samples);
37
38        data.resize(total_num_samples, T::default());
39
40        Self {
41            data,
42            num_channels,
43            num_samples,
44        }
45    }
46
47    /// Creates a new buffer with the given size, copying all data from self.
48    pub fn clone_resized(&self, num_channels: Channels, num_samples: Samples) -> Self {
49        let mut target = Self::allocate(num_channels, num_samples);
50
51        for channel in 0..min(self.num_channels(), num_channels).as_usize() {
52            for sample in 0..min(self.num_samples(), num_samples).as_usize() {
53                target.chan_mut(channel)[sample] = self.chan(channel)[sample];
54            }
55        }
56
57        target
58    }
59
60    /// Returns a reference to the internal buffer. Channels are stored one after the other,
61    /// so **not** interleaved!
62    pub fn data(&self) -> &[T] {
63        &self.data
64    }
65
66    /// Returns a mutable reference to the internal buffer. Channels are stored one after the other,
67    /// so **not** interleaved!
68    pub fn data_mut(&mut self) -> &mut [T] {
69        &mut self.data
70    }
71
72    /// Fills the buffer with the default value of the given type `T`. This can be useful to
73    /// make the buffer silent for example.
74    pub fn fill_default(&mut self) {
75        self.data.fill(T::default());
76    }
77
78    /// Gives you the channel numbers as a range. This can be useful when you want to iterate over
79    /// the channel indices.
80    pub fn channel_indices(&self) -> Range<usize> {
81        0..self.num_channels.as_usize()
82    }
83
84    /// Gives you the sample indices as a range. This can be useful when you want to use the
85    /// sample index in the loop for some reason.
86    pub fn sample_indices(&self) -> Range<usize> {
87        0..self.num_samples.as_usize()
88    }
89
90    /// Returns the number of channels in the buffer.
91    /// ```
92    /// use rabu::buffer::Buffer;
93    /// use rabu::units::{Channels, Samples};
94    ///
95    /// let buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(4));
96    ///
97    /// assert_eq!(buffer.num_channels(), Channels::from(2));
98    /// ```
99    pub fn num_channels(&self) -> Channels {
100        self.num_channels
101    }
102
103    /// Returns the number of samples that each channel contains
104    /// (**not the total number of samples in the buffer**):
105    /// ```
106    /// use rabu::buffer::Buffer;
107    /// use rabu::units::{Channels, Samples};
108    ///
109    /// let buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(4));
110    ///
111    /// assert_eq!(buffer.num_samples(), Samples::from(4));
112    /// ```
113    pub fn num_samples(&self) -> Samples {
114        self.num_samples
115    }
116
117    /// Returns a reference to the given channel (indexing starts at 0).
118    pub fn chan(&self, index: usize) -> &[T] {
119        if index >= self.num_channels.as_usize() {
120            panic!();
121        }
122
123        let start = index * self.num_samples.as_usize();
124        let end = start + self.num_samples.as_usize();
125        &self.data[start..end]
126    }
127
128    /// Returns a mutable reference to the given channel (indexing starts at 0).
129    pub fn chan_mut(&mut self, index: usize) -> &mut [T] {
130        if index >= self.num_channels().as_usize() {
131            panic!();
132        }
133
134        let start = index * self.num_samples.as_usize();
135        let end = start + self.num_samples.as_usize();
136        &mut self.data[start..end]
137    }
138
139    /// Returns an iterator to iterate over the channels in the buffer.
140    /// ```
141    /// use rabu::buffer::Buffer;
142    /// use rabu::units::{Channels, Samples};
143    ///
144    /// let buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(4));
145    ///
146    /// for channel in buffer.iter_chans() {
147    ///     for sample in channel {
148    ///         println!("sample {}", sample);
149    ///     }   
150    /// }
151    /// ```
152    pub fn iter_chans(&self) -> ChannelIterator<T> {
153        ChannelIterator {
154            buffer: self,
155            current_channel: 0,
156        }
157    }
158
159    /// Returns a mutable iterator to iterate over the channels in the buffer.
160    /// ```
161    /// use rabu::buffer::Buffer;
162    /// use rabu::units::{Channels, Samples};
163    ///
164    /// let mut buffer = Buffer::allocate(Channels::from(2), Samples::from(4));
165    ///
166    /// for channel in buffer.iter_chans_mut() {
167    ///     for sample in channel.iter_mut() {
168    ///         *sample = 1.0;
169    ///     }
170    /// }
171    /// ```
172    pub fn iter_chans_mut(&mut self) -> MutChannelIterator<T> {
173        MutChannelIterator {
174            buffer: self,
175            current_channel: 0,
176        }
177    }
178
179    /// Copies the content of self into the given target buffer.
180    /// This will panic if the buffers are not of the same size.
181    pub fn copy_into(&self, dest: &mut Self) {
182        assert_eq!(self.num_channels(), dest.num_channels());
183        assert_eq!(self.num_samples(), dest.num_samples());
184
185        for channel in self.channel_indices() {
186            for sample in self.sample_indices() {
187                dest.chan_mut(channel)[sample] = self.chan(channel)[sample];
188            }
189        }
190    }
191
192    /// Applies the given map function to all samples in the buffer.
193    /// This can be useful for multiplying all samples by some value, for example.
194    /// ```
195    /// use rabu::buffer::Buffer;
196    /// use rabu::units::{Channels, Samples};
197    ///
198    /// let mut buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(4));
199    ///
200    /// buffer.map_samples(|current_sample| current_sample + 2.0);
201    ///
202    /// assert!(buffer.data().iter().all(|v| *v == 2.0));
203    /// ```
204    pub fn map_samples(&mut self, mut func: impl FnMut(T) -> T) {
205        self.data
206            .iter_mut()
207            .for_each(|sample| *sample = func(*sample));
208    }
209
210    /// Iterate over all samples in the buffer, but make it behave like an interleaved buffer.
211    /// ```
212    /// use rabu::buffer::Buffer;
213    /// use rabu::units::{Channels, Samples};
214    ///
215    /// let mut buffer = Buffer::allocate(Channels::from(2), Samples::from(3));
216    ///
217    /// buffer.chan_mut(0)[0] = 1.0;
218    /// buffer.chan_mut(0)[1] = 2.0;
219    /// buffer.chan_mut(0)[2] = 3.0;
220    ///
221    /// let result: Vec<_> = buffer.iter_interleaved().collect();
222    ///
223    /// assert_eq!(result, vec![1.0, 0.0, 2.0, 0.0, 3.0, 0.0]);
224    ///```
225    pub fn iter_interleaved(&self) -> InterleavedIterator<T> {
226        InterleavedIterator {
227            buffer: self,
228            index: 0,
229        }
230    }
231}
232
233pub struct InterleavedIterator<'a, T>
234where
235    T: Copy + Default,
236{
237    buffer: &'a Buffer<T>,
238    index: usize,
239}
240
241impl<'a, T> Iterator for InterleavedIterator<'a, T>
242where
243    T: Copy + Default,
244{
245    type Item = T;
246
247    fn next(&mut self) -> Option<Self::Item> {
248        let num_channels = self.buffer.num_channels().as_usize();
249        let num_samples = self.buffer.num_samples().as_usize();
250        let total_num_samples = num_samples * num_channels;
251        if self.index >= total_num_samples {
252            None
253        } else {
254            let sample_index = self.index / num_channels;
255            let channel_index = self.index - (sample_index * num_channels);
256            self.index += 1;
257            Some(self.buffer.chan(channel_index)[sample_index])
258        }
259    }
260}
261
262pub struct MutChannelIterator<'a, T>
263where
264    T: Copy,
265{
266    buffer: &'a mut Buffer<T>,
267    current_channel: usize,
268}
269
270impl<'a, T> Iterator for MutChannelIterator<'a, T>
271where
272    T: Copy + Default,
273{
274    type Item = &'a mut [T];
275
276    fn next(&mut self) -> Option<Self::Item> {
277        if self.current_channel >= self.buffer.num_channels().as_usize() {
278            return None;
279        }
280        let channel = self.buffer.chan_mut(self.current_channel);
281        let channel_len = channel.len();
282        let channel_ptr = channel.as_mut_ptr();
283        self.current_channel += 1;
284        Some(unsafe { std::slice::from_raw_parts_mut(channel_ptr, channel_len) })
285    }
286}
287
288pub struct ChannelIterator<'a, T>
289where
290    T: Copy + Default,
291{
292    buffer: &'a Buffer<T>,
293    current_channel: usize,
294}
295
296impl<'a, T> Iterator for ChannelIterator<'a, T>
297where
298    T: Copy + Default,
299{
300    type Item = &'a [T];
301
302    fn next(&mut self) -> Option<Self::Item> {
303        if self.current_channel >= self.buffer.num_channels.as_usize() {
304            return None;
305        }
306        let channel = self.buffer.chan(self.current_channel);
307        self.current_channel += 1;
308        Some(channel)
309    }
310}
311
312#[cfg(test)]
313mod tests {
314    use super::*;
315
316    #[test]
317    fn interleaved_iterator() {
318        let mut buffer = Buffer::allocate(Channels::from(2), Samples::from(3));
319        buffer.chan_mut(0)[0] = 1.0;
320        buffer.chan_mut(0)[1] = 1.0;
321        buffer.chan_mut(0)[2] = 1.0;
322
323        let mut result = Vec::new();
324        for sample in buffer.iter_interleaved() {
325            result.push(sample);
326        }
327
328        assert_eq!(result, &[1.0, 0.0, 1.0, 0.0, 1.0, 0.0]);
329    }
330
331    #[test]
332    fn correct_num_samples_and_channels() {
333        let buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(10));
334        assert_eq!(buffer.num_samples(), Samples::from(10));
335        assert_eq!(buffer.num_channels(), Channels::from(2));
336    }
337
338    #[test]
339    fn index_into_channels() {
340        let buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(10));
341
342        assert_eq!(buffer.chan(0).len(), buffer.num_samples().as_usize());
343    }
344
345    #[test]
346    fn iterate_channels() {
347        let buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(10));
348        let mut num = 0;
349        for _chan in buffer.iter_chans() {
350            num += 1;
351        }
352
353        assert_eq!(Channels::from(num), buffer.num_channels());
354    }
355
356    #[test]
357    fn map_samples() {
358        let mut buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(3));
359        buffer.map_samples(|_| 0.5);
360        assert_eq!(buffer.chan(1)[2], 0.5);
361    }
362
363    #[test]
364    fn clone_with_new_bigger_size() {
365        let mut buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(3));
366        for chan in buffer.channel_indices() {
367            for samp in buffer.sample_indices() {
368                buffer.chan_mut(chan)[samp] = samp as f32;
369            }
370        }
371
372        let resized = buffer.clone_resized(Channels::from(3), Samples::from(4));
373
374        assert_eq!(resized.chan(0)[1], 1.0);
375        assert_eq!(resized.chan(0)[3], 0.0);
376
377        assert_eq!(resized.chan(1)[1], 1.0);
378        assert_eq!(resized.chan(1)[3], 0.0);
379
380        assert_eq!(resized.chan(2)[1], 0.0);
381    }
382
383    #[test]
384    fn clone_with_new_smaller_size() {
385        let mut buffer = Buffer::<f32>::allocate(Channels::from(2), Samples::from(3));
386        for chan in buffer.channel_indices() {
387            for samp in buffer.sample_indices() {
388                buffer.chan_mut(chan)[samp] = samp as f32;
389            }
390        }
391
392        let resized = buffer.clone_resized(Channels::from(1), Samples::from(2));
393
394        assert_eq!(resized.chan(0)[1], 1.0);
395        assert_eq!(resized.chan(0)[0], 0.0);
396    }
397}