1use rtsan_standalone::nonblocking;
2
3use core::{marker::PhantomData, ptr::NonNull};
4
5use crate::{AudioBlock, Sample, iter::StridedSampleIter};
6
7pub struct SequentialView<'a, S: Sample> {
27 data: &'a [S],
28 num_channels: u16,
29 num_frames: usize,
30 num_channels_allocated: u16,
31 num_frames_allocated: usize,
32}
33
34impl<'a, S: Sample> SequentialView<'a, S> {
35 #[nonblocking]
45 pub fn from_slice(data: &'a [S], num_channels: u16, num_frames: usize) -> Self {
46 assert_eq!(data.len(), num_channels as usize * num_frames);
47 Self {
48 data,
49 num_channels,
50 num_frames,
51 num_channels_allocated: num_channels,
52 num_frames_allocated: num_frames,
53 }
54 }
55
56 #[nonblocking]
73 pub fn from_slice_limited(
74 data: &'a [S],
75 num_channels_visible: u16,
76 num_frames_visible: usize,
77 num_channels_allocated: u16,
78 num_frames_allocated: usize,
79 ) -> Self {
80 assert_eq!(
81 data.len(),
82 num_channels_allocated as usize * num_frames_allocated
83 );
84 Self {
85 data,
86 num_channels: num_channels_visible,
87 num_frames: num_frames_visible,
88 num_channels_allocated,
89 num_frames_allocated,
90 }
91 }
92
93 #[nonblocking]
102 pub unsafe fn from_ptr(ptr: *const S, num_channels: u16, num_frames: usize) -> Self {
103 Self {
104 data: unsafe { std::slice::from_raw_parts(ptr, num_channels as usize * num_frames) },
105 num_channels,
106 num_frames,
107 num_channels_allocated: num_channels,
108 num_frames_allocated: num_frames,
109 }
110 }
111
112 #[nonblocking]
121 pub unsafe fn from_ptr_limited(
122 ptr: *const S,
123 num_channels_visible: u16,
124 num_frames_visible: usize,
125 num_channels_allocated: u16,
126 num_frames_allocated: usize,
127 ) -> Self {
128 assert!(num_channels_visible <= num_channels_allocated);
129 assert!(num_frames_visible <= num_frames_allocated);
130 Self {
131 data: unsafe {
132 std::slice::from_raw_parts(
133 ptr,
134 num_channels_allocated as usize * num_frames_allocated,
135 )
136 },
137 num_channels: num_channels_visible,
138 num_frames: num_frames_visible,
139 num_channels_allocated,
140 num_frames_allocated,
141 }
142 }
143}
144
145impl<S: Sample> AudioBlock<S> for SequentialView<'_, S> {
146 #[nonblocking]
147 fn num_channels(&self) -> u16 {
148 self.num_channels
149 }
150
151 #[nonblocking]
152 fn num_frames(&self) -> usize {
153 self.num_frames
154 }
155
156 #[nonblocking]
157 fn num_channels_allocated(&self) -> u16 {
158 self.num_channels_allocated
159 }
160
161 #[nonblocking]
162 fn num_frames_allocated(&self) -> usize {
163 self.num_frames_allocated
164 }
165
166 #[nonblocking]
167 fn sample(&self, channel: u16, frame: usize) -> S {
168 assert!(channel < self.num_channels);
169 assert!(frame < self.num_frames);
170 unsafe {
171 *self
172 .data
173 .get_unchecked(channel as usize * self.num_frames_allocated + frame)
174 }
175 }
176
177 #[nonblocking]
178 fn channel(&self, channel: u16) -> impl Iterator<Item = &S> {
179 assert!(channel < self.num_channels);
180 self.data
181 .iter()
182 .skip(channel as usize * self.num_frames_allocated)
183 .take(self.num_frames)
184 }
185
186 #[nonblocking]
187 fn channels(&self) -> impl Iterator<Item = impl Iterator<Item = &S> + '_> + '_ {
188 let num_frames = self.num_frames; let num_frames_allocated = self.num_frames_allocated; self.data
192 .chunks(num_frames_allocated)
193 .take(self.num_channels as usize)
194 .map(move |channel_chunk| channel_chunk.iter().take(num_frames))
195 }
196
197 #[nonblocking]
198 fn frame(&self, frame: usize) -> impl Iterator<Item = &S> {
199 assert!(frame < self.num_frames);
200 self.data
201 .iter()
202 .skip(frame)
203 .step_by(self.num_frames_allocated)
204 .take(self.num_channels as usize)
205 }
206
207 #[nonblocking]
208 fn frames(&self) -> impl Iterator<Item = impl Iterator<Item = &S> + '_> + '_ {
209 let num_channels = self.num_channels as usize;
210 let num_frames = self.num_frames;
211 let stride = self.num_frames_allocated;
212 let data_ptr = self.data.as_ptr();
213
214 (0..num_frames).map(move |frame_idx| {
215 let start_ptr = if self.data.is_empty() {
220 NonNull::dangling().as_ptr() } else {
222 unsafe { data_ptr.add(frame_idx) }
225 };
226
227 StridedSampleIter::<'_, S> {
228 ptr: NonNull::new(start_ptr as *mut S).unwrap_or(NonNull::dangling()), stride,
233 remaining: num_channels, _marker: PhantomData,
235 }
236 })
237 }
238
239 #[nonblocking]
240 fn view(&self) -> impl AudioBlock<S> {
241 SequentialView::from_slice_limited(
242 self.data,
243 self.num_channels,
244 self.num_frames,
245 self.num_channels_allocated,
246 self.num_frames_allocated,
247 )
248 }
249
250 #[nonblocking]
251 fn layout(&self) -> crate::BlockLayout {
252 crate::BlockLayout::Sequential
253 }
254
255 #[nonblocking]
256 fn raw_data(&self, _: Option<u16>) -> &[S] {
257 self.data
258 }
259}
260
261#[cfg(test)]
262mod tests {
263 use super::*;
264
265 #[test]
266 fn test_samples() {
267 let data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
268 let block = SequentialView::<f32>::from_slice(&data, 2, 5);
269
270 for ch in 0..block.num_channels() {
271 for f in 0..block.num_frames() {
272 assert_eq!(
273 block.sample(ch, f),
274 (ch as usize * block.num_frames() + f) as f32
275 );
276 }
277 }
278 }
279
280 #[test]
281 fn test_channel() {
282 let data = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
283 let block = SequentialView::<f32>::from_slice(&data, 2, 5);
284
285 let channel = block.channel(0).copied().collect::<Vec<_>>();
286 assert_eq!(channel, vec![0.0, 1.0, 2.0, 3.0, 4.0]);
287 let channel = block.channel(1).copied().collect::<Vec<_>>();
288 assert_eq!(channel, vec![5.0, 6.0, 7.0, 8.0, 9.0]);
289 }
290
291 #[test]
292 fn test_channels() {
293 let data = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
294 let block = SequentialView::<f32>::from_slice(&data, 2, 5);
295
296 let mut channels_iter = block.channels();
297 let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
298 assert_eq!(channel, vec![0.0, 1.0, 2.0, 3.0, 4.0]);
299
300 let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
301 assert_eq!(channel, vec![5.0, 6.0, 7.0, 8.0, 9.0]);
302 assert!(channels_iter.next().is_none());
303 }
304
305 #[test]
306 fn test_frame() {
307 let data = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
308 let block = SequentialView::<f32>::from_slice(&data, 2, 5);
309
310 let channel = block.frame(0).copied().collect::<Vec<_>>();
311 assert_eq!(channel, vec![0.0, 5.0]);
312 let channel = block.frame(1).copied().collect::<Vec<_>>();
313 assert_eq!(channel, vec![1.0, 6.0]);
314 let channel = block.frame(2).copied().collect::<Vec<_>>();
315 assert_eq!(channel, vec![2.0, 7.0]);
316 let channel = block.frame(3).copied().collect::<Vec<_>>();
317 assert_eq!(channel, vec![3.0, 8.0]);
318 let channel = block.frame(4).copied().collect::<Vec<_>>();
319 assert_eq!(channel, vec![4.0, 9.0]);
320 }
321
322 #[test]
323 fn test_frames() {
324 let data = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
325 let block = SequentialView::<f32>::from_slice(&data, 2, 5);
326
327 let mut frames_iter = block.frames();
328 let channel = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
329 assert_eq!(channel, vec![0.0, 5.0]);
330 let channel = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
331 assert_eq!(channel, vec![1.0, 6.0]);
332 let channel = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
333 assert_eq!(channel, vec![2.0, 7.0]);
334 let channel = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
335 assert_eq!(channel, vec![3.0, 8.0]);
336 let channel = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
337 assert_eq!(channel, vec![4.0, 9.0]);
338 assert!(frames_iter.next().is_none());
339 }
340
341 #[test]
342 fn test_from_slice() {
343 let data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
344 let block = SequentialView::<f32>::from_slice(&data, 2, 5);
345 assert_eq!(block.num_channels(), 2);
346 assert_eq!(block.num_channels_allocated, 2);
347 assert_eq!(block.num_frames(), 5);
348 assert_eq!(block.num_frames_allocated, 5);
349 assert_eq!(
350 block.channel(0).copied().collect::<Vec<_>>(),
351 vec![0.0, 1.0, 2.0, 3.0, 4.0]
352 );
353 assert_eq!(
354 block.channel(1).copied().collect::<Vec<_>>(),
355 vec![5.0, 6.0, 7.0, 8.0, 9.0]
356 );
357 assert_eq!(block.frame(0).copied().collect::<Vec<_>>(), vec![0.0, 5.0]);
358 assert_eq!(block.frame(1).copied().collect::<Vec<_>>(), vec![1.0, 6.0]);
359 assert_eq!(block.frame(2).copied().collect::<Vec<_>>(), vec![2.0, 7.0]);
360 assert_eq!(block.frame(3).copied().collect::<Vec<_>>(), vec![3.0, 8.0]);
361 assert_eq!(block.frame(4).copied().collect::<Vec<_>>(), vec![4.0, 9.0]);
362 }
363
364 #[test]
365 fn test_view() {
366 let data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
367 let block = SequentialView::<f32>::from_slice(&data, 2, 5);
368 let view = block.view();
369 assert_eq!(
370 view.channel(0).copied().collect::<Vec<_>>(),
371 vec![0.0, 1.0, 2.0, 3.0, 4.0]
372 );
373 assert_eq!(
374 view.channel(1).copied().collect::<Vec<_>>(),
375 vec![5.0, 6.0, 7.0, 8.0, 9.0]
376 );
377 }
378
379 #[test]
380 fn test_limited() {
381 let data = [1.0, 2.0, 0.0, 3.0, 4.0, 0.0, 5.0, 6.0, 0.0, 0.0, 0.0, 0.0];
382
383 let block = SequentialView::from_slice_limited(&data, 2, 3, 3, 4);
384
385 assert_eq!(block.num_channels(), 2);
386 assert_eq!(block.num_frames(), 3);
387 assert_eq!(block.num_channels_allocated, 3);
388 assert_eq!(block.num_frames_allocated, 4);
389
390 for i in 0..block.num_channels() {
391 assert_eq!(block.channel(i).count(), 3);
392 }
393 for i in 0..block.num_frames() {
394 assert_eq!(block.frame(i).count(), 2);
395 }
396 }
397
398 #[test]
399 fn test_from_raw() {
400 let mut data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
401 let block = unsafe { SequentialView::<f32>::from_ptr(data.as_mut_ptr(), 2, 5) };
402 assert_eq!(block.num_channels(), 2);
403 assert_eq!(block.num_channels_allocated, 2);
404 assert_eq!(block.num_frames(), 5);
405 assert_eq!(block.num_frames_allocated, 5);
406 assert_eq!(
407 block.channel(0).copied().collect::<Vec<_>>(),
408 vec![0.0, 1.0, 2.0, 3.0, 4.0]
409 );
410 assert_eq!(
411 block.channel(1).copied().collect::<Vec<_>>(),
412 vec![5.0, 6.0, 7.0, 8.0, 9.0]
413 );
414 assert_eq!(block.frame(0).copied().collect::<Vec<_>>(), vec![0.0, 5.0]);
415 assert_eq!(block.frame(1).copied().collect::<Vec<_>>(), vec![1.0, 6.0]);
416 assert_eq!(block.frame(2).copied().collect::<Vec<_>>(), vec![2.0, 7.0]);
417 assert_eq!(block.frame(3).copied().collect::<Vec<_>>(), vec![3.0, 8.0]);
418 assert_eq!(block.frame(4).copied().collect::<Vec<_>>(), vec![4.0, 9.0]);
419 }
420
421 #[test]
422 fn test_from_raw_limited() {
423 let data = [1.0, 2.0, 0.0, 3.0, 4.0, 0.0, 5.0, 6.0, 0.0, 0.0, 0.0, 0.0];
424
425 let block = unsafe { SequentialView::from_ptr_limited(data.as_ptr(), 2, 3, 3, 4) };
426
427 assert_eq!(block.num_channels(), 2);
428 assert_eq!(block.num_frames(), 3);
429 assert_eq!(block.num_channels_allocated, 3);
430 assert_eq!(block.num_frames_allocated, 4);
431
432 for i in 0..block.num_channels() {
433 assert_eq!(block.channel(i).count(), 3);
434 }
435 for i in 0..block.num_frames() {
436 assert_eq!(block.frame(i).count(), 2);
437 }
438 }
439
440 #[test]
441 fn test_raw_data() {
442 let data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
443 let block = SequentialView::<f32>::from_slice(&data, 2, 5);
444
445 assert_eq!(block.layout(), crate::BlockLayout::Sequential);
446
447 assert_eq!(
448 block.raw_data(None),
449 &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
450 );
451 }
452}