1use rtsan_standalone::{blocking, nonblocking};
2
3#[cfg(all(feature = "alloc", not(feature = "std")))]
4use alloc::{boxed::Box, vec, vec::Vec};
5#[cfg(all(feature = "std", not(feature = "alloc")))]
6use std::{boxed::Box, vec, vec::Vec};
7#[cfg(all(feature = "std", feature = "alloc"))]
8use std::{boxed::Box, vec, vec::Vec};
9
10use super::{view::AudioBlockMonoView, view_mut::AudioBlockMonoViewMut};
11use crate::{AudioBlock, AudioBlockMut, Sample};
12
13pub struct AudioBlockMono<S: Sample> {
38 data: Box<[S]>,
39 num_frames: usize,
40 num_frames_allocated: usize,
41}
42
43impl<S: Sample + Default> AudioBlockMono<S> {
44 #[blocking]
65 pub fn new(num_frames: usize) -> Self {
66 Self {
67 data: vec![S::default(); num_frames].into_boxed_slice(),
68 num_frames,
69 num_frames_allocated: num_frames,
70 }
71 }
72}
73
74impl<S: Sample> AudioBlockMono<S> {
75 #[blocking]
87 pub fn from_slice(samples: &[S]) -> Self {
88 Self {
89 data: samples.to_vec().into_boxed_slice(),
90 num_frames: samples.len(),
91 num_frames_allocated: samples.len(),
92 }
93 }
94
95 #[blocking]
108 pub fn from_slice_limited(samples: &[S], num_frames_visible: usize) -> Self {
109 assert!(num_frames_visible <= samples.len());
110 Self {
111 data: samples.to_vec().into_boxed_slice(),
112 num_frames: num_frames_visible,
113 num_frames_allocated: samples.len(),
114 }
115 }
116
117 #[blocking]
134 pub fn from_block(block: &impl AudioBlock<S>) -> Self {
135 assert!(
136 block.num_channels() > 0,
137 "Cannot create mono block from block with zero channels"
138 );
139
140 let mut data = Vec::with_capacity(block.num_frames());
141 block.channel_iter(0).for_each(|&v| data.push(v));
142
143 Self {
144 data: data.into_boxed_slice(),
145 num_frames: block.num_frames(),
146 num_frames_allocated: block.num_frames(),
147 }
148 }
149
150 #[nonblocking]
156 pub fn sample(&self, frame: usize) -> S {
157 assert!(frame < self.num_frames);
158 unsafe { *self.data.get_unchecked(frame) }
159 }
160
161 #[nonblocking]
167 pub fn sample_mut(&mut self, frame: usize) -> &mut S {
168 assert!(frame < self.num_frames);
169 unsafe { self.data.get_unchecked_mut(frame) }
170 }
171
172 #[nonblocking]
176 pub fn samples(&self) -> &[S] {
177 &self.data[..self.num_frames]
178 }
179
180 #[nonblocking]
184 pub fn samples_mut(&mut self) -> &mut [S] {
185 let num_frames = self.num_frames;
186 &mut self.data[..num_frames]
187 }
188
189 #[nonblocking]
194 pub fn raw_data(&self) -> &[S] {
195 &self.data
196 }
197
198 #[nonblocking]
203 pub fn raw_data_mut(&mut self) -> &mut [S] {
204 &mut self.data
205 }
206
207 #[nonblocking]
209 pub fn view(&self) -> AudioBlockMonoView<'_, S> {
210 AudioBlockMonoView::from_slice_limited(
211 self.raw_data(),
212 self.num_frames,
213 self.num_frames_allocated,
214 )
215 }
216
217 #[nonblocking]
219 pub fn view_mut(&mut self) -> AudioBlockMonoViewMut<'_, S> {
220 let num_frames = self.num_frames;
221 let num_frames_allocated = self.num_frames_allocated;
222 AudioBlockMonoViewMut::from_slice_limited(
223 self.raw_data_mut(),
224 num_frames,
225 num_frames_allocated,
226 )
227 }
228}
229
230impl<S: Sample> AudioBlock<S> for AudioBlockMono<S> {
231 type PlanarView = [S; 0];
232
233 #[nonblocking]
234 fn num_channels(&self) -> u16 {
235 1
236 }
237
238 #[nonblocking]
239 fn num_frames(&self) -> usize {
240 self.num_frames
241 }
242
243 #[nonblocking]
244 fn num_channels_allocated(&self) -> u16 {
245 1
246 }
247
248 #[nonblocking]
249 fn num_frames_allocated(&self) -> usize {
250 self.num_frames_allocated
251 }
252
253 #[nonblocking]
254 fn layout(&self) -> crate::BlockLayout {
255 crate::BlockLayout::Sequential
256 }
257
258 #[nonblocking]
259 fn sample(&self, channel: u16, frame: usize) -> S {
260 assert_eq!(channel, 0, "AudioBlockMono only has channel 0");
261 self.sample(frame)
262 }
263
264 #[nonblocking]
265 fn channel_iter(&self, channel: u16) -> impl Iterator<Item = &S> {
266 assert_eq!(channel, 0, "AudioBlockMono only has channel 0");
267 self.samples().iter()
268 }
269
270 #[nonblocking]
271 fn channels_iter(&self) -> impl Iterator<Item = impl Iterator<Item = &S> + '_> + '_ {
272 core::iter::once(self.samples().iter())
273 }
274
275 #[nonblocking]
276 fn frame_iter(&self, frame: usize) -> impl Iterator<Item = &S> {
277 assert!(frame < self.num_frames);
278 core::iter::once(&self.data[frame])
279 }
280
281 #[nonblocking]
282 fn frames_iter(&self) -> impl Iterator<Item = impl Iterator<Item = &S> + '_> + '_ {
283 self.data.iter().take(self.num_frames).map(core::iter::once)
284 }
285
286 #[nonblocking]
287 fn as_view(&self) -> impl AudioBlock<S> {
288 AudioBlockMonoView::from_slice_limited(
289 self.raw_data(),
290 self.num_frames,
291 self.num_frames_allocated,
292 )
293 }
294}
295
296impl<S: Sample> AudioBlockMut<S> for AudioBlockMono<S> {
297 type PlanarViewMut = [S; 0];
298
299 #[nonblocking]
300 fn set_num_channels_visible(&mut self, num_channels: u16) {
301 assert_eq!(
302 num_channels, 1,
303 "AudioBlockMono can only have 1 channel, got {}",
304 num_channels
305 );
306 }
307
308 #[nonblocking]
309 fn set_num_frames_visible(&mut self, num_frames: usize) {
310 assert!(
311 num_frames <= self.num_frames_allocated,
312 "Cannot set visible frames ({}) beyond allocated frames ({})",
313 num_frames,
314 self.num_frames_allocated
315 );
316 self.num_frames = num_frames;
317 }
318
319 #[nonblocking]
320 fn sample_mut(&mut self, channel: u16, frame: usize) -> &mut S {
321 assert_eq!(channel, 0, "AudioBlockMono only has channel 0");
322 self.sample_mut(frame)
323 }
324
325 #[nonblocking]
326 fn channel_iter_mut(&mut self, channel: u16) -> impl Iterator<Item = &mut S> {
327 assert_eq!(channel, 0, "AudioBlockMono only has channel 0");
328 self.samples_mut().iter_mut()
329 }
330
331 #[nonblocking]
332 fn channels_iter_mut(
333 &mut self,
334 ) -> impl Iterator<Item = impl Iterator<Item = &mut S> + '_> + '_ {
335 core::iter::once(self.samples_mut().iter_mut())
336 }
337
338 #[nonblocking]
339 fn frame_iter_mut(&mut self, frame: usize) -> impl Iterator<Item = &mut S> {
340 assert!(frame < self.num_frames);
341 let ptr = &mut self.data[frame] as *mut S;
342 core::iter::once(unsafe { &mut *ptr })
344 }
345
346 #[nonblocking]
347 fn frames_iter_mut(&mut self) -> impl Iterator<Item = impl Iterator<Item = &mut S> + '_> + '_ {
348 let num_frames = self.num_frames;
349 self.data.iter_mut().take(num_frames).map(core::iter::once)
350 }
351
352 #[nonblocking]
353 fn as_view_mut(&mut self) -> impl AudioBlockMut<S> {
354 let num_frames = self.num_frames;
355 let num_frames_allocated = self.num_frames_allocated;
356 AudioBlockMonoViewMut::from_slice_limited(
357 self.raw_data_mut(),
358 num_frames,
359 num_frames_allocated,
360 )
361 }
362}
363
364impl<S: Sample + core::fmt::Debug> core::fmt::Debug for AudioBlockMono<S> {
365 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
366 writeln!(f, "AudioBlockMono {{")?;
367 writeln!(f, " num_frames: {}", self.num_frames)?;
368 writeln!(f, " num_frames_allocated: {}", self.num_frames_allocated)?;
369 writeln!(f, " samples: {:?}", self.samples())?;
370 writeln!(f, "}}")?;
371 Ok(())
372 }
373}
374
375#[cfg(test)]
376mod tests {
377 use super::*;
378 use rtsan_standalone::no_sanitize_realtime;
379
380 #[test]
381 fn test_new() {
382 let block = AudioBlockMono::<f32>::new(1024);
383 assert_eq!(block.num_frames(), 1024);
384 assert_eq!(block.num_frames_allocated(), 1024);
385 assert!(block.samples().iter().all(|&s| s == 0.0));
386 }
387
388 #[test]
389 fn test_from_slice() {
390 let samples = [1.0, 2.0, 3.0, 4.0, 5.0];
391 let block = AudioBlockMono::from_slice(&samples);
392 assert_eq!(block.num_frames(), 5);
393 assert_eq!(block.samples(), &samples);
394 }
395
396 #[test]
397 fn test_sample_access() {
398 let mut block = AudioBlockMono::from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0]);
399 assert_eq!(block.sample(0), 1.0);
400 assert_eq!(block.sample(2), 3.0);
401 assert_eq!(block.sample(4), 5.0);
402
403 *block.sample_mut(2) = 10.0;
404 assert_eq!(block.sample(2), 10.0);
405 }
406
407 #[test]
408 fn test_iterators() {
409 let mut block = AudioBlockMono::from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0]);
410
411 let sum: f32 = block.samples().iter().sum();
412 assert_eq!(sum, 15.0);
413
414 for sample in block.samples_mut() {
415 *sample *= 2.0;
416 }
417
418 assert_eq!(block.samples(), &[2.0, 4.0, 6.0, 8.0, 10.0]);
419 }
420
421 #[test]
422 #[should_panic]
423 #[no_sanitize_realtime]
424 fn test_resize_beyond_allocated() {
425 let mut block = AudioBlockMono::<f32>::new(10);
426 block.set_num_frames_visible(11);
427 }
428
429 #[test]
430 fn test_audio_block_trait() {
431 let block = AudioBlockMono::from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0]);
432
433 assert_eq!(block.num_channels(), 1);
434 assert_eq!(block.num_frames(), 5);
435
436 let channel: Vec<f32> = block.channel_iter(0).copied().collect();
438 assert_eq!(channel, vec![1.0, 2.0, 3.0, 4.0, 5.0]);
439
440 let frame: Vec<f32> = block.frame_iter(2).copied().collect();
442 assert_eq!(frame, vec![3.0]);
443 }
444
445 #[test]
446 fn test_audio_block_mut_trait() {
447 let mut block = AudioBlockMono::<f32>::new(5);
448
449 for (i, sample) in block.channel_iter_mut(0).enumerate() {
450 *sample = i as f32;
451 }
452
453 assert_eq!(block.samples(), &[0.0, 1.0, 2.0, 3.0, 4.0]);
454 }
455
456 #[test]
457 #[should_panic]
458 #[no_sanitize_realtime]
459 fn test_wrong_channel() {
460 let block = AudioBlockMono::<f32>::new(10);
461 let _ = block.channel_iter(1);
462 }
463
464 #[test]
465 #[should_panic]
466 #[no_sanitize_realtime]
467 fn test_sample_out_of_bounds() {
468 let block = AudioBlockMono::<f32>::new(10);
469 let _ = block.sample(10);
470 }
471
472 #[test]
473 fn test_from_block() {
474 use crate::AudioBlockInterleaved;
475
476 let mut multi = AudioBlockInterleaved::<f32>::new(2, 5);
477 for (i, sample) in multi.channel_iter_mut(0).enumerate() {
478 *sample = i as f32;
479 }
480
481 let mono = AudioBlockMono::from_block(&multi);
482 assert_eq!(mono.samples(), &[0.0, 1.0, 2.0, 3.0, 4.0]);
483 }
484
485 #[test]
486 fn test_views() {
487 let mut block = AudioBlockMono::from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0]);
488
489 {
491 let view = block.as_view();
492 assert_eq!(view.num_frames(), 5);
493 assert_eq!(view.sample(0, 2), 3.0);
494 }
495
496 {
498 let mut view_mut = block.as_view_mut();
499 *view_mut.sample_mut(0, 2) = 10.0;
500 }
501
502 assert_eq!(block.sample(2), 10.0);
503 }
504}