libflo_audio/lossy/
decoder.rs1use super::encoder::TransformFrame;
2use super::mdct::{BlockSize, Mdct, WindowType, LONG_BLOCK_SIZE, SHORT_BLOCK_SIZE};
3use super::psychoacoustic::{PsychoacousticModel, NUM_BARK_BANDS};
4use alloc::vec;
5use alloc::vec::Vec;
6
7pub struct TransformDecoder {
9 sample_rate: u32,
11 channels: u8,
13 mdct: Mdct,
15}
16
17impl TransformDecoder {
18 pub fn new(sample_rate: u32, channels: u8) -> Self {
20 let mdct = Mdct::new(channels as usize, WindowType::Vorbis);
21
22 Self {
23 sample_rate,
24 channels,
25 mdct,
26 }
27 }
28
29 pub fn decode_frame(&mut self, frame: &TransformFrame) -> Vec<f32> {
32 if frame.block_size.is_short_group() {
33 let freq_resolution = self.sample_rate as f32 / SHORT_BLOCK_SIZE as f32;
36 let coeffs_per_window = SHORT_BLOCK_SIZE / 2;
37 self.decode_frame_inner(frame, coeffs_per_window, freq_resolution)
38 } else {
39 let freq_resolution = self.sample_rate as f32 / LONG_BLOCK_SIZE as f32;
40 let coeffs_per_window = LONG_BLOCK_SIZE / 2;
41 self.decode_frame_inner(frame, coeffs_per_window, freq_resolution)
42 }
43 }
44
45 fn decode_frame_inner(
47 &mut self,
48 frame: &TransformFrame,
49 coeffs_per_window: usize,
50 freq_resolution: f32,
51 ) -> Vec<f32> {
52 let mut dequantized: Vec<Vec<f32>> = Vec::with_capacity(self.channels as usize);
54
55 for (ch, quantized) in frame.coefficients.iter().enumerate() {
56 let mut coeffs = vec![0.0f32; quantized.len()];
57
58 for (k, (&q, c)) in quantized.iter().zip(coeffs.iter_mut()).enumerate() {
59 let bin = k % coeffs_per_window;
60 let freq = (bin as f32 + 0.5) * freq_resolution;
61 let band = PsychoacousticModel::freq_to_bark_band(freq);
62
63 if frame.scale_factors[ch][band] > 0.0 {
64 *c = q as f32 / frame.scale_factors[ch][band];
65 }
66 }
67
68 dequantized.push(coeffs);
69 }
70
71 self.mdct.synthesize(&dequantized, frame.block_size)
73 }
74
75 pub fn reset(&mut self) {
77 self.mdct.reset();
78 }
79}
80
81pub fn deserialize_frame(data: &[u8]) -> Option<TransformFrame> {
83 if data.len() < 2 {
84 return None;
85 }
86
87 let mut pos = 0;
88
89 let block_size = match data[pos] {
91 0 => BlockSize::Long,
92 1 => BlockSize::Short,
93 2 => BlockSize::Start,
94 3 => BlockSize::Stop,
95 _ => return None,
96 };
97 pos += 1;
98
99 let num_coeffs = block_size.frame_coefficients();
101
102 let num_channels = data[pos] as usize;
104 pos += 1;
105
106 let mut scale_factors = Vec::with_capacity(num_channels);
108 for _ in 0..num_channels {
109 let mut sf = vec![0.0f32; NUM_BARK_BANDS];
110 for s in &mut sf {
111 if pos + 2 > data.len() {
112 return None;
113 }
114 let log_sf = u16::from_le_bytes(data[pos..pos + 2].try_into().ok()?);
115 pos += 2;
116
117 if log_sf > 0 {
119 *s = libm::powf(2.0f32, (log_sf as f32 - 32768.0) / 256.0);
120 }
121 }
122 scale_factors.push(sf);
123 }
124
125 let mut coefficients = Vec::with_capacity(num_channels);
127 for _ in 0..num_channels {
128 if pos + 4 > data.len() {
130 return None;
131 }
132 let len = u32::from_le_bytes(data[pos..pos + 4].try_into().ok()?) as usize;
133 pos += 4;
134
135 if pos + len > data.len() {
136 return None;
137 }
138
139 let quantized = deserialize_sparse(&data[pos..pos + len], num_coeffs);
141 coefficients.push(quantized);
142
143 pos += len;
144 }
145
146 Some(TransformFrame {
147 coefficients,
148 scale_factors,
149 block_size,
150 num_samples: block_size.frame_coefficients(),
151 })
152}
153
154pub fn deserialize_sparse(data: &[u8], num_coeffs: usize) -> Vec<i16> {
156 let mut output = vec![0i16; num_coeffs];
157 let mut pos = 0;
158 let mut out_idx = 0;
159
160 while pos < data.len() && out_idx < num_coeffs {
161 let (zero_count, bytes_read) = decode_varint(&data[pos..]);
163 pos += bytes_read;
164
165 out_idx += zero_count as usize;
167
168 if pos >= data.len() {
169 break;
170 }
171
172 let non_zero_count = data[pos] as usize;
174 pos += 1;
175
176 for _ in 0..non_zero_count {
178 if pos + 2 > data.len() || out_idx >= num_coeffs {
179 break;
180 }
181 output[out_idx] = i16::from_le_bytes([data[pos], data[pos + 1]]);
182 pos += 2;
183 out_idx += 1;
184 }
185 }
186
187 output
188}
189
190fn decode_varint(data: &[u8]) -> (u32, usize) {
192 let mut value = 0u32;
193 let mut shift = 0;
194 let mut bytes_read = 0;
195
196 for &byte in data {
197 value |= ((byte & 0x7F) as u32) << shift;
198 bytes_read += 1;
199 if byte & 0x80 == 0 {
200 break;
201 }
202 shift += 7;
203 if shift >= 32 {
204 break;
205 }
206 }
207
208 (value, bytes_read)
209}