libflo_audio/lossy/
decoder.rs1use super::encoder::TransformFrame;
2use super::mdct::{BlockSize, Mdct, WindowType};
3use super::psychoacoustic::{PsychoacousticModel, NUM_BARK_BANDS};
4
5pub struct TransformDecoder {
7 sample_rate: u32,
9 channels: u8,
11 mdct: Mdct,
13}
14
15impl TransformDecoder {
16 pub fn new(sample_rate: u32, channels: u8) -> Self {
18 let mdct = Mdct::new(channels as usize, WindowType::Vorbis);
19
20 Self {
21 sample_rate,
22 channels,
23 mdct,
24 }
25 }
26
27 pub fn decode_frame(&mut self, frame: &TransformFrame) -> Vec<f32> {
30 let freq_resolution = self.sample_rate as f32 / frame.block_size.samples() as f32;
31
32 let mut dequantized: Vec<Vec<f32>> = Vec::with_capacity(self.channels as usize);
34
35 for (ch, quantized) in frame.coefficients.iter().enumerate() {
36 let mut coeffs = vec![0.0f32; quantized.len()];
37
38 for (k, (&q, c)) in quantized.iter().zip(coeffs.iter_mut()).enumerate() {
39 let freq = (k as f32 + 0.5) * freq_resolution;
40 let band = PsychoacousticModel::freq_to_bark_band(freq);
41
42 if frame.scale_factors[ch][band] > 0.0 {
43 *c = q as f32 / frame.scale_factors[ch][band];
44 }
45 }
46
47 dequantized.push(coeffs);
48 }
49
50 self.mdct.synthesize(&dequantized, frame.block_size)
52 }
53
54 pub fn reset(&mut self) {
56 self.mdct.reset();
57 }
58}
59
60pub fn deserialize_frame(data: &[u8]) -> Option<TransformFrame> {
62 if data.len() < 2 {
63 return None;
64 }
65
66 let mut pos = 0;
67
68 let block_size = match data[pos] {
70 0 => BlockSize::Long,
71 1 => BlockSize::Short,
72 2 => BlockSize::Start,
73 3 => BlockSize::Stop,
74 _ => return None,
75 };
76 pos += 1;
77
78 let num_coeffs = block_size.coefficients();
80
81 let num_channels = data[pos] as usize;
83 pos += 1;
84
85 let mut scale_factors = Vec::with_capacity(num_channels);
87 for _ in 0..num_channels {
88 let mut sf = vec![0.0f32; NUM_BARK_BANDS];
89 for s in &mut sf {
90 if pos + 2 > data.len() {
91 return None;
92 }
93 let log_sf = u16::from_le_bytes(data[pos..pos + 2].try_into().ok()?);
94 pos += 2;
95
96 if log_sf > 0 {
98 *s = 2.0f32.powf((log_sf as f32 - 32768.0) / 256.0);
99 }
100 }
101 scale_factors.push(sf);
102 }
103
104 let mut coefficients = Vec::with_capacity(num_channels);
106 for _ in 0..num_channels {
107 if pos + 4 > data.len() {
109 return None;
110 }
111 let len = u32::from_le_bytes(data[pos..pos + 4].try_into().ok()?) as usize;
112 pos += 4;
113
114 if pos + len > data.len() {
115 return None;
116 }
117
118 let quantized = deserialize_sparse(&data[pos..pos + len], num_coeffs);
120 coefficients.push(quantized);
121
122 pos += len;
123 }
124
125 Some(TransformFrame {
126 coefficients,
127 scale_factors,
128 block_size,
129 num_samples: block_size.coefficients(),
130 })
131}
132
133pub fn deserialize_sparse(data: &[u8], num_coeffs: usize) -> Vec<i16> {
135 let mut output = vec![0i16; num_coeffs];
136 let mut pos = 0;
137 let mut out_idx = 0;
138
139 while pos < data.len() && out_idx < num_coeffs {
140 let (zero_count, bytes_read) = decode_varint(&data[pos..]);
142 pos += bytes_read;
143
144 out_idx += zero_count as usize;
146
147 if pos >= data.len() {
148 break;
149 }
150
151 let non_zero_count = data[pos] as usize;
153 pos += 1;
154
155 for _ in 0..non_zero_count {
157 if pos + 2 > data.len() || out_idx >= num_coeffs {
158 break;
159 }
160 output[out_idx] = i16::from_le_bytes([data[pos], data[pos + 1]]);
161 pos += 2;
162 out_idx += 1;
163 }
164 }
165
166 output
167}
168
169fn decode_varint(data: &[u8]) -> (u32, usize) {
171 let mut value = 0u32;
172 let mut shift = 0;
173 let mut bytes_read = 0;
174
175 for &byte in data {
176 value |= ((byte & 0x7F) as u32) << shift;
177 bytes_read += 1;
178 if byte & 0x80 == 0 {
179 break;
180 }
181 shift += 7;
182 if shift >= 32 {
183 break;
184 }
185 }
186
187 (value, bytes_read)
188}