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