1use crate::core_types::{
8 FrameParams, FRAME_SAMPLES, SUPERFRAME_FRAMES,
9 SUPERFRAME_SAMPLES, SUPERFRAME_BYTES_600, NUM_LSF, NUM_BANDS,
10};
11use crate::bitstream::unpack_superframe;
12use crate::quantize::dequantize_superframe;
13use crate::voicing::{NoiseGen, mixed_excitation};
14use crate::synthesis::SynthesisFrameProcessor;
15
16pub struct Decoder {
18 synth: SynthesisFrameProcessor,
20 prev_anchor_lsf: [f32; NUM_LSF],
22 noise: NoiseGen,
24 pulse_phase: f32,
26 initialized: bool,
28}
29
30impl Decoder {
31 pub fn new() -> Self {
32 Self {
33 synth: SynthesisFrameProcessor::new(),
34 prev_anchor_lsf: crate::core_types::default_lsf(),
35 noise: NoiseGen::new(12345),
36 pulse_phase: 0.0,
37 initialized: false,
38 }
39 }
40
41 pub fn decode(
46 &mut self,
47 bitstream: &[u8; SUPERFRAME_BYTES_600],
48 output: &mut [f32; SUPERFRAME_SAMPLES],
49 ) {
50 let (quantized, _bits_read) = unpack_superframe(bitstream);
52
53 let frames = dequantize_superframe(&quantized, &self.prev_anchor_lsf);
55
56 self.prev_anchor_lsf = frames[SUPERFRAME_FRAMES - 1].lsf;
58
59 for f in 0..SUPERFRAME_FRAMES {
61 let start = f * FRAME_SAMPLES;
62 let end = start + FRAME_SAMPLES;
63
64 self.synthesize_frame(
65 &frames[f],
66 &mut output[start..end],
67 f == 0 && !self.initialized,
68 );
69 }
70
71 self.initialized = true;
72 }
73
74 fn synthesize_frame(
76 &mut self,
77 params: &FrameParams,
78 output: &mut [f32],
79 first_frame: bool,
80 ) {
81 let n = output.len().min(FRAME_SAMPLES);
82
83 let mut excitation = [0.0f32; FRAME_SAMPLES];
85
86 let mut voicing = [0.0f32; NUM_BANDS];
88 voicing.copy_from_slice(¶ms.bandpass_voicing);
89
90 mixed_excitation(
91 params.pitch,
92 &voicing,
93 params.jitter,
94 &mut excitation[..n],
95 &mut self.pulse_phase,
96 &mut self.noise,
97 );
98
99 if first_frame {
101 self.synth.process_frame_no_interp(params, &excitation[..n], &mut output[..n]);
102 } else {
103 self.synth.process_frame(params, &excitation[..n], &mut output[..n]);
104 }
105 }
106
107 pub fn reset(&mut self) {
109 self.synth.reset();
110 self.prev_anchor_lsf = crate::core_types::default_lsf();
111 self.noise = NoiseGen::new(12345);
112 self.pulse_phase = 0.0;
113 self.initialized = false;
114 }
115
116 pub fn is_initialized(&self) -> bool {
118 self.initialized
119 }
120
121 pub fn prev_anchor_lsf(&self) -> &[f32; NUM_LSF] {
123 &self.prev_anchor_lsf
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use crate::core_types::{SAMPLE_RATE, SuperFrameQuantized};
131 use crate::bitstream::pack_superframe;
132 use crate::quantize;
133
134 fn pack_known(sq: &SuperFrameQuantized) -> [u8; SUPERFRAME_BYTES_600] {
136 let mut buf = [0u8; SUPERFRAME_BYTES_600];
137 pack_superframe(sq, &mut buf);
138 buf
139 }
140
141 #[test]
142 fn test_decode_output_length() {
143 let mut dec = Decoder::new();
144 let bitstream = [0u8; SUPERFRAME_BYTES_600];
145 let mut output = [0.0f32; SUPERFRAME_SAMPLES];
146
147 dec.decode(&bitstream, &mut output);
148
149 assert!(
151 output.iter().all(|x| x.is_finite()),
152 "All output samples must be finite"
153 );
154 }
155
156 #[test]
157 fn test_decode_zeros_quiet() {
158 let mut dec = Decoder::new();
160 let bitstream = [0u8; SUPERFRAME_BYTES_600];
161 let mut output = [0.0f32; SUPERFRAME_SAMPLES];
162
163 dec.decode(&bitstream, &mut output);
164
165 let rms = (output.iter().map(|x| x * x).sum::<f32>() / SUPERFRAME_SAMPLES as f32).sqrt();
166 assert!(
169 rms < 1.0,
170 "Zero bitstream should produce quiet output, rms={}",
171 rms
172 );
173 }
174
175 #[test]
176 fn test_decode_nonzero_bitstream() {
177 let sq = SuperFrameQuantized {
179 lsf_indices: [4, 4, 4, 4, 2, 2, 2, 2, 2, 2],
180 pitch_index: 30, gain_index: 20, voicing_bits: 0b0111, jitter_bit: 0,
184 };
185 let bitstream = pack_known(&sq);
186
187 let mut dec = Decoder::new();
188 let mut output = [0.0f32; SUPERFRAME_SAMPLES];
189 dec.decode(&bitstream, &mut output);
190
191 let energy: f32 = output.iter().map(|x| x * x).sum::<f32>() / SUPERFRAME_SAMPLES as f32;
193 assert!(
194 energy > 1e-8,
195 "Voiced frame with gain should produce energy, got {}",
196 energy
197 );
198 assert!(
199 output.iter().all(|x| x.is_finite()),
200 "Output must be finite"
201 );
202 }
203
204 #[test]
205 fn test_decode_state_updates() {
206 let mut dec = Decoder::new();
207 assert!(!dec.is_initialized());
208
209 let bitstream = [0u8; SUPERFRAME_BYTES_600];
210 let mut output = [0.0f32; SUPERFRAME_SAMPLES];
211
212 dec.decode(&bitstream, &mut output);
213 assert!(dec.is_initialized());
214
215 let lsf = dec.prev_anchor_lsf();
217 for i in 1..NUM_LSF {
218 assert!(
219 lsf[i] > lsf[i - 1],
220 "Anchor LSFs should be ordered after decode"
221 );
222 }
223 }
224
225 #[test]
226 fn test_decode_reset() {
227 let mut dec = Decoder::new();
228 let bitstream = [0u8; SUPERFRAME_BYTES_600];
229 let mut output = [0.0f32; SUPERFRAME_SAMPLES];
230
231 dec.decode(&bitstream, &mut output);
232 assert!(dec.is_initialized());
233
234 dec.reset();
235 assert!(!dec.is_initialized());
236 }
237
238 #[test]
239 fn test_decode_multi_superframe() {
240 let mut dec = Decoder::new();
242 let sq = SuperFrameQuantized {
243 lsf_indices: [3, 3, 3, 3, 1, 1, 1, 1, 1, 1],
244 pitch_index: 25,
245 gain_index: 15,
246 voicing_bits: 0b0101, jitter_bit: 0,
248 };
249 let bitstream = pack_known(&sq);
250
251 let mut output = [0.0f32; SUPERFRAME_SAMPLES];
252 for i in 0..5 {
253 dec.decode(&bitstream, &mut output);
254 assert!(
255 output.iter().all(|x| x.is_finite()),
256 "Output not finite at superframe {}",
257 i
258 );
259 let peak = output.iter().fold(0.0f32, |m, &s| m.max(s.abs()));
260 assert!(
261 peak < 100.0,
262 "Output blowing up at superframe {}: peak={}",
263 i, peak
264 );
265 }
266 }
267
268 #[test]
269 fn test_decode_deterministic() {
270 let sq = SuperFrameQuantized {
271 lsf_indices: [5, 3, 6, 2, 3, 1, 2, 3, 1, 2],
272 pitch_index: 35,
273 gain_index: 18,
274 voicing_bits: 0b0011,
275 jitter_bit: 1,
276 };
277 let bitstream = pack_known(&sq);
278
279 let mut dec1 = Decoder::new();
280 let mut dec2 = Decoder::new();
281 let mut out1 = [0.0f32; SUPERFRAME_SAMPLES];
282 let mut out2 = [0.0f32; SUPERFRAME_SAMPLES];
283
284 dec1.decode(&bitstream, &mut out1);
285 dec2.decode(&bitstream, &mut out2);
286
287 for i in 0..SUPERFRAME_SAMPLES {
288 assert!(
289 (out1[i] - out2[i]).abs() < 1e-6,
290 "Determinism failed at sample [{}]: {} vs {}",
291 i, out1[i], out2[i]
292 );
293 }
294 }
295
296 #[test]
297 fn test_voiced_vs_unvoiced_differ() {
298 let sq_voiced = SuperFrameQuantized {
300 lsf_indices: [4, 4, 4, 4, 2, 2, 2, 2, 2, 2],
301 pitch_index: 30,
302 gain_index: 20,
303 voicing_bits: 0b0111, jitter_bit: 0,
305 };
306 let sq_unvoiced = SuperFrameQuantized {
307 lsf_indices: [4, 4, 4, 4, 2, 2, 2, 2, 2, 2],
308 pitch_index: 30,
309 gain_index: 20,
310 voicing_bits: 0b0000, jitter_bit: 0,
312 };
313
314 let mut dec = Decoder::new();
315 let mut out_v = [0.0f32; SUPERFRAME_SAMPLES];
316 dec.decode(&pack_known(&sq_voiced), &mut out_v);
317
318 dec.reset();
319 let mut out_uv = [0.0f32; SUPERFRAME_SAMPLES];
320 dec.decode(&pack_known(&sq_unvoiced), &mut out_uv);
321
322 let diff: f32 = out_v.iter().zip(out_uv.iter())
324 .map(|(a, b)| (a - b).abs())
325 .sum::<f32>() / SUPERFRAME_SAMPLES as f32;
326 assert!(
327 diff > 1e-6,
328 "Voiced and unvoiced should produce different output, avg_diff={}",
329 diff
330 );
331 }
332
333 #[test]
334 fn test_different_bitstreams_differ() {
335 let sq1 = SuperFrameQuantized {
336 lsf_indices: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
337 pitch_index: 10,
338 gain_index: 10,
339 voicing_bits: 0b0111,
340 jitter_bit: 0,
341 };
342 let sq2 = SuperFrameQuantized {
343 lsf_indices: [6, 6, 6, 6, 3, 3, 3, 3, 3, 3],
344 pitch_index: 50,
345 gain_index: 25,
346 voicing_bits: 0b0000,
347 jitter_bit: 1,
348 };
349
350 let mut dec = Decoder::new();
351 let mut out1 = [0.0f32; SUPERFRAME_SAMPLES];
352 dec.decode(&pack_known(&sq1), &mut out1);
353
354 dec.reset();
355 let mut out2 = [0.0f32; SUPERFRAME_SAMPLES];
356 dec.decode(&pack_known(&sq2), &mut out2);
357
358 assert_ne!(
359 out1.as_slice(), out2.as_slice(),
360 "Different bitstreams should produce different output"
361 );
362 }
363}