1pub mod info;
2pub mod layout;
3
4use std::mem::{ManuallyDrop, MaybeUninit};
5use std::ops::Range;
6
7use byteorder::ByteOrder;
8pub use info::BufferInfo;
9pub use layout::BufferLayout;
10use layout::{Deinterleaved, Interleaved};
11use thiserror::Error;
12
13pub trait FromBytes<L>: Sized {
14 type Error;
15
16 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error>;
17}
18
19pub trait ToByteBufferRef<L>: Sized {
20 type Error;
21
22 fn bytes_len(&self);
23 fn to_bytes<B: ByteOrder>(
24 &self,
25 bytes: &mut [u8],
26 channels: usize,
27 ) -> Result<usize, Self::Error>;
28}
29
30#[derive(Debug, Error, PartialEq, Eq)]
31pub enum Error {
32 #[error("Unexpected end of buffer: (expected: {expected}, actual: {actual})")]
33 UnexpectedEndOfBuffer { expected: usize, actual: usize },
34}
35
36#[derive(Eq, PartialEq, Clone, Debug)]
37pub struct BufferRef<'a, T, L> {
38 samples: &'a [T],
39 info: BufferInfo<L>,
40}
41
42impl<'a, T, L> BufferRef<'a, T, L> {
43 pub fn new(samples: &'a [T], channels: usize) -> Self {
44 debug_assert_eq!(samples.len() % channels, 0);
45 let info = {
46 let frames = samples.len() / channels;
47 BufferInfo::new(channels, frames)
48 };
49 Self { samples, info }
50 }
51}
52
53#[derive(Eq, PartialEq, Clone, Debug)]
55pub struct Buffer<T, L> {
56 samples: Vec<T>,
57 info: BufferInfo<L>,
58}
59
60impl<T, L> Buffer<T, L> {
61 pub fn new(samples: Vec<T>, channels: usize) -> Self {
62 debug_assert_eq!(samples.len() % channels, 0);
63 let info = {
64 let frames = samples.len() / channels;
65 BufferInfo::new(channels, frames)
66 };
67 Self { samples, info }
68 }
69
70 pub fn as_ref(&'_ self) -> BufferRef<'_, T, L> {
71 BufferRef {
72 samples: &self.samples[..],
73 info: self.info,
74 }
75 }
76
77 pub fn sub_range(&'_ self, range: Range<usize>) -> BufferRef<'_, T, L> {
78 let samples_len = range.len();
79 let samples = &self.samples[range];
80 let info = {
81 let channels = self.info.channels();
82 assert_eq!(samples_len % channels, 0);
83 let frames = samples_len / channels;
84 BufferInfo::new(channels, frames)
85 };
86 BufferRef { samples, info }
87 }
88}
89
90impl<T> From<Buffer<T, Deinterleaved>> for Buffer<T, Interleaved>
91where
92 T: Default + Copy,
93{
94 fn from(buffer: Buffer<T, Deinterleaved>) -> Self {
95 Self::from(buffer.as_ref())
96 }
97}
98
99impl<'a, T> From<BufferRef<'a, T, Deinterleaved>> for Buffer<T, Interleaved>
100where
101 T: Default + Copy,
102{
103 fn from(buffer: BufferRef<'a, T, Deinterleaved>) -> Self {
104 let samples = {
113 let mut samples: Vec<MaybeUninit<T>> =
115 vec![MaybeUninit::uninit(); buffer.samples.len()];
116
117 layout::interleaved_by(
119 buffer.samples,
120 &mut samples[..],
121 buffer.info.channels(),
122 |sample| MaybeUninit::new(*sample),
123 );
124
125 unsafe { std::mem::transmute::<Vec<MaybeUninit<T>>, Vec<T>>(samples) }
127 };
128
129 let info = buffer.info.into();
130 Self { samples, info }
131 }
132}
133
134impl<T> From<Buffer<T, Interleaved>> for Buffer<T, Deinterleaved>
135where
136 T: Default + Copy,
137{
138 fn from(buffer: Buffer<T, Interleaved>) -> Self {
139 Self::from(buffer.as_ref())
140 }
141}
142
143impl<'a, T> From<BufferRef<'a, T, Interleaved>> for Buffer<T, Deinterleaved>
144where
145 T: Default + Copy,
146{
147 fn from(buffer: BufferRef<'a, T, Interleaved>) -> Self {
148 let samples = {
157 let mut samples: Vec<MaybeUninit<T>> =
159 vec![MaybeUninit::uninit(); buffer.samples.len()];
160
161 layout::deinterleaved_by(
163 buffer.samples,
164 &mut samples[..],
165 buffer.info.channels(),
166 |sample| MaybeUninit::new(*sample),
167 );
168
169 unsafe { std::mem::transmute::<Vec<MaybeUninit<T>>, Vec<T>>(samples) }
171 };
172
173 let info = buffer.info.into();
174 Self { samples, info }
175 }
176}
177
178impl FromBytes<Interleaved> for Buffer<i16, Interleaved> {
179 type Error = ();
180
181 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error> {
182 const STRIDE: usize = std::mem::size_of::<i16>();
183 assert_eq!(bytes.len() % STRIDE, 0);
184
185 let chunks = {
186 let chunks_ptr = bytes.as_ptr() as *const [u8; STRIDE];
187 let chunks_len = bytes.len() / STRIDE;
188 unsafe { std::slice::from_raw_parts(chunks_ptr, chunks_len) }
189 };
190
191 let samples: Vec<_> = chunks.iter().map(|chunk| B::read_i16(&chunk[..])).collect();
192
193 let info = {
194 let frames = samples.len() / channels;
195 BufferInfo::new(channels, frames)
196 };
197 Ok(Self { samples, info })
198 }
199}
200
201impl FromBytes<Deinterleaved> for Buffer<i16, Interleaved> {
202 type Error = ();
203
204 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error> {
205 const STRIDE: usize = std::mem::size_of::<i16>();
206 assert_eq!(bytes.len() % STRIDE, 0);
207
208 let chunks = {
209 let chunks_ptr = bytes.as_ptr() as *const [u8; STRIDE];
210 let chunks_len = bytes.len() / STRIDE;
211 unsafe { std::slice::from_raw_parts(chunks_ptr, chunks_len) }
212 };
213
214 let samples = unsafe {
223 init_vec(chunks.len(), |samples| {
224 layout::interleaved_by(chunks, samples, channels, |chunk| {
225 MaybeUninit::new(B::read_i16(&chunk[..]))
226 });
227 })
228 };
229
230 let info = {
231 let frames = samples.len() / channels;
232 BufferInfo::new(channels, frames)
233 };
234 Ok(Self { samples, info })
235 }
236}
237
238impl FromBytes<Deinterleaved> for Buffer<i16, Deinterleaved> {
239 type Error = ();
240
241 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error> {
242 const STRIDE: usize = std::mem::size_of::<i16>();
243 assert_eq!(bytes.len() % STRIDE, 0);
244
245 let chunks = {
246 let chunks_ptr = bytes.as_ptr() as *const [u8; STRIDE];
247 let chunks_len = bytes.len() / STRIDE;
248 unsafe { std::slice::from_raw_parts(chunks_ptr, chunks_len) }
249 };
250
251 let samples: Vec<_> = chunks.iter().map(|chunk| B::read_i16(&chunk[..])).collect();
252
253 let info = {
254 let frames = samples.len() / channels;
255 BufferInfo::new(channels, frames)
256 };
257 Ok(Self { samples, info })
258 }
259}
260
261impl FromBytes<Interleaved> for Buffer<i16, Deinterleaved> {
262 type Error = ();
263
264 fn from_bytes<B: ByteOrder>(bytes: &[u8], channels: usize) -> Result<Self, Self::Error> {
265 const STRIDE: usize = std::mem::size_of::<i16>();
266 assert_eq!(bytes.len() % STRIDE, 0);
267
268 let chunks = {
269 let chunks_ptr = bytes.as_ptr() as *const [u8; STRIDE];
270 let chunks_len = bytes.len() / STRIDE;
271 unsafe { std::slice::from_raw_parts(chunks_ptr, chunks_len) }
272 };
273
274 let samples = unsafe {
283 init_vec(chunks.len(), |samples| {
284 layout::deinterleaved_by(chunks, samples, channels, |chunk| {
285 MaybeUninit::new(B::read_i16(&chunk[..]))
286 });
287 })
288 };
289
290 let info = {
291 let frames = samples.len() / channels;
292 BufferInfo::new(channels, frames)
293 };
294 Ok(Self { samples, info })
295 }
296}
297
298unsafe fn init_vec<T, F>(len: usize, f: F) -> Vec<T>
304where
305 MaybeUninit<T>: Clone,
306 F: FnOnce(&mut [MaybeUninit<T>]),
307{
308 let mut vec: Vec<MaybeUninit<T>> = vec![MaybeUninit::uninit(); len];
310
311 f(&mut vec[..]);
313
314 let mut manually_drop: ManuallyDrop<_> = ManuallyDrop::new(vec);
316
317 let ptr = manually_drop.as_mut_ptr() as *mut T;
319 let len = manually_drop.len();
320 let cap = manually_drop.capacity();
321 Vec::from_raw_parts(ptr, len, cap)
322}
323
324#[cfg(test)]
325mod tests {
326 use byteorder::NativeEndian;
327
328 use super::*;
329
330 #[test]
331 fn deinterleaved_from_interleaved() {
332 let channels = 3;
333
334 let input_samples: Vec<i32> = vec![0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14];
335 let input: Buffer<i32, Interleaved> = Buffer::new(input_samples, channels);
336
337 let output = Buffer::<i32, Deinterleaved>::from(input);
338
339 let actual = output.samples;
340 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
341
342 assert_eq!(actual, expected);
343 }
344
345 #[test]
346 fn interleaved_from_deinterleaved() {
347 let channels = 3;
348
349 let input_samples: Vec<i32> = vec![0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14];
350 let input: Buffer<i32, Deinterleaved> = Buffer::new(input_samples, channels);
351
352 let output = Buffer::<i32, Interleaved>::from(input);
353
354 let actual = output.samples;
355 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
356
357 assert_eq!(actual, expected);
358 }
359
360 #[test]
361 fn deinterleaved_from_deinterleaved_bytes() {
362 let channels = 3;
363 let stride = 2;
364
365 let input_samples: Vec<i16> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
366 let input_bytes: &[u8] = {
367 let bytes_ptr = input_samples.as_ptr() as *const u8;
368 let bytes_len = input_samples.len() * stride;
369 unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }
370 };
371
372 let output: Buffer<i16, Deinterleaved> =
373 FromBytes::<Deinterleaved>::from_bytes::<NativeEndian>(input_bytes, channels).unwrap();
374
375 let actual = output.samples;
376 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
377
378 assert_eq!(actual, expected);
379 }
380
381 #[test]
382 fn deinterleaved_from_interleaved_bytes() {
383 let channels = 3;
384 let stride = 2;
385
386 let input_samples: Vec<i16> = vec![0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14];
387 let input_bytes: &[u8] = {
388 let bytes_ptr = input_samples.as_ptr() as *const u8;
389 let bytes_len = input_samples.len() * stride;
390 unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }
391 };
392
393 let output: Buffer<i16, Deinterleaved> =
394 FromBytes::<Interleaved>::from_bytes::<NativeEndian>(input_bytes, channels).unwrap();
395
396 let actual = output.samples;
397 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
398
399 assert_eq!(actual, expected);
400 }
401
402 #[test]
403 fn interleaved_from_interleaved_bytes() {
404 let channels = 3;
405 let stride = 2;
406
407 let input_samples: Vec<i16> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
408 let input_bytes: &[u8] = {
409 let bytes_ptr = input_samples.as_ptr() as *const u8;
410 let bytes_len = input_samples.len() * stride;
411 unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }
412 };
413
414 let output: Buffer<i16, Interleaved> =
415 FromBytes::<Interleaved>::from_bytes::<NativeEndian>(input_bytes, channels).unwrap();
416
417 let actual = output.samples;
418 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
419
420 assert_eq!(actual, expected);
421 }
422
423 #[test]
424 fn interleaved_from_deinterleaved_bytes() {
425 let channels = 3;
426 let stride = 2;
427
428 let input_samples: Vec<i16> = vec![0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14];
429 let input_bytes: &[u8] = {
430 let bytes_ptr = input_samples.as_ptr() as *const u8;
431 let bytes_len = input_samples.len() * stride;
432 unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }
433 };
434
435 let output: Buffer<i16, Interleaved> =
436 FromBytes::<Deinterleaved>::from_bytes::<NativeEndian>(input_bytes, channels).unwrap();
437
438 let actual = output.samples;
439 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
440
441 assert_eq!(actual, expected);
442 }
443}