+trait SampleReader {
+ fn get_samples_i32(&self, pos: usize, dst: &mut [i32]);
+ fn get_samples_f32(&self, pos: usize, dst: &mut [f32]);
+}
+
+struct GenericSampleReader<'a, T:Copy> {
+ data: &'a [T],
+ stride: usize,
+}
+
+impl<'a, T:Copy+IntoFmt<i32>+IntoFmt<f32>> SampleReader for GenericSampleReader<'a, T> {
+ fn get_samples_i32(&self, pos: usize, dst: &mut [i32]) {
+ let mut off = pos;
+ for el in dst.iter_mut() {
+ *el = self.data[off].cvt_into();
+ off += self.stride;
+ }
+ }
+ fn get_samples_f32(&self, pos: usize, dst: &mut [f32]) {
+ let mut off = pos;
+ for el in dst.iter_mut() {
+ *el = self.data[off].cvt_into();
+ off += self.stride;
+ }
+ }
+}
+
+struct S8SampleReader<'a> {
+ data: &'a [u8],
+ stride: usize,
+}
+
+impl<'a> SampleReader for S8SampleReader<'a> {
+ fn get_samples_i32(&self, pos: usize, dst: &mut [i32]) {
+ let mut off = pos;
+ for el in dst.iter_mut() {
+ *el = (self.data[off] ^ 0x80).cvt_into();
+ off += self.stride;
+ }
+ }
+ fn get_samples_f32(&self, pos: usize, dst: &mut [f32]) {
+ let mut off = pos;
+ for el in dst.iter_mut() {
+ *el = (self.data[off] ^ 0x80).cvt_into();
+ off += self.stride;
+ }
+ }
+}
+
+struct PackedSampleReader<'a> {
+ data: &'a [u8],
+ fmt: NASoniton,
+ bpp: usize,
+}
+
+impl<'a> PackedSampleReader<'a> {
+ fn new(data: &'a [u8], fmt: NASoniton) -> Self {
+ if (fmt.bits & 7) != 0 { unimplemented!(); }
+ let bpp = (fmt.bits >> 3) as usize;
+ Self { data, fmt, bpp }
+ }
+ fn get_samples<T:Copy>(&self, pos: usize, dst: &mut [T]) where u8: IntoFmt<T>, i16: IntoFmt<T>, i32: IntoFmt<T>, f32: IntoFmt<T> {
+ let mut offset = pos * self.bpp * dst.len();
+
+ for el in dst.iter_mut() {
+ let src = &self.data[offset..];
+ *el = if !self.fmt.float {
+ match (self.bpp, self.fmt.be) {
+ (1, _) => if !self.fmt.signed { src[0].cvt_into() } else { (src[0] ^ 0x80).cvt_into() },
+ (2, true) => (read_u16be(src).unwrap() as i16).cvt_into(),
+ (2, false) => (read_u16le(src).unwrap() as i16).cvt_into(),
+ (3, true) => ((read_u24be(src).unwrap() << 8) as i32).cvt_into(),
+ (3, false) => ((read_u24be(src).unwrap() << 8) as i32).cvt_into(),
+ (4, true) => (read_u32be(src).unwrap() as i32).cvt_into(),
+ (4, false) => (read_u32be(src).unwrap() as i32).cvt_into(),
+ _ => unreachable!(),
+ }
+ } else {
+ match (self.bpp, self.fmt.be) {
+ (4, true) => read_f32be(src).unwrap().cvt_into(),
+ (4, false) => read_f32le(src).unwrap().cvt_into(),
+ (8, true) => (read_f64be(src).unwrap() as f32).cvt_into(),
+ (8, false) => (read_f64le(src).unwrap() as f32).cvt_into(),
+ (_, _) => unreachable!(),
+ }
+ };
+ offset += self.bpp;
+ }