use crate::base::*;
use crate::conversion::conversion_fn_for;
pub struct Frames<'s> {
data: &'s [u8],
format: Format,
channels: u32,
}
impl<'s> Frames<'s> {
#[inline]
pub fn wrap<S: Sample>(data: &'s [S], format: Format, channels: u32) -> Frames<'s> {
let byte_data_len = data.len() * std::mem::size_of::<S>();
let byte_data =
unsafe { std::slice::from_raw_parts(data.as_ptr() as *const u8, byte_data_len) };
Frames {
data: byte_data,
format,
channels,
}
}
#[inline]
pub fn convert(&self, dest: &mut FramesMut, dither_mode: DitherMode) {
assert!(
self.frame_count() == dest.frame_count(),
"frame conversion with different frame counts (input: {}, output: {})",
self.frame_count(),
dest.frame_count()
);
let convert_fn = conversion_fn_for(self.format, dest.format);
unsafe {
convert_fn(
dest.as_mut_ptr() as *mut _,
self.as_ptr() as *const _,
self.frame_count() as u64,
dither_mode as _,
);
}
}
pub(crate) fn as_ptr(&self) -> *const u8 {
self.data.as_ptr()
}
#[inline]
pub fn as_bytes(&self) -> &[u8] {
self.data
}
#[inline]
pub fn as_samples<S: Sample>(&self) -> &[S] {
assert!(
self.format() == S::format(),
"format mismatch (frames: {:?}, requested: {:?})",
self.format,
S::format()
);
let len = self.sample_count();
unsafe { std::slice::from_raw_parts(self.data.as_ptr().cast::<S>(), len) }
}
#[inline]
pub fn frames<'t, S: 'static + Sample>(&'t self) -> impl 't + Iterator<Item = &[S]> {
FramesIter {
samples: self.as_samples(),
channels: self.channels,
offset: 0,
}
}
#[inline]
pub fn byte_count(&self) -> usize {
self.data.len()
}
#[inline]
pub fn frame_count(&self) -> usize {
self.sample_count() / self.channels as usize
}
#[inline]
pub fn sample_count(&self) -> usize {
self.data.len() / self.format.size_in_bytes()
}
#[inline]
pub fn format(&self) -> Format {
self.format
}
#[inline]
pub fn channels(&self) -> u32 {
self.channels
}
}
pub struct FramesMut<'s> {
data: &'s mut [u8],
format: Format,
channels: u32,
}
impl<'s> FramesMut<'s> {
#[inline]
pub fn wrap<S: Sample>(data: &'s mut [S], format: Format, channels: u32) -> FramesMut<'s> {
let byte_data_len = data.len() * std::mem::size_of::<S>();
let byte_data =
unsafe { std::slice::from_raw_parts_mut(data.as_ptr() as *mut u8, byte_data_len) };
FramesMut {
data: byte_data,
format,
channels,
}
}
pub(crate) fn as_ptr(&self) -> *const u8 {
self.data.as_ptr()
}
pub(crate) fn as_mut_ptr(&mut self) -> *mut u8 {
self.data.as_ptr() as *mut u8
}
#[inline]
pub fn convert(&self, dest: &mut FramesMut, dither_mode: DitherMode) {
assert!(
self.frame_count() == dest.frame_count(),
"frame conversion with different frame counts (input: {}, output: {})",
self.frame_count(),
dest.frame_count()
);
let convert_fn = conversion_fn_for(self.format, dest.format);
unsafe {
convert_fn(
dest.as_mut_ptr() as *mut _,
self.as_ptr() as *const _,
self.frame_count() as u64,
dither_mode as _,
);
}
}
#[inline]
pub fn as_samples<S: Sample>(&self) -> &[S] {
assert!(
self.format() == S::format(),
"format mismatch (frames: {:?}, requested: {:?})",
self.format,
S::format()
);
let len = self.sample_count();
unsafe { std::slice::from_raw_parts(self.data.as_ptr().cast::<S>(), len) }
}
#[inline]
pub fn as_samples_mut<S: Sample>(&mut self) -> &mut [S] {
assert!(
self.format() == S::format(),
"format mismatch (frames: {:?}, requested: {:?})",
self.format,
S::format()
);
let len = self.sample_count();
unsafe { std::slice::from_raw_parts_mut(self.data.as_mut_ptr().cast::<S>(), len) }
}
#[inline]
pub fn frames<'t, S: 'static + Sample>(&'t self) -> impl 't + Iterator<Item = &[S]> {
FramesIter {
samples: self.as_samples(),
channels: self.channels,
offset: 0,
}
}
#[inline]
pub fn frames_mut<'t, S: 'static + Sample>(
&'t mut self,
) -> impl 't + Iterator<Item = &mut [S]> {
let channels = self.channels;
let samples = self.as_samples_mut();
let samples_len = samples.len();
FramesIterMut {
samples_ptr: samples.as_mut_ptr(),
samples_len,
channels,
offset: 0,
phantom: std::marker::PhantomData,
}
}
#[inline]
pub fn as_bytes(&self) -> &[u8] {
self.data
}
#[inline]
pub fn as_bytes_mut(&mut self) -> &mut [u8] {
self.data
}
#[inline]
pub fn byte_count(&self) -> usize {
self.data.len()
}
#[inline]
pub fn frame_count(&self) -> usize {
self.sample_count() / self.channels as usize
}
#[inline]
pub fn sample_count(&self) -> usize {
self.data.len() / self.format.size_in_bytes()
}
#[inline]
pub fn format(&self) -> Format {
self.format
}
#[inline]
pub fn channels(&self) -> u32 {
self.channels
}
}
pub struct FramesIter<'s, S: Sample> {
samples: &'s [S],
channels: u32,
offset: usize,
}
impl<'s, S: Sample> Iterator for FramesIter<'s, S> {
type Item = &'s [S];
fn next(&mut self) -> Option<Self::Item> {
if self.offset < self.samples.len() {
let ret = Some(&self.samples[self.offset..(self.offset + self.channels as usize)]);
self.offset += self.channels as usize;
ret
} else {
None
}
}
}
pub struct FramesIterMut<'s, S: Sample> {
samples_ptr: *mut S,
samples_len: usize,
channels: u32,
offset: usize,
phantom: std::marker::PhantomData<&'s S>,
}
impl<'s, S: Sample> Iterator for FramesIterMut<'s, S> {
type Item = &'s mut [S];
fn next(&mut self) -> Option<Self::Item> {
if self.offset < self.samples_len {
let ret = Some(unsafe {
std::slice::from_raw_parts_mut(
self.samples_ptr.add(self.offset),
self.channels as usize,
)
});
self.offset += self.channels as usize;
ret
} else {
None
}
}
}
pub trait Sample {
fn format() -> Format;
}
impl Sample for u8 {
fn format() -> Format {
Format::U8
}
}
impl Sample for i16 {
fn format() -> Format {
Format::S16
}
}
impl Sample for [u8; 3] {
fn format() -> Format {
Format::S24
}
}
impl Sample for i32 {
fn format() -> Format {
Format::S32
}
}
impl Sample for f32 {
fn format() -> Format {
Format::F32
}
}