1use crate::io::{ReadExt, WriteExt};
2use mycrc::CRC;
3use std::io::{Error, ErrorKind, Read, Result, Write};
4use std::ops::{AddAssign, Mul};
5
6pub trait Sample:
8 Sized + Default + AddAssign + Mul<Output = Self> + Clone + Copy + PartialEq
9{
10 fn from_f32(n: f32) -> Self;
11 fn from_f64(n: f64) -> Self;
12 fn to_f32(self) -> f32;
13 fn to_f64(self) -> f64;
14 fn read<R: Read>(reader: &mut R) -> Result<Self>;
15 fn write<W: Write>(self, writer: &mut W) -> Result<()>;
16
17 fn read_and_calc_bytes<R: Read>(reader: &mut R, crc: &mut CRC<u32>) -> Result<Self>;
18 fn write_and_calc_bytes<W: Write>(self, writer: &mut W, crc: &mut CRC<u32>) -> Result<()>;
19}
20
21macro_rules! le_sample_impl {
22 ( $( $t:ty ),* ) => ($(
23 impl Sample for $t {
24 fn from_f32(n: f32) -> Self {
25 n as $t
26 }
27
28 fn from_f64(n: f64) -> Self {
29 n as $t
30 }
31
32 fn to_f32(self) -> f32 {
33 self as f32
34 }
35
36 fn to_f64(self) -> f64 {
37 self as f64
38 }
39
40 fn read<R: Read>(reader: &mut R) -> Result<Self> {
41 reader.read_le()
42 }
43 fn write<W: Write>(self, writer: &mut W) -> Result<()> {
44 writer.write_le(self)
45 }
46
47 fn read_and_calc_bytes<R: Read>(reader: &mut R, crc: &mut CRC<u32>) -> Result<Self> {
48 reader.read_le_and_calc_bytes(crc)
49 }
50 fn write_and_calc_bytes<W: Write>(self, writer: &mut W, crc: &mut CRC<u32>) -> Result<()> {
51 writer.write_le_and_calc_bytes(self, crc)
52 }
53 }
54 )*)
55}
56
57le_sample_impl!(f32, f64);
58
59#[derive(Clone, Debug, PartialEq)]
61pub struct Frame<S: Sample>(pub Vec<S>);
62
63impl<S: Sample> From<Frame<S>> for Vec<S> {
64 fn from(value: Frame<S>) -> Self {
65 value.0
66 }
67}
68
69impl<S: Sample> From<Vec<S>> for Frame<S> {
70 fn from(value: Vec<S>) -> Self {
71 Frame(value)
72 }
73}
74
75impl<S: Sample> Frame<S> {
76 pub fn add(&mut self, other: Self) -> Result<()> {
77 if self.0.len() != other.0.len() {
78 return Err(Error::new(
79 ErrorKind::Other,
80 format!(
81 "The frames are not the same length. expected `{:?}`, found `{:?}`",
82 self.0.len(),
83 other.0.len()
84 ),
85 ));
86 }
87
88 for i in 0..self.0.len() {
89 self.0[i] += other.0[i];
90 }
91
92 Ok(())
93 }
94}
95
96#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
97pub enum LpcmKind {
98 F32LE,
99 F64LE,
100 I16LE,
101}
102
103impl LpcmKind {
104 pub fn read<R: Read>(reader: &mut R) -> Result<Self> {
105 let value: u8 = reader.read_le()?;
106 Ok(match value {
107 0 => Self::F32LE,
108 1 => Self::F64LE,
109 3 => Self::I16LE,
110 _ => return Err(ErrorKind::InvalidData.into()),
111 })
112 }
113 pub fn read_and_calc_bytes<R: Read>(reader: &mut R, crc: &mut CRC<u32>) -> Result<Self> {
114 let value: u8 = reader.read_le_and_calc_bytes(crc)?;
115 Ok(match value {
116 0 => Self::F32LE,
117 1 => Self::F64LE,
118 3 => Self::I16LE,
119 _ => return Err(ErrorKind::InvalidData.into()),
120 })
121 }
122
123 pub fn write<W: Write>(self, writer: &mut W) -> Result<()> {
124 writer.write_le(self.to_u8())
125 }
126 pub fn write_and_calc_bytes<W: Write>(self, writer: &mut W, crc: &mut CRC<u32>) -> Result<()> {
127 writer.write_le_and_calc_bytes(self.to_u8(), crc)
128 }
129
130 pub fn from_u8(value: u8) -> Self {
131 match value {
132 0 => Self::F32LE,
133 1 => Self::F64LE,
134 3 => Self::I16LE,
135 _ => unimplemented!(),
136 }
137 }
138
139 pub const fn to_u8(self) -> u8 {
140 match self {
141 Self::F32LE => 0,
142 Self::F64LE => 1,
143 Self::I16LE => 3,
144 }
145 }
146
147 pub const fn format_tag(&self) -> u16 {
148 match self {
149 Self::F32LE => 3,
150 Self::F64LE => 3,
151 Self::I16LE => 1,
152 }
153 }
154
155 pub const fn bits_per_sample(&self) -> u16 {
156 match self {
157 Self::F32LE => 32,
158 Self::F64LE => 64,
159 Self::I16LE => 16,
160 }
161 }
162
163 pub fn from_format_tag_and_bits_per_sample(format_tag: u16, bits_per_sample: u16) -> Self {
164 match format_tag {
165 1 => match bits_per_sample {
166 16 => Self::I16LE,
167 _ => unimplemented!(),
168 },
169 3 => match bits_per_sample {
170 32 => Self::F32LE,
171 64 => Self::F64LE,
172 _ => unimplemented!(),
173 },
174 _ => unimplemented!(),
175 }
176 }
177}