1pub mod info;
13pub mod layout;
15
16use std::mem::{ManuallyDrop, MaybeUninit};
17use std::ops::Range;
18
19use byteorder::ByteOrder;
20pub use info::BufferInfo;
21pub use layout::BufferLayout;
22use layout::{Deinterleaved, Interleaved};
23use thiserror::Error;
24
25pub trait FromBytes<L>: Sized {
29 type Error;
31
32 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error>;
38}
39
40pub trait ToByteBufferRef<L>: Sized {
42 type Error;
44
45 fn bytes_len(&self);
47 fn to_bytes<B: ByteOrder>(
53 &self,
54 bytes: &mut [u8],
55 channels: usize,
56 ) -> Result<usize, Self::Error>;
57}
58
59#[derive(Debug, Error, PartialEq, Eq)]
60pub enum Error {
62 #[error("Unexpected end of buffer: (expected: {expected}, actual: {actual})")]
63 UnexpectedEndOfBuffer {
65 expected: usize,
67 actual: usize,
69 },
70}
71
72#[derive(Eq, PartialEq, Clone, Debug)]
73pub struct BufferRef<'a, T, L> {
75 samples: &'a [T],
76 info: BufferInfo<L>,
77}
78
79impl<'a, T, L> BufferRef<'a, T, L> {
80 pub fn new(samples: &'a [T], channels: usize) -> Self {
84 debug_assert_eq!(samples.len() % channels, 0);
85 let info = {
86 let frames = samples.len() / channels;
87 BufferInfo::new(channels, frames)
88 };
89 Self { samples, info }
90 }
91}
92
93#[derive(Eq, PartialEq, Clone, Debug)]
95pub struct Buffer<T, L> {
96 samples: Vec<T>,
97 info: BufferInfo<L>,
98}
99
100impl<T, L> Buffer<T, L> {
101 pub fn new(samples: Vec<T>, channels: usize) -> Self {
105 debug_assert_eq!(samples.len() % channels, 0);
106 let info = {
107 let frames = samples.len() / channels;
108 BufferInfo::new(channels, frames)
109 };
110 Self { samples, info }
111 }
112
113 pub fn as_ref(&'_ self) -> BufferRef<'_, T, L> {
115 BufferRef {
116 samples: &self.samples[..],
117 info: self.info,
118 }
119 }
120
121 pub fn sub_range(&'_ self, range: Range<usize>) -> BufferRef<'_, T, L> {
123 let samples_len = range.len();
124 let samples = &self.samples[range];
125 let info = {
126 let channels = self.info.channels();
127 assert_eq!(samples_len % channels, 0);
128 let frames = samples_len / channels;
129 BufferInfo::new(channels, frames)
130 };
131 BufferRef { samples, info }
132 }
133}
134
135impl<T> From<Buffer<T, Deinterleaved>> for Buffer<T, Interleaved>
136where
137 T: Default + Copy,
138{
139 fn from(buffer: Buffer<T, Deinterleaved>) -> Self {
140 Self::from(buffer.as_ref())
141 }
142}
143
144impl<'a, T> From<BufferRef<'a, T, Deinterleaved>> for Buffer<T, Interleaved>
145where
146 T: Default + Copy,
147{
148 fn from(buffer: BufferRef<'a, T, Deinterleaved>) -> Self {
149 let samples = {
158 let mut samples: Vec<MaybeUninit<T>> =
160 vec![MaybeUninit::uninit(); buffer.samples.len()];
161
162 layout::interleaved_by(
164 buffer.samples,
165 &mut samples[..],
166 buffer.info.channels(),
167 |sample| MaybeUninit::new(*sample),
168 );
169
170 unsafe { std::mem::transmute::<Vec<MaybeUninit<T>>, Vec<T>>(samples) }
172 };
173
174 let info = buffer.info.into();
175 Self { samples, info }
176 }
177}
178
179impl<T> From<Buffer<T, Interleaved>> for Buffer<T, Deinterleaved>
180where
181 T: Default + Copy,
182{
183 fn from(buffer: Buffer<T, Interleaved>) -> Self {
184 Self::from(buffer.as_ref())
185 }
186}
187
188impl<'a, T> From<BufferRef<'a, T, Interleaved>> for Buffer<T, Deinterleaved>
189where
190 T: Default + Copy,
191{
192 fn from(buffer: BufferRef<'a, T, Interleaved>) -> Self {
193 let samples = {
202 let mut samples: Vec<MaybeUninit<T>> =
204 vec![MaybeUninit::uninit(); buffer.samples.len()];
205
206 layout::deinterleaved_by(
208 buffer.samples,
209 &mut samples[..],
210 buffer.info.channels(),
211 |sample| MaybeUninit::new(*sample),
212 );
213
214 unsafe { std::mem::transmute::<Vec<MaybeUninit<T>>, Vec<T>>(samples) }
216 };
217
218 let info = buffer.info.into();
219 Self { samples, info }
220 }
221}
222
223impl FromBytes<Interleaved> for Buffer<i16, Interleaved> {
224 type Error = ();
225
226 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error> {
227 const STRIDE: usize = std::mem::size_of::<i16>();
228 assert_eq!(bytes.len() % STRIDE, 0);
229
230 let chunks = {
231 let chunks_ptr = bytes.as_ptr() as *const [u8; STRIDE];
232 let chunks_len = bytes.len() / STRIDE;
233 unsafe { std::slice::from_raw_parts(chunks_ptr, chunks_len) }
234 };
235
236 let samples: Vec<_> = chunks.iter().map(|chunk| B::read_i16(&chunk[..])).collect();
237
238 let info = {
239 let frames = samples.len() / channels;
240 BufferInfo::new(channels, frames)
241 };
242 Ok(Self { samples, info })
243 }
244}
245
246impl FromBytes<Deinterleaved> for Buffer<i16, Interleaved> {
247 type Error = ();
248
249 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error> {
250 const STRIDE: usize = std::mem::size_of::<i16>();
251 assert_eq!(bytes.len() % STRIDE, 0);
252
253 let chunks = {
254 let chunks_ptr = bytes.as_ptr() as *const [u8; STRIDE];
255 let chunks_len = bytes.len() / STRIDE;
256 unsafe { std::slice::from_raw_parts(chunks_ptr, chunks_len) }
257 };
258
259 let samples = unsafe {
268 init_vec(chunks.len(), |samples| {
269 layout::interleaved_by(chunks, samples, channels, |chunk| {
270 MaybeUninit::new(B::read_i16(&chunk[..]))
271 });
272 })
273 };
274
275 let info = {
276 let frames = samples.len() / channels;
277 BufferInfo::new(channels, frames)
278 };
279 Ok(Self { samples, info })
280 }
281}
282
283impl FromBytes<Deinterleaved> for Buffer<i16, Deinterleaved> {
284 type Error = ();
285
286 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error> {
287 const STRIDE: usize = std::mem::size_of::<i16>();
288 assert_eq!(bytes.len() % STRIDE, 0);
289
290 let chunks = {
291 let chunks_ptr = bytes.as_ptr() as *const [u8; STRIDE];
292 let chunks_len = bytes.len() / STRIDE;
293 unsafe { std::slice::from_raw_parts(chunks_ptr, chunks_len) }
294 };
295
296 let samples: Vec<_> = chunks.iter().map(|chunk| B::read_i16(&chunk[..])).collect();
297
298 let info = {
299 let frames = samples.len() / channels;
300 BufferInfo::new(channels, frames)
301 };
302 Ok(Self { samples, info })
303 }
304}
305
306impl FromBytes<Interleaved> for Buffer<i16, Deinterleaved> {
307 type Error = ();
308
309 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error> {
310 const STRIDE: usize = std::mem::size_of::<i16>();
311 assert_eq!(bytes.len() % STRIDE, 0);
312
313 let chunks = {
314 let chunks_ptr = bytes.as_ptr() as *const [u8; STRIDE];
315 let chunks_len = bytes.len() / STRIDE;
316 unsafe { std::slice::from_raw_parts(chunks_ptr, chunks_len) }
317 };
318
319 let samples = unsafe {
328 init_vec(chunks.len(), |samples| {
329 layout::deinterleaved_by(chunks, samples, channels, |chunk| {
330 MaybeUninit::new(B::read_i16(&chunk[..]))
331 });
332 })
333 };
334
335 let info = {
336 let frames = samples.len() / channels;
337 BufferInfo::new(channels, frames)
338 };
339 Ok(Self { samples, info })
340 }
341}
342
343unsafe fn init_vec<T, F>(len: usize, f: F) -> Vec<T>
349where
350 MaybeUninit<T>: Clone,
351 F: FnOnce(&mut [MaybeUninit<T>]),
352{
353 unsafe {
354 let mut vec: Vec<MaybeUninit<T>> = vec![MaybeUninit::uninit(); len];
356
357 f(&mut vec[..]);
359
360 let mut manually_drop: ManuallyDrop<_> = ManuallyDrop::new(vec);
362
363 let ptr = manually_drop.as_mut_ptr() as *mut T;
365 let len = manually_drop.len();
366 let cap = manually_drop.capacity();
367 Vec::from_raw_parts(ptr, len, cap)
368 }
369}
370
371#[cfg(test)]
372mod tests {
373 use byteorder::NativeEndian;
374
375 use super::*;
376
377 #[test]
378 fn deinterleaved_from_interleaved() {
379 let channels = 3;
380
381 let input_samples: Vec<i32> = vec![0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14];
382 let input: Buffer<i32, Interleaved> = Buffer::new(input_samples, channels);
383
384 let output = Buffer::<i32, Deinterleaved>::from(input);
385
386 let actual = output.samples;
387 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
388
389 assert_eq!(actual, expected);
390 }
391
392 #[test]
393 fn interleaved_from_deinterleaved() {
394 let channels = 3;
395
396 let input_samples: Vec<i32> = vec![0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14];
397 let input: Buffer<i32, Deinterleaved> = Buffer::new(input_samples, channels);
398
399 let output = Buffer::<i32, Interleaved>::from(input);
400
401 let actual = output.samples;
402 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
403
404 assert_eq!(actual, expected);
405 }
406
407 #[test]
408 fn deinterleaved_from_deinterleaved_bytes() {
409 let channels = 3;
410 let stride = 2;
411
412 let input_samples: Vec<i16> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
413 let input_bytes: &[u8] = {
414 let bytes_ptr = input_samples.as_ptr() as *const u8;
415 let bytes_len = input_samples.len() * stride;
416 unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }
417 };
418
419 let output: Buffer<i16, Deinterleaved> =
420 FromBytes::<Deinterleaved>::from_bytes::<NativeEndian>(input_bytes, channels).unwrap();
421
422 let actual = output.samples;
423 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
424
425 assert_eq!(actual, expected);
426 }
427
428 #[test]
429 fn deinterleaved_from_interleaved_bytes() {
430 let channels = 3;
431 let stride = 2;
432
433 let input_samples: Vec<i16> = vec![0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14];
434 let input_bytes: &[u8] = {
435 let bytes_ptr = input_samples.as_ptr() as *const u8;
436 let bytes_len = input_samples.len() * stride;
437 unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }
438 };
439
440 let output: Buffer<i16, Deinterleaved> =
441 FromBytes::<Interleaved>::from_bytes::<NativeEndian>(input_bytes, channels).unwrap();
442
443 let actual = output.samples;
444 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
445
446 assert_eq!(actual, expected);
447 }
448
449 #[test]
450 fn interleaved_from_interleaved_bytes() {
451 let channels = 3;
452 let stride = 2;
453
454 let input_samples: Vec<i16> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
455 let input_bytes: &[u8] = {
456 let bytes_ptr = input_samples.as_ptr() as *const u8;
457 let bytes_len = input_samples.len() * stride;
458 unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }
459 };
460
461 let output: Buffer<i16, Interleaved> =
462 FromBytes::<Interleaved>::from_bytes::<NativeEndian>(input_bytes, channels).unwrap();
463
464 let actual = output.samples;
465 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
466
467 assert_eq!(actual, expected);
468 }
469
470 #[test]
471 fn interleaved_from_deinterleaved_bytes() {
472 let channels = 3;
473 let stride = 2;
474
475 let input_samples: Vec<i16> = vec![0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14];
476 let input_bytes: &[u8] = {
477 let bytes_ptr = input_samples.as_ptr() as *const u8;
478 let bytes_len = input_samples.len() * stride;
479 unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }
480 };
481
482 let output: Buffer<i16, Interleaved> =
483 FromBytes::<Deinterleaved>::from_bytes::<NativeEndian>(input_bytes, channels).unwrap();
484
485 let actual = output.samples;
486 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
487
488 assert_eq!(actual, expected);
489 }
490}