1use std::io::Write;
9use std::marker::PhantomData;
10
11use fon::chan::{Ch16, Ch32, Ch8, Channel};
12use fon::{Frame, Stream};
13
14use crate::pcm::{
15 ALaw, F32Be, F32Le, F64Be, F64Le, MuLaw, Pcm, S16Be, S16Le, S24Be, S24Le,
16 S32Be, S32Le, U16Be, U16Le, U24Be, U24Le, U32Be, U32Le, S8, U8,
17};
18
19pub struct Encoder<W: Write, F: Frame, P: Pcm>(W, PhantomData<(F, P)>);
21
22fn pcm_chan_32<C: Channel>(chan: C) -> i32 {
24 let input = chan.to_f64() * 2147483647.5;
25
26 if input < 0.0 {
27 let input = -input;
28 let fract = input % 1.0;
29 let mut whole = input - fract;
30 if fract > f64::EPSILON {
31 whole += 1.0;
32 }
33 (-whole) as i32
34 } else {
35 input as i32
36 }
37}
38
39impl<W: Write, F: Frame, P: Pcm> Encoder<W, F, P> {
40 pub fn new(writer: W, pcm: P) -> Self {
42 let _ = pcm;
43 Self(writer, PhantomData)
44 }
45}
46
47impl<W: Write, F: Frame> Encoder<W, F, U8> {
48 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
51 assert!(stream.len().is_some());
52 for frame in stream.into_iter() {
53 for chan in frame.channels().iter().cloned() {
54 let chan: Ch8 = chan.into();
55 let chan: i8 = chan.into();
56 self.0.write_all(&[chan as u8 ^ 0x80])?;
57 }
58 }
59 Ok(())
60 }
61}
62
63impl<W: Write, F: Frame> Encoder<W, F, S8> {
64 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
67 assert!(stream.len().is_some());
68 for frame in stream.into_iter() {
69 for chan in frame.channels().iter().cloned() {
70 let chan: Ch8 = chan.into();
71 let chan: i8 = chan.into();
72 self.0.write_all(&chan.to_le_bytes())?;
73 }
74 }
75 Ok(())
76 }
77}
78
79impl<W: Write, F: Frame> Encoder<W, F, MuLaw> {
80 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
83 assert!(stream.len().is_some());
84 for frame in stream.into_iter() {
85 for chan in frame.channels().iter().cloned() {
86 let chan: Ch16 = chan.into();
87 let chan: i16 = chan.into();
88 let chan: u8 = match chan >> 2 {
90 x if x <= -8159 => 0x00,
91 x if x <= -4064 => ((x + 8159) >> 8) as u8,
92 x if x <= -2016 => 0x10 | ((x + 4063) >> 7) as u8,
93 x if x <= -992 => 0x20 | ((x + 2015) >> 6) as u8,
94 x if x <= -480 => 0x30 | ((x + 991) >> 5) as u8,
95 x if x <= -224 => 0x40 | ((x + 479) >> 4) as u8,
96 x if x <= -96 => 0x50 | ((x + 223) >> 3) as u8,
97 x if x <= -32 => 0x60 | ((x + 95) >> 2) as u8,
98 x if x <= -1 => 0x70 | ((x + 31) >> 1) as u8,
99 x if x <= 30 => 0xF0 | ((30 - x) >> 1) as u8,
100 x if x <= 94 => 0xE0 | ((94 - x) >> 2) as u8,
101 x if x <= 222 => 0xD0 | ((222 - x) >> 3) as u8,
102 x if x <= 478 => 0xC0 | ((478 - x) >> 4) as u8,
103 x if x <= 990 => 0xB0 | ((990 - x) >> 5) as u8,
104 x if x <= 2014 => 0xA0 | ((2014 - x) >> 6) as u8,
105 x if x <= 4062 => 0x90 | ((4062 - x) >> 7) as u8,
106 x if x <= 8158 => 0x80 | ((8158 - x) >> 8) as u8,
107 _ => 0x80,
108 };
109 self.0.write_all(&[chan])?;
110 }
111 }
112 Ok(())
113 }
114}
115
116impl<W: Write, F: Frame> Encoder<W, F, ALaw> {
117 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
120 assert!(stream.len().is_some());
121 for frame in stream.into_iter() {
122 for chan in frame.channels().iter().cloned() {
123 let chan: Ch16 = chan.into();
124 let chan: i16 = chan.into();
125
126 const C_CLIP: i16 = 32635;
127 const LOG_TABLE: [u8; 128] = [
128 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
129 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6,
130 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
131 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
132 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
133 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
134 7, 7, 7, 7, 7, 7, 7, 7,
135 ];
136
137 let mut chan = if chan == -32768 { -32767 } else { chan };
138 let sign = ((!chan) >> 8) as u8 & 0x80;
139 if sign == 0 {
140 chan = -chan;
141 }
142 if chan > C_CLIP {
143 chan = C_CLIP;
144 }
145 let mut chan: u8 = if chan >= 256 {
146 let exponent = LOG_TABLE[((chan >> 8) & 0x7F) as usize];
147 let mantissa = ((chan >> (exponent + 3)) & 0x0F) as u8;
148 (exponent << 4) | mantissa
149 } else {
150 (chan >> 4) as u8
151 };
152 chan ^= sign ^ 0x55;
153
154 self.0.write_all(&[chan])?;
155 }
156 }
157 Ok(())
158 }
159}
160
161impl<W: Write, F: Frame> Encoder<W, F, U16Le> {
162 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
165 assert!(stream.len().is_some());
166 for frame in stream.into_iter() {
167 for chan in frame.channels().iter().cloned() {
168 let chan: Ch16 = chan.into();
169 let chan: i16 = chan.into();
170 self.0.write_all(&(chan ^ 0x8000u16 as i16).to_le_bytes())?;
171 }
172 }
173 Ok(())
174 }
175}
176
177impl<W: Write, F: Frame> Encoder<W, F, U16Be> {
178 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
181 assert!(stream.len().is_some());
182 for frame in stream.into_iter() {
183 for chan in frame.channels().iter().cloned() {
184 let chan: Ch16 = chan.into();
185 let chan: i16 = chan.into();
186 self.0.write_all(&(chan ^ 0x8000u16 as i16).to_be_bytes())?;
187 }
188 }
189 Ok(())
190 }
191}
192
193impl<W: Write, F: Frame> Encoder<W, F, S16Le> {
194 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
197 assert!(stream.len().is_some());
198 for frame in stream.into_iter() {
199 for chan in frame.channels().iter().cloned() {
200 let chan: Ch16 = chan.into();
201 let chan: i16 = chan.into();
202 self.0.write_all(&chan.to_le_bytes())?;
203 }
204 }
205 Ok(())
206 }
207}
208
209impl<W: Write, F: Frame> Encoder<W, F, S16Be> {
210 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
213 assert!(stream.len().is_some());
214 for frame in stream.into_iter() {
215 for chan in frame.channels().iter().cloned() {
216 let chan: Ch16 = chan.into();
217 let chan: i16 = chan.into();
218 self.0.write_all(&chan.to_be_bytes())?;
219 }
220 }
221 Ok(())
222 }
223}
224
225impl<W: Write, F: Frame> Encoder<W, F, U24Le> {
226 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
229 assert!(stream.len().is_some());
230 for frame in stream.into_iter() {
231 for chan in frame.channels() {
232 let chan = pcm_chan_32(*chan).to_le_bytes();
233 self.0.write_all(&[chan[0], chan[1], chan[2] ^ 0x80])?;
234 }
235 }
236 Ok(())
237 }
238}
239
240impl<W: Write, F: Frame> Encoder<W, F, U24Be> {
241 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
244 assert!(stream.len().is_some());
245 for frame in stream.into_iter() {
246 for chan in frame.channels() {
247 let chan = pcm_chan_32(*chan).to_be_bytes();
248 self.0.write_all(&[chan[1] ^ 0x80, chan[2], chan[3]])?;
249 }
250 }
251 Ok(())
252 }
253}
254
255impl<W: Write, F: Frame> Encoder<W, F, S24Le> {
256 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
259 assert!(stream.len().is_some());
260 for frame in stream.into_iter() {
261 for chan in frame.channels() {
262 let chan = pcm_chan_32(*chan).to_le_bytes();
263 self.0.write_all(&[chan[0], chan[1], chan[2]])?;
264 }
265 }
266 Ok(())
267 }
268}
269
270impl<W: Write, F: Frame> Encoder<W, F, S24Be> {
271 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
274 assert!(stream.len().is_some());
275 for frame in stream.into_iter() {
276 for chan in frame.channels() {
277 let chan = pcm_chan_32(*chan).to_be_bytes();
278 self.0.write_all(&[chan[1], chan[2], chan[3]])?;
279 }
280 }
281 Ok(())
282 }
283}
284
285impl<W: Write, F: Frame> Encoder<W, F, U32Le> {
286 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
289 assert!(stream.len().is_some());
290 for frame in stream.into_iter() {
291 for chan in frame.channels() {
292 let chan = pcm_chan_32(*chan) ^ (1 << 31);
293 self.0.write_all(&chan.to_le_bytes())?;
294 }
295 }
296 Ok(())
297 }
298}
299
300impl<W: Write, F: Frame> Encoder<W, F, U32Be> {
301 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
304 assert!(stream.len().is_some());
305 for frame in stream.into_iter() {
306 for chan in frame.channels() {
307 let chan = pcm_chan_32(*chan) ^ (1 << 31);
308 self.0.write_all(&chan.to_be_bytes())?;
309 }
310 }
311 Ok(())
312 }
313}
314
315impl<W: Write, F: Frame> Encoder<W, F, S32Le> {
316 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
319 assert!(stream.len().is_some());
320 for frame in stream.into_iter() {
321 for chan in frame.channels() {
322 let chan = pcm_chan_32(*chan);
323 self.0.write_all(&chan.to_le_bytes())?;
324 }
325 }
326 Ok(())
327 }
328}
329
330impl<W: Write, F: Frame> Encoder<W, F, S32Be> {
331 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
334 assert!(stream.len().is_some());
335 for frame in stream.into_iter() {
336 for chan in frame.channels() {
337 let chan = pcm_chan_32(*chan);
338 self.0.write_all(&chan.to_be_bytes())?;
339 }
340 }
341 Ok(())
342 }
343}
344
345impl<W: Write, F: Frame> Encoder<W, F, F32Le> {
346 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
349 assert!(stream.len().is_some());
350 for frame in stream.into_iter() {
351 for chan in frame.channels().iter().cloned() {
352 let chan: Ch32 = chan.into();
353 let chan: f32 = chan.into();
354 self.0.write_all(&chan.to_le_bytes())?;
355 }
356 }
357 Ok(())
358 }
359}
360
361impl<W: Write, F: Frame> Encoder<W, F, F32Be> {
362 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
365 assert!(stream.len().is_some());
366 for frame in stream.into_iter() {
367 for chan in frame.channels().iter().cloned() {
368 let chan: Ch32 = chan.into();
369 let chan: f32 = chan.into();
370 self.0.write_all(&chan.to_be_bytes())?;
371 }
372 }
373 Ok(())
374 }
375}
376
377impl<W: Write, F: Frame> Encoder<W, F, F64Le> {
378 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
381 assert!(stream.len().is_some());
382 for frame in stream.into_iter() {
383 for chan in frame.channels() {
384 self.0.write_all(&chan.to_f64().to_le_bytes())?;
385 }
386 }
387 Ok(())
388 }
389}
390
391impl<W: Write, F: Frame> Encoder<W, F, F64Be> {
392 pub fn encode<S: Stream<F>>(&mut self, stream: S) -> std::io::Result<()> {
395 assert!(stream.len().is_some());
396 for frame in stream.into_iter() {
397 for chan in frame.channels() {
398 self.0.write_all(&chan.to_f64().to_be_bytes())?;
399 }
400 }
401 Ok(())
402 }
403}