meadow_dsp_essentials/buffer.rs
1use alloc::vec::Vec;
2use core::num::NonZeroUsize;
3
4use arrayvec::ArrayVec;
5
6/// A memory-efficient buffer of samples with `CHANNELS` channels. Each channel
7/// has a length of `frames`.
8pub struct ChannelBuffer<T: Clone + Copy + Default, const CHANNELS: usize> {
9 buffer: Vec<T>,
10 frames: usize,
11}
12
13impl<T: Clone + Copy + Default, const CHANNELS: usize> ChannelBuffer<T, CHANNELS> {
14 pub const fn empty() -> Self {
15 assert!(CHANNELS > 0);
16
17 Self {
18 buffer: Vec::new(),
19 frames: 0,
20 }
21 }
22
23 pub fn new(frames: usize) -> Self {
24 assert!(CHANNELS > 0);
25
26 let buffer_len = frames * CHANNELS;
27
28 let mut buffer = Vec::new();
29 buffer.reserve_exact(buffer_len);
30 buffer.resize(buffer_len, Default::default());
31
32 Self { buffer, frames }
33 }
34
35 pub fn frames(&self) -> usize {
36 self.frames
37 }
38
39 /// Get an immutable reference to the first channel.
40 #[inline]
41 pub fn first(&self) -> &[T] {
42 // SAFETY:
43 //
44 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`.
45 unsafe { core::slice::from_raw_parts(self.buffer.as_ptr(), self.frames) }
46 }
47
48 /// Get a mutable reference to the first channel.
49 #[inline]
50 pub fn first_mut(&mut self) -> &mut [T] {
51 // SAFETY:
52 //
53 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`.
54 // * `self` is borrowed mutably in this method, so all mutability rules are
55 // being upheld.
56 unsafe { core::slice::from_raw_parts_mut(self.buffer.as_mut_ptr(), self.frames) }
57 }
58
59 /// Get an immutable reference to the first channel with the given number of
60 /// frames.
61 ///
62 /// The length of the returned slice will be either `frames` or the number of
63 /// frames in this buffer, whichever is smaller.
64 #[inline]
65 pub fn first_with_frames(&self, frames: usize) -> &[T] {
66 let frames = frames.min(self.frames);
67
68 // SAFETY:
69 //
70 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
71 // and we have constrained `frames` above, so this is always within range.
72 unsafe { core::slice::from_raw_parts(self.buffer.as_ptr(), frames) }
73 }
74
75 /// Get a mutable reference to the first channel with the given number of
76 /// frames.
77 ///
78 /// The length of the returned slice will be either `frames` or the number of
79 /// frames in this buffer, whichever is smaller.
80 #[inline]
81 pub fn first_with_frames_mut(&mut self, frames: usize) -> &mut [T] {
82 let frames = frames.min(self.frames);
83
84 // SAFETY:
85 //
86 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
87 // and we have constrained `frames` above, so this is always within range.
88 // * `self` is borrowed mutably in this method, so all mutability rules are
89 // being upheld.
90 unsafe { core::slice::from_raw_parts_mut(self.buffer.as_mut_ptr(), frames) }
91 }
92
93 /// Get an immutable reference to the first given number of channels in this buffer.
94 pub fn channels<const NUM_CHANNELS: usize>(&self) -> [&[T]; NUM_CHANNELS] {
95 assert!(NUM_CHANNELS <= CHANNELS);
96
97 // SAFETY:
98 //
99 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
100 // and we have constrained NUM_CHANNELS above, so this is always within range.
101 unsafe {
102 core::array::from_fn(|ch_i| {
103 core::slice::from_raw_parts(
104 self.buffer.as_ptr().add(ch_i * self.frames),
105 self.frames,
106 )
107 })
108 }
109 }
110
111 /// Get a mutable reference to the first given number of channels in this buffer.
112 pub fn channels_mut<const NUM_CHANNELS: usize>(&mut self) -> [&mut [T]; NUM_CHANNELS] {
113 assert!(NUM_CHANNELS <= CHANNELS);
114
115 // SAFETY:
116 //
117 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
118 // and we have constrained NUM_CHANNELS above, so this is always within range.
119 // * None of these slices overlap, and `self` is borrowed mutably in this method,
120 // so all mutability rules are being upheld.
121 unsafe {
122 core::array::from_fn(|ch_i| {
123 core::slice::from_raw_parts_mut(
124 self.buffer.as_mut_ptr().add(ch_i * self.frames),
125 self.frames,
126 )
127 })
128 }
129 }
130
131 /// Get an immutable reference to the first given number of channels with the
132 /// given number of frames.
133 ///
134 /// The length of the returned slices will be either `frames` or the number of
135 /// frames in this buffer, whichever is smaller.
136 pub fn channels_with_frames<const NUM_CHANNELS: usize>(
137 &self,
138 frames: usize,
139 ) -> [&[T]; NUM_CHANNELS] {
140 assert!(NUM_CHANNELS <= CHANNELS);
141
142 let frames = frames.min(self.frames);
143
144 // SAFETY:
145 //
146 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
147 // and we have constrained NUM_CHANNELS and `frames` above, so this is always
148 // within range.
149 unsafe {
150 core::array::from_fn(|ch_i| {
151 core::slice::from_raw_parts(self.buffer.as_ptr().add(ch_i * self.frames), frames)
152 })
153 }
154 }
155
156 /// Get a mutable reference to the first given number of channels with the given
157 /// number of frames.
158 ///
159 /// The length of the returned slices will be either `frames` or the number of
160 /// frames in this buffer, whichever is smaller.
161 pub fn channels_with_frames_mut<const NUM_CHANNELS: usize>(
162 &mut self,
163 frames: usize,
164 ) -> [&mut [T]; NUM_CHANNELS] {
165 assert!(NUM_CHANNELS <= CHANNELS);
166
167 let frames = frames.min(self.frames);
168
169 // SAFETY:
170 //
171 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
172 // and we have constrained NUM_CHANNELS and `frames` above, so this is always
173 // within range.
174 // * None of these slices overlap, and `self` is borrowed mutably in this method,
175 // so all mutability rules are being upheld.
176 unsafe {
177 core::array::from_fn(|ch_i| {
178 core::slice::from_raw_parts_mut(
179 self.buffer.as_mut_ptr().add(ch_i * self.frames),
180 frames,
181 )
182 })
183 }
184 }
185
186 /// Get an immutable reference to all channels in this buffer.
187 pub fn all(&self) -> [&[T]; CHANNELS] {
188 // SAFETY:
189 //
190 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`.
191 unsafe {
192 core::array::from_fn(|ch_i| {
193 core::slice::from_raw_parts(
194 self.buffer.as_ptr().add(ch_i * self.frames),
195 self.frames,
196 )
197 })
198 }
199 }
200
201 /// Get a mutable reference to all channels in this buffer.
202 pub fn all_mut(&mut self) -> [&mut [T]; CHANNELS] {
203 // SAFETY:
204 //
205 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`.
206 // * None of these slices overlap, and `self` is borrowed mutably in this method,
207 // so all mutability rules are being upheld.
208 unsafe {
209 core::array::from_fn(|ch_i| {
210 core::slice::from_raw_parts_mut(
211 self.buffer.as_mut_ptr().add(ch_i * self.frames),
212 self.frames,
213 )
214 })
215 }
216 }
217
218 /// Get an immutable reference to all channels with the given number of frames.
219 ///
220 /// The length of the returned slices will be either `frames` or the number of
221 /// frames in this buffer, whichever is smaller.
222 pub fn all_with_frames(&self, frames: usize) -> [&[T]; CHANNELS] {
223 let frames = frames.min(self.frames);
224
225 // SAFETY:
226 //
227 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
228 // and we have constrained `frames` above, so this is always within range.
229 unsafe {
230 core::array::from_fn(|ch_i| {
231 core::slice::from_raw_parts(self.buffer.as_ptr().add(ch_i * self.frames), frames)
232 })
233 }
234 }
235
236 /// Get a mutable reference to all channels with the given number of frames.
237 ///
238 /// The length of the returned slices will be either `frames` or the number of
239 /// frames in this buffer, whichever is smaller.
240 pub fn all_with_frames_mut(&mut self, frames: usize) -> [&mut [T]; CHANNELS] {
241 let frames = frames.min(self.frames);
242
243 // SAFETY:
244 //
245 // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
246 // and we have constrained `frames` above, so this is always within range.
247 // * None of these slices overlap, and `self` is borrowed mutably in this method,
248 // so all mutability rules are being upheld.
249 unsafe {
250 core::array::from_fn(|ch_i| {
251 core::slice::from_raw_parts_mut(
252 self.buffer.as_mut_ptr().add(ch_i * self.frames),
253 frames,
254 )
255 })
256 }
257 }
258}
259
260/// A memory-efficient buffer of samples with up to `MAX_CHANNELS` channels. Each
261/// channel has a length of `frames`.
262pub struct VarChannelBuffer<T: Clone + Copy + Default, const MAX_CHANNELS: usize> {
263 buffer: Vec<T>,
264 channels: NonZeroUsize,
265 frames: usize,
266}
267
268impl<T: Clone + Copy + Default, const MAX_CHANNELS: usize> VarChannelBuffer<T, MAX_CHANNELS> {
269 pub fn new(channels: NonZeroUsize, frames: usize) -> Self {
270 assert!(channels.get() <= MAX_CHANNELS);
271
272 let buffer_len = frames * channels.get();
273
274 let mut buffer = Vec::new();
275 buffer.reserve_exact(buffer_len);
276 buffer.resize(buffer_len, Default::default());
277
278 Self {
279 buffer,
280 channels,
281 frames,
282 }
283 }
284
285 pub fn frames(&self) -> usize {
286 self.frames
287 }
288
289 pub fn num_channels(&self) -> NonZeroUsize {
290 self.channels
291 }
292
293 pub fn channels(&self, num_channels: usize, frames: usize) -> ArrayVec<&[T], MAX_CHANNELS> {
294 let frames = frames.min(self.frames);
295 let channels = num_channels.min(self.channels.get());
296
297 let mut res = ArrayVec::new();
298
299 // SAFETY:
300 //
301 // * The constructor has set the size of the buffer to `self.frames * self.channels`,
302 // and we have constrained `channels` and `frames` above, so this is always
303 // within range.
304 // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
305 unsafe {
306 for ch_i in 0..channels {
307 res.push_unchecked(core::slice::from_raw_parts(
308 self.buffer.as_ptr().add(ch_i * self.frames),
309 frames,
310 ));
311 }
312 }
313
314 res
315 }
316
317 pub fn channels_mut(
318 &mut self,
319 num_channels: usize,
320 frames: usize,
321 ) -> ArrayVec<&mut [T], MAX_CHANNELS> {
322 let frames = frames.min(self.frames);
323 let channels = num_channels.min(self.channels.get());
324
325 let mut res = ArrayVec::new();
326
327 // SAFETY:
328 //
329 // * The constructor has set the size of the buffer to `self.frames * self.channels`,
330 // and we have constrained `channels` and `frames` above, so this is always
331 // within range.
332 // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
333 // * None of these slices overlap, and `self` is borrowed mutably in this method,
334 // so all mutability rules are being upheld.
335 unsafe {
336 for ch_i in 0..channels {
337 res.push_unchecked(core::slice::from_raw_parts_mut(
338 self.buffer.as_mut_ptr().add(ch_i * self.frames),
339 frames,
340 ));
341 }
342 }
343
344 res
345 }
346}
347
348/// A memory-efficient buffer of samples with variable number of instances each with up to
349/// `MAX_CHANNELS` channels. Each channel has a length of `frames`.
350pub struct InstanceBuffer<T: Clone + Copy + Default, const MAX_CHANNELS: usize> {
351 buffer: Vec<T>,
352 num_instances: usize,
353 channels: NonZeroUsize,
354 frames: usize,
355}
356
357impl<T: Clone + Copy + Default, const MAX_CHANNELS: usize> InstanceBuffer<T, MAX_CHANNELS> {
358 pub fn new(num_instances: usize, channels: NonZeroUsize, frames: usize) -> Self {
359 assert!(channels.get() <= MAX_CHANNELS);
360
361 let buffer_len = frames * channels.get() * num_instances;
362
363 let mut buffer = Vec::new();
364 buffer.reserve_exact(buffer_len);
365 buffer.resize(buffer_len, Default::default());
366
367 Self {
368 buffer,
369 num_instances,
370 channels,
371 frames,
372 }
373 }
374
375 pub fn frames(&self) -> usize {
376 self.frames
377 }
378
379 pub fn num_channels(&self) -> NonZeroUsize {
380 self.channels
381 }
382
383 pub fn num_instances(&self) -> usize {
384 self.num_instances
385 }
386
387 pub fn instance(
388 &self,
389 instance_index: usize,
390 channels: usize,
391 frames: usize,
392 ) -> Option<ArrayVec<&[T], MAX_CHANNELS>> {
393 if instance_index >= self.num_instances {
394 return None;
395 }
396
397 let frames = frames.min(self.frames);
398 let channels = channels.min(self.channels.get());
399
400 let start_frame = instance_index * self.frames * self.channels.get();
401
402 let mut res = ArrayVec::new();
403
404 // SAFETY:
405 //
406 // * The constructor has set the size of the buffer to
407 // `self.frames * self.channels * self.num_instances`, and we have constrained
408 // `instance_index`, `channels` and `frames` above, so this is always within range.
409 // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
410 unsafe {
411 for ch_i in 0..channels {
412 res.push_unchecked(core::slice::from_raw_parts(
413 self.buffer.as_ptr().add(start_frame + (ch_i * self.frames)),
414 frames,
415 ));
416 }
417 }
418
419 Some(res)
420 }
421
422 pub fn instance_mut(
423 &mut self,
424 instance_index: usize,
425 channels: usize,
426 frames: usize,
427 ) -> Option<ArrayVec<&mut [T], MAX_CHANNELS>> {
428 if instance_index >= self.num_instances {
429 return None;
430 }
431
432 let frames = frames.min(self.frames);
433 let channels = channels.min(self.channels.get());
434
435 let start_frame = instance_index * self.frames * self.channels.get();
436
437 let mut res = ArrayVec::new();
438
439 // SAFETY:
440 //
441 // * The constructor has set the size of the buffer to
442 // `self.frames * self.channels * self.num_instances`, and we have constrained
443 // `instance_index`, `channels` and `frames` above, so this is always within range.
444 // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
445 // * None of these slices overlap, and `self` is borrowed mutably in this method,
446 // so all mutability rules are being upheld.
447 unsafe {
448 for ch_i in 0..channels {
449 res.push_unchecked(core::slice::from_raw_parts_mut(
450 self.buffer
451 .as_mut_ptr()
452 .add(start_frame + (ch_i * self.frames)),
453 frames,
454 ));
455 }
456 }
457
458 Some(res)
459 }
460}