1use crate::prelude::*;
2use rand::Rng;
3use std::ops::Range;
4
5#[repr(align(64))]
9#[derive(Clone)]
10pub struct OwnedAudioBuffer {
11 data: Vec<f32>,
12 channel_count: usize,
13 frame_count: usize,
14 sample_rate: usize,
15}
16
17impl OwnedAudioBuffer {
18 pub fn new(frame_count: usize, channel_count: usize, sample_rate: usize) -> Self {
20 Self {
21 data: vec![0.0; frame_count * channel_count],
22 channel_count,
23 frame_count,
24 sample_rate,
25 }
26 }
27
28 pub fn from_slice(data: &[f32], channel_count: usize, sample_rate: usize) -> Self {
32 let mut buffer = Self::new(data.len(), 1, sample_rate);
33
34 for channel in 0..channel_count {
35 buffer.fill_from_slice(data, SampleLocation::channel(channel));
36 }
37
38 buffer
39 }
40
41 pub fn from_buffer(buffer: &dyn AudioBuffer) -> Self {
43 let mut new_buffer = Self::new(
44 buffer.frame_count(),
45 buffer.channel_count(),
46 buffer.sample_rate(),
47 );
48
49 new_buffer.copy_from(
50 buffer,
51 SampleLocation::origin(),
52 SampleLocation::origin(),
53 buffer.channel_count(),
54 buffer.frame_count(),
55 );
56
57 new_buffer
58 }
59
60 pub fn extended_with_buffer(&self, buffer: &dyn AudioBuffer) -> Self {
64 assert_eq!(buffer.channel_count(), self.channel_count());
65 assert_eq!(buffer.sample_rate(), self.sample_rate());
66
67 let mut new_buffer = Self::new(
68 self.frame_count() + buffer.frame_count(),
69 self.channel_count(),
70 self.sample_rate(),
71 );
72
73 new_buffer.copy_from(
74 self,
75 SampleLocation::origin(),
76 SampleLocation::origin(),
77 self.channel_count(),
78 self.frame_count(),
79 );
80
81 new_buffer.copy_from(
82 buffer,
83 SampleLocation::origin(),
84 SampleLocation::frame(self.frame_count()),
85 buffer.channel_count(),
86 buffer.frame_count(),
87 );
88
89 new_buffer
90 }
91
92 pub fn white_noise(frame_count: usize, channel_count: usize, sample_rate: usize) -> Self {
94 let mut buffer = Self::new(frame_count, channel_count, sample_rate);
95
96 let mut random_generator = rand::thread_rng();
97
98 for frame in buffer.frame_iter() {
99 let sample_value = random_generator.gen_range(-1.0..=1.0);
100 buffer.set_sample(frame, sample_value);
101 }
102
103 buffer
104 }
105
106 pub fn padded_to_length(&self, frame_count: usize) -> Self {
108 let mut buffer = Self::new(frame_count, self.channel_count(), self.sample_rate());
109
110 buffer.copy_from(
111 self,
112 SampleLocation::origin(),
113 SampleLocation::origin(),
114 self.channel_count(),
115 self.frame_count(),
116 );
117
118 buffer
119 }
120
121 pub fn sine(
123 frame_count: usize,
124 channel_count: usize,
125 sample_rate: usize,
126 frequency: f64,
127 amplitude: f64,
128 ) -> Self {
129 debug_assert!(channel_count > 0);
130
131 let mut buffer = Self::new(frame_count, channel_count, sample_rate);
132
133 let channel = buffer.get_channel_data_mut(SampleLocation::origin());
134
135 for (index, sample) in channel.iter_mut().enumerate() {
136 let time = index as f64 / sample_rate as f64;
137 *sample = (amplitude * (std::f64::consts::TAU * frequency * time).sin()) as f32;
138 }
139
140 for channel in 1..channel_count {
141 let source_location = SampleLocation::channel(0);
142 buffer.duplicate_channel(source_location, channel, frame_count);
143 }
144
145 buffer
146 }
147
148 pub fn step(
150 frame_count: usize,
151 channel_count: usize,
152 sample_rate: usize,
153 step_range: Range<usize>,
154 ) -> Self {
155 let mut buffer = Self::new(frame_count, channel_count, sample_rate);
156
157 let channel = buffer.get_channel_data_mut(SampleLocation::origin());
158
159 for (index, sample) in channel.iter_mut().enumerate() {
160 *sample = if step_range.contains(&index) {
161 1.0
162 } else {
163 0.0
164 };
165 }
166
167 for channel in 1..channel_count {
168 let source_location = SampleLocation::channel(0);
169 buffer.duplicate_channel(source_location, channel, frame_count);
170 }
171
172 buffer
173 }
174
175 fn get_sample_location_range(&self, sample_location: &SampleLocation) -> Range<usize> {
176 let start = sample_location.channel * self.frame_count + sample_location.frame;
177 let end = (sample_location.channel + 1) * self.frame_count;
178 start..end
179 }
180}
181
182impl AudioBuffer for OwnedAudioBuffer {
183 fn channel_count(&self) -> usize {
184 self.channel_count
185 }
186
187 fn frame_count(&self) -> usize {
188 self.frame_count
189 }
190
191 fn sample_rate(&self) -> usize {
192 self.sample_rate
193 }
194
195 fn get_channel_data(&self, sample_location: SampleLocation) -> &[f32] {
196 let range = self.get_sample_location_range(&sample_location);
197 &self.data[range]
198 }
199
200 fn get_channel_data_mut(&mut self, sample_location: SampleLocation) -> &mut [f32] {
201 let range = self.get_sample_location_range(&sample_location);
202 &mut self.data[range]
203 }
204
205 fn duplicate_channel(&mut self, source: SampleLocation, to_channel: usize, frame_count: usize) {
206 let source_range = self.get_sample_location_range(&source);
207 let destination_range = self.get_sample_location_range(&source.with_channel(to_channel));
208 self.data.copy_within(
209 source_range.start..source_range.start + frame_count,
210 destination_range.start,
211 );
212 }
213}
214
215#[cfg(test)]
216mod tests {
217
218 use super::*;
219 use rand::Rng;
220
221 fn random_sample() -> f32 {
222 let mut generator = rand::thread_rng();
223 generator.gen_range(-1.0_f32..=1.0_f32)
224 }
225
226 fn is_empty(buffer: &dyn AudioBuffer) -> bool {
227 for channel in 0..buffer.channel_count() {
228 let data = buffer.get_channel_data(SampleLocation::channel(channel));
229 if !data.iter().all(|value| relative_eq!(*value, 0.0)) {
230 return false;
231 }
232 }
233
234 true
235 }
236
237 #[test]
238 fn starts_empty() {
239 let frame_count = 1000;
240 let channel_count = 2;
241 let sample_rate = 44100;
242 let buffer = OwnedAudioBuffer::new(frame_count, channel_count, sample_rate);
243 assert!(is_empty(&buffer));
244 }
245
246 #[test]
247 fn clear_resets_all_samples() {
248 let frame_count = 1000;
249 let channel_count = 2;
250 let sample_rate = 44100;
251 let mut buffer = OwnedAudioBuffer::white_noise(frame_count, channel_count, sample_rate);
252
253 assert!(!is_empty(&buffer));
254 buffer.clear();
255 assert!(is_empty(&buffer));
256 }
257
258 #[test]
259 fn set_and_get_a_sample() {
260 let frame_count = 1000;
261 let channel_count = 2;
262 let sample_rate = 44100;
263 let mut buffer = OwnedAudioBuffer::new(frame_count, channel_count, sample_rate);
264
265 let frame_index = 53;
266 let channel_index = 1;
267 let location = SampleLocation::new(channel_index, frame_index);
268
269 let expected_sample = random_sample();
270 buffer.set_sample(location, expected_sample);
271
272 let actual_sample = buffer.get_sample(location);
273 assert_eq!(expected_sample, actual_sample);
274 }
275}