libflo_audio/lossy/
decoder.rs

1use super::encoder::TransformFrame;
2use super::mdct::{BlockSize, Mdct, WindowType};
3use super::psychoacoustic::{PsychoacousticModel, NUM_BARK_BANDS};
4
5/// Transform lossy decoder
6pub struct TransformDecoder {
7    /// Sample rate
8    sample_rate: u32,
9    /// Number of channels
10    channels: u8,
11    /// MDCT processor
12    mdct: Mdct,
13}
14
15impl TransformDecoder {
16    /// Create a new transform decoder
17    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    /// Decode a frame
28    /// Returns interleaved samples
29    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        // Dequantize coefficients
33        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        // IMDCT + overlap-add
51        self.mdct.synthesize(&dequantized, frame.block_size)
52    }
53
54    /// Reset decoder state
55    pub fn reset(&mut self) {
56        self.mdct.reset();
57    }
58}
59
60/// Deserialize a transform frame from bytes
61pub fn deserialize_frame(data: &[u8]) -> Option<TransformFrame> {
62    if data.len() < 2 {
63        return None;
64    }
65
66    let mut pos = 0;
67
68    // Block size
69    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    // Derive num_coeffs from block size
79    let num_coeffs = block_size.coefficients();
80
81    // Number of channels
82    let num_channels = data[pos] as usize;
83    pos += 1;
84
85    // Scale factors (stored as log-scale u16)
86    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            // Decode from log scale: 2^((log_sf - 32768) / 256)
97            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    // Coefficients (sparse encoded)
105    let mut coefficients = Vec::with_capacity(num_channels);
106    for _ in 0..num_channels {
107        // Length (4 bytes)
108        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        // Sparse decode
119        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
133/// Decode sparse coefficients
134pub 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        // Read zero count
141        let (zero_count, bytes_read) = decode_varint(&data[pos..]);
142        pos += bytes_read;
143
144        // Skip zeros
145        out_idx += zero_count as usize;
146
147        if pos >= data.len() {
148            break;
149        }
150
151        // Read non-zero count
152        let non_zero_count = data[pos] as usize;
153        pos += 1;
154
155        // Read non-zero values
156        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
169/// Decode varint, returns (value, bytes_read)
170fn 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}