cpal
cpal copied to clipboard
[Question] turn a `Sample` to &[u8]?
Hi,
I'm using master branch on 624ba659da7ed97cd973d98fe1c0eae331a6f84c so I can follow the examples folder :). I'm trying to send a Sample over TCP using tokio and I'm reaching a point where I want to have a &[u8] out of a cpal::Sample.
Is there a simple way to achieve that?
Regards,
let bytes:&[u8] = unsafe { core::mem::transmute::<&[f32], &[u8]>(sample) };
let bytes:&[u8] = unsafe { core::mem::transmute::<&[f32], &[u8]>(sample) };
If you have a slice of samples, I would not recommend this, as directly transmuting between slices is UB if I recall, plus the size will most likely be wrong. Do something like this instead:
pub fn slice_to_u8_slice<T>(slice: &[T]) -> &[u8] {
unsafe { core::slice::from_raw_parts(slice.as_ptr().cast(), core::mem::size_of_val(slice)) }
}
let bytes = slice_to_u8_slice(&[
0.0f32, 0.5f32, 1.0f32, 0.5f32, 0.0f32, -0.5f32, -1.0f32, -0.5f32,
]);
If you only want to convert one sample then I would probably create a trait akin to this:
pub trait Buf: Sized {
fn buf(&self) -> &[u8] {
unsafe {
core::slice::from_raw_parts(
core::ptr::from_ref(self).cast(),
core::mem::size_of::<Self>(),
)
}
}
}
impl Buf for u8 {
fn buf(&self) -> &[u8] {
core::slice::from_ref(self)
}
}
impl Buf for i8 {
fn buf(&self) -> &[u8] {
core::slice::from_ref(unsafe { &*core::ptr::from_ref(self).cast::<u8>() })
}
}
impl Buf for u16 {}
impl Buf for i16 {}
impl Buf for u32 {}
impl Buf for i32 {}
impl Buf for f32 {}
impl Buf for f64 {}
While this is something that could be implemented in cpal, I really see no reason for it.
Yes, this is completely out of scope for cpal, Use something like the above, or the bytemuck crate.