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 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 26 fn bytes_len(&self); 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> { 47 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> { 65 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 74 pub fn as_ref(&'_ self) -> BufferRef<'_, T, L> { 75 BufferRef { 76 samples: &self.samples[..], 77 info: self.info, 78 } 79 } 80 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 { 98 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 { 107 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 { 142 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 { 151 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 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 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 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 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. 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] 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] 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] 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] 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] 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] 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