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 ExactSizeIterator<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 ExactSizeIterator<Item = impl ExactSizeIterator<Item = &S>> {
272 core::iter::once(self.samples().iter())
273 }
274
275 #[nonblocking]
276 fn frame_iter(&self, frame: usize) -> impl ExactSizeIterator<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 ExactSizeIterator<Item = impl ExactSizeIterator<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 ExactSizeIterator<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 ExactSizeIterator<Item = impl ExactSizeIterator<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 ExactSizeIterator<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(
348 &mut self,
349 ) -> impl ExactSizeIterator<Item = impl ExactSizeIterator<Item = &mut S>> {
350 let num_frames = self.num_frames;
351 self.data.iter_mut().take(num_frames).map(core::iter::once)
352 }
353
354 #[nonblocking]
355 fn as_view_mut(&mut self) -> impl AudioBlockMut<S> {
356 let num_frames = self.num_frames;
357 let num_frames_allocated = self.num_frames_allocated;
358 AudioBlockMonoViewMut::from_slice_limited(
359 self.raw_data_mut(),
360 num_frames,
361 num_frames_allocated,
362 )
363 }
364}
365
366impl<S: Sample + core::fmt::Debug> core::fmt::Debug for AudioBlockMono<S> {
367 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
368 writeln!(f, "AudioBlockMono {{")?;
369 writeln!(f, " num_frames: {}", self.num_frames)?;
370 writeln!(f, " num_frames_allocated: {}", self.num_frames_allocated)?;
371 writeln!(f, " samples: {:?}", self.samples())?;
372 writeln!(f, "}}")?;
373 Ok(())
374 }
375}
376
377#[cfg(test)]
378mod tests {
379 use super::*;
380 use rtsan_standalone::no_sanitize_realtime;
381
382 #[test]
383 fn test_new() {
384 let block = AudioBlockMono::<f32>::new(1024);
385 assert_eq!(block.num_frames(), 1024);
386 assert_eq!(block.num_frames_allocated(), 1024);
387 assert!(block.samples().iter().all(|&s| s == 0.0));
388 }
389
390 #[test]
391 fn test_from_slice() {
392 let samples = [1.0, 2.0, 3.0, 4.0, 5.0];
393 let block = AudioBlockMono::from_slice(&samples);
394 assert_eq!(block.num_frames(), 5);
395 assert_eq!(block.samples(), &samples);
396 }
397
398 #[test]
399 fn test_sample_access() {
400 let mut block = AudioBlockMono::from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0]);
401 assert_eq!(block.sample(0), 1.0);
402 assert_eq!(block.sample(2), 3.0);
403 assert_eq!(block.sample(4), 5.0);
404
405 *block.sample_mut(2) = 10.0;
406 assert_eq!(block.sample(2), 10.0);
407 }
408
409 #[test]
410 fn test_iterators() {
411 let mut block = AudioBlockMono::from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0]);
412
413 let sum: f32 = block.samples().iter().sum();
414 assert_eq!(sum, 15.0);
415
416 for sample in block.samples_mut() {
417 *sample *= 2.0;
418 }
419
420 assert_eq!(block.samples(), &[2.0, 4.0, 6.0, 8.0, 10.0]);
421 }
422
423 #[test]
424 #[should_panic]
425 #[no_sanitize_realtime]
426 fn test_resize_beyond_allocated() {
427 let mut block = AudioBlockMono::<f32>::new(10);
428 block.set_num_frames_visible(11);
429 }
430
431 #[test]
432 fn test_audio_block_trait() {
433 let block = AudioBlockMono::from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0]);
434
435 assert_eq!(block.num_channels(), 1);
436 assert_eq!(block.num_frames(), 5);
437
438 let channel: Vec<f32> = block.channel_iter(0).copied().collect();
440 assert_eq!(channel, vec![1.0, 2.0, 3.0, 4.0, 5.0]);
441
442 let frame: Vec<f32> = block.frame_iter(2).copied().collect();
444 assert_eq!(frame, vec![3.0]);
445 }
446
447 #[test]
448 fn test_audio_block_mut_trait() {
449 let mut block = AudioBlockMono::<f32>::new(5);
450
451 for (i, sample) in block.channel_iter_mut(0).enumerate() {
452 *sample = i as f32;
453 }
454
455 assert_eq!(block.samples(), &[0.0, 1.0, 2.0, 3.0, 4.0]);
456 }
457
458 #[test]
459 #[should_panic]
460 #[no_sanitize_realtime]
461 fn test_wrong_channel() {
462 let block = AudioBlockMono::<f32>::new(10);
463 let _ = block.channel_iter(1);
464 }
465
466 #[test]
467 #[should_panic]
468 #[no_sanitize_realtime]
469 fn test_sample_out_of_bounds() {
470 let block = AudioBlockMono::<f32>::new(10);
471 let _ = block.sample(10);
472 }
473
474 #[test]
475 fn test_from_block() {
476 use crate::AudioBlockInterleaved;
477
478 let mut multi = AudioBlockInterleaved::<f32>::new(2, 5);
479 for (i, sample) in multi.channel_iter_mut(0).enumerate() {
480 *sample = i as f32;
481 }
482
483 let mono = AudioBlockMono::from_block(&multi);
484 assert_eq!(mono.samples(), &[0.0, 1.0, 2.0, 3.0, 4.0]);
485 }
486
487 #[test]
488 fn test_views() {
489 let mut block = AudioBlockMono::from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0]);
490
491 {
493 let view = block.as_view();
494 assert_eq!(view.num_frames(), 5);
495 assert_eq!(view.sample(0, 2), 3.0);
496 }
497
498 {
500 let mut view_mut = block.as_view_mut();
501 *view_mut.sample_mut(0, 2) = 10.0;
502 }
503
504 assert_eq!(block.sample(2), 10.0);
505 }
506}