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