libflo_audio/lossless/
decoder.rs1use crate::core::audio_constants::i32_to_f32;
2use crate::core::types::{ChannelData, FloFile};
3use crate::{core::rice, FloResult, Reader};
4use alloc::vec;
5use alloc::vec::Vec;
6
7pub struct Decoder;
9
10impl Decoder {
11 pub fn new() -> Self {
12 Decoder
13 }
14
15 pub fn decode(&self, data: &[u8]) -> FloResult<Vec<f32>> {
17 let reader = Reader::new();
18 let file = reader.read(data)?;
19 self.decode_file(&file)
20 }
21
22 pub fn decode_file(&self, file: &FloFile) -> FloResult<Vec<f32>> {
24 let channels = file.header.channels as usize;
25 let halved_mid_side = file.header.version_minor >= 2;
26 let mut all_samples: Vec<Vec<i32>> = vec![vec![]; channels];
27
28 for frame in &file.frames {
29 let use_mid_side = channels == 2 && (frame.flags & 0x01) != 0;
30
31 let mut frame_channels: Vec<Vec<i32>> = Vec::with_capacity(channels);
32
33 for ch_data in &frame.channels {
34 let samples = self.decode_channel_int(ch_data, frame.frame_samples as usize)?;
35 frame_channels.push(samples);
36 }
37
38 if use_mid_side && frame_channels.len() == 2 {
40 let (left, right) =
41 self.decode_mid_side(&frame_channels[0], &frame_channels[1], halved_mid_side);
42 all_samples[0].extend(left);
43 all_samples[1].extend(right);
44 } else {
45 for (ch_idx, samples) in frame_channels.into_iter().enumerate() {
46 if ch_idx < channels {
47 all_samples[ch_idx].extend(samples);
48 }
49 }
50 }
51 }
52
53 let max_len = all_samples.iter().map(|v| v.len()).max().unwrap_or(0);
55 let mut interleaved = Vec::with_capacity(max_len * channels);
56
57 if channels == 2 && all_samples[0].len() == all_samples[1].len() {
59 let left = &all_samples[0];
60 let right = &all_samples[1];
61 for i in 0..left.len() {
62 interleaved.push(i32_to_f32(left[i]));
63 interleaved.push(i32_to_f32(right[i]));
64 }
65 } else {
66 for i in 0..max_len {
68 for ch in 0..channels {
69 let sample = all_samples[ch].get(i).copied().unwrap_or(0);
70 interleaved.push(i32_to_f32(sample));
71 }
72 }
73 }
74
75 Ok(interleaved)
76 }
77
78 fn decode_mid_side(&self, mid: &[i32], side: &[i32], halved: bool) -> (Vec<i32>, Vec<i32>) {
80 if halved {
81 let left: Vec<i32> = mid
82 .iter()
83 .zip(side.iter())
84 .map(|(&m, &s)| m + ((s + (s & 1)) >> 1))
85 .collect();
86 let right: Vec<i32> = mid
87 .iter()
88 .zip(side.iter())
89 .map(|(&m, &s)| m - (s >> 1))
90 .collect();
91 (left, right)
92 } else {
93 let left: Vec<i32> = mid
94 .iter()
95 .zip(side.iter())
96 .map(|(&m, &s)| (m + s) / 2)
97 .collect();
98 let right: Vec<i32> = mid
99 .iter()
100 .zip(side.iter())
101 .map(|(&m, &s)| (m - s) / 2)
102 .collect();
103 (left, right)
104 }
105 }
106
107 fn decode_channel_int(
109 &self,
110 ch_data: &ChannelData,
111 frame_samples: usize,
112 ) -> FloResult<Vec<i32>> {
113 let has_coeffs = !ch_data.predictor_coeffs.is_empty();
114 let has_residuals = !ch_data.residuals.is_empty();
115 let shift_bits = ch_data.shift_bits;
116
117 let is_fixed_predictor = !has_coeffs && has_residuals && shift_bits >= 128;
119
120 if is_fixed_predictor {
121 let fixed_order = (shift_bits - 128) as usize;
123
124 let residuals =
125 rice::decode_i32(&ch_data.residuals, ch_data.rice_parameter, frame_samples);
126
127 return Ok(self.reconstruct_fixed(fixed_order, &residuals, frame_samples));
128 }
129
130 if has_coeffs {
131 let residuals =
133 rice::decode_i32(&ch_data.residuals, ch_data.rice_parameter, frame_samples);
134
135 let order = ch_data.predictor_coeffs.len();
136
137 let samples = self.reconstruct_lpc_int(
138 &ch_data.predictor_coeffs,
139 &residuals,
140 shift_bits,
141 order,
142 frame_samples,
143 );
144
145 return Ok(samples);
146 }
147
148 if has_residuals {
149 let mut samples = Vec::with_capacity(frame_samples);
151 for chunk in ch_data.residuals.chunks(2) {
152 if chunk.len() == 2 {
153 samples.push(i16::from_le_bytes([chunk[0], chunk[1]]) as i32);
154 }
155 }
156 while samples.len() < frame_samples {
157 samples.push(0);
158 }
159 return Ok(samples);
160 }
161
162 Ok(vec![0; frame_samples])
164 }
165
166 #[inline]
168 fn reconstruct_lpc_int(
169 &self,
170 coeffs: &[i32],
171 residuals: &[i32],
172 shift: u8,
173 order: usize,
174 target_len: usize,
175 ) -> Vec<i32> {
176 let mut samples = Vec::with_capacity(target_len);
177 let actual_len = target_len.min(residuals.len());
178
179 let warmup_len = order.min(actual_len);
181 samples.extend_from_slice(&residuals[..warmup_len]);
182
183 for i in order..actual_len {
186 let mut prediction: i64 = 0;
187
188 for j in 0..order {
191 prediction += (coeffs[j] as i64) * (samples[i - j - 1] as i64);
192 }
193
194 samples.push((prediction >> shift) as i32 + residuals[i]);
195 }
196
197 samples.resize(target_len, 0);
199 samples
200 }
201
202 fn reconstruct_fixed(&self, order: usize, residuals: &[i32], target_len: usize) -> Vec<i32> {
204 let mut samples = Vec::with_capacity(target_len);
205
206 if residuals.is_empty() {
207 return vec![0; target_len];
208 }
209
210 match order {
211 0 => {
212 samples.extend_from_slice(residuals);
214 }
215 1 => {
216 samples.push(residuals[0]);
218 for i in 1..residuals.len().min(target_len) {
219 samples.push(residuals[i].wrapping_add(samples[i - 1]));
220 }
221 }
222 2 => {
223 if !residuals.is_empty() {
225 samples.push(residuals[0]);
226 }
227 if residuals.len() > 1 {
228 samples.push(residuals[1].wrapping_add(samples[0]));
229 }
230 for i in 2..residuals.len().min(target_len) {
231 let pred = (2i64 * samples[i - 1] as i64 - samples[i - 2] as i64) as i32;
232 samples.push(residuals[i].wrapping_add(pred));
233 }
234 }
235 3 => {
236 if !residuals.is_empty() {
238 samples.push(residuals[0]);
239 }
240 if residuals.len() > 1 {
241 samples.push(residuals[1].wrapping_add(samples[0]));
242 }
243 if residuals.len() > 2 {
244 let pred = (2i64 * samples[1] as i64 - samples[0] as i64) as i32;
245 samples.push(residuals[2].wrapping_add(pred));
246 }
247 for i in 3..residuals.len().min(target_len) {
248 let pred = (3i64 * samples[i - 1] as i64 - 3i64 * samples[i - 2] as i64
249 + samples[i - 3] as i64) as i32;
250 samples.push(residuals[i].wrapping_add(pred));
251 }
252 }
253 4 => {
254 if !residuals.is_empty() {
256 samples.push(residuals[0]);
257 }
258 if residuals.len() > 1 {
259 samples.push(residuals[1].wrapping_add(samples[0]));
260 }
261 if residuals.len() > 2 {
262 let pred = (2i64 * samples[1] as i64 - samples[0] as i64) as i32;
263 samples.push(residuals[2].wrapping_add(pred));
264 }
265 if residuals.len() > 3 {
266 let pred = (3i64 * samples[2] as i64 - 3i64 * samples[1] as i64
267 + samples[0] as i64) as i32;
268 samples.push(residuals[3].wrapping_add(pred));
269 }
270 for i in 4..residuals.len().min(target_len) {
271 let pred = (4i64 * samples[i - 1] as i64 - 6i64 * samples[i - 2] as i64
272 + 4i64 * samples[i - 3] as i64
273 - samples[i - 4] as i64) as i32;
274 samples.push(residuals[i].wrapping_add(pred));
275 }
276 }
277 _ => {
278 samples.extend_from_slice(residuals);
280 }
281 }
282
283 while samples.len() < target_len {
285 samples.push(0);
286 }
287
288 samples
289 }
290}
291
292impl Default for Decoder {
293 fn default() -> Self {
294 Self::new()
295 }
296}