1use crate::core::audio_constants::i32_to_f32;
2use crate::core::{rice, ChannelData, FloResult, Frame, FrameType, Header, TocEntry};
3use crate::lossless::Decoder as LosslessDecoder;
4use crate::lossy::{deserialize_frame, TransformDecoder};
5use crate::{Reader, ResidualEncoding, MAGIC};
6use alloc::vec;
7use alloc::vec::Vec;
8
9use super::types::{DecoderState, StreamingAudioInfo};
10
11pub struct StreamingDecoder {
12 buffer: Vec<u8>,
14 state: DecoderState,
16 header: Option<Header>,
18 toc: Vec<TocEntry>,
20 current_frame: usize,
22 data_offset: usize,
24 lossy_decoder: Option<TransformDecoder>,
26 is_lossy: bool,
28 skipped_preroll: bool,
30}
31
32impl StreamingDecoder {
33 pub fn new() -> Self {
35 Self {
36 buffer: Vec::with_capacity(64 * 1024),
37 state: DecoderState::WaitingForHeader,
38 header: None,
39 toc: Vec::new(),
40 current_frame: 0,
41 data_offset: 0,
42 lossy_decoder: None,
43 is_lossy: false,
44 skipped_preroll: false,
45 }
46 }
47
48 pub fn state(&self) -> DecoderState {
50 self.state
51 }
52
53 pub fn info(&self) -> Option<StreamingAudioInfo> {
55 self.header.as_ref().map(|h| StreamingAudioInfo {
56 sample_rate: h.sample_rate,
57 channels: h.channels,
58 bit_depth: h.bit_depth,
59 total_samples: h.total_samples,
60 is_lossy: self.is_lossy,
61 })
62 }
63
64 pub fn frames_available(&self) -> usize {
66 if self.state != DecoderState::Ready {
67 return 0;
68 }
69 self.count_complete_frames()
70 }
71
72 pub fn feed(&mut self, data: &[u8]) -> FloResult<bool> {
74 if self.state == DecoderState::Error || self.state == DecoderState::Finished {
75 return Ok(false);
76 }
77
78 self.buffer.extend_from_slice(data);
79 self.try_advance_state()
80 }
81
82 pub fn next_frame(&mut self) -> FloResult<Option<Vec<f32>>> {
84 if self.state != DecoderState::Ready {
85 return Ok(None);
86 }
87
88 let header = match self.header.as_ref() {
89 Some(h) => h.clone(),
90 None => {
91 return Err("No header".into());
92 }
93 };
94
95 if self.current_frame >= self.toc.len() {
96 self.state = DecoderState::Finished;
97 return Ok(None);
98 }
99
100 let toc_entry = &self.toc[self.current_frame];
101 let frame_start =
102 self.data_offset
103 .checked_add(usize::try_from(toc_entry.byte_offset).map_err(|_| {
104 crate::core::FloError::from("Frame offset does not fit in memory")
105 })?)
106 .ok_or_else(|| {
107 crate::core::FloError::from("Frame offset overflows memory address space")
108 })?;
109 let frame_end = frame_start
110 .checked_add(toc_entry.frame_size as usize)
111 .ok_or_else(|| {
112 crate::core::FloError::from("Frame size overflows memory address space")
113 })?;
114
115 if frame_end > self.buffer.len() {
116 return Ok(None);
117 }
118
119 let frame_data = &self.buffer[frame_start..frame_end];
120 let frame = self.parse_frame(frame_data, header.channels)?;
121
122 self.current_frame += 1;
123 let samples = self.decode_frame(&frame, &header)?;
124
125 Ok(Some(samples))
126 }
127
128 pub fn decode_available(&mut self) -> FloResult<Vec<f32>> {
130 if self.state != DecoderState::Ready {
131 return Ok(Vec::new());
132 }
133
134 let samples = self.decode_with_standard_decoder()?;
135 self.state = DecoderState::Finished;
136 Ok(samples)
137 }
138
139 pub fn reset(&mut self) {
141 self.buffer.clear();
142 self.state = DecoderState::WaitingForHeader;
143 self.header = None;
144 self.toc.clear();
145 self.current_frame = 0;
146 self.data_offset = 0;
147 self.lossy_decoder = None;
148 self.is_lossy = false;
149 self.skipped_preroll = false;
150 }
151
152 pub fn buffered_bytes(&self) -> usize {
154 self.buffer.len()
155 }
156
157 pub fn available_frames(&self) -> usize {
159 if self.state != DecoderState::Ready {
160 return 0;
161 }
162 self.count_complete_frames()
163 .saturating_sub(self.current_frame)
164 }
165
166 pub fn current_frame_index(&self) -> usize {
168 self.current_frame
169 }
170
171 fn try_advance_state(&mut self) -> FloResult<bool> {
174 match self.state {
175 DecoderState::WaitingForHeader => {
176 if self.try_parse_header()? {
177 self.state = DecoderState::WaitingForToc;
178 return self.try_advance_state();
179 }
180 }
181 DecoderState::WaitingForToc => {
182 if self.try_parse_toc()? {
183 self.state = DecoderState::Ready;
184 return Ok(true);
185 }
186 }
187 DecoderState::Ready => {
188 return Ok(self.count_complete_frames() > self.current_frame);
189 }
190 _ => {}
191 }
192 Ok(false)
193 }
194
195 fn try_parse_header(&mut self) -> FloResult<bool> {
196 if self.buffer.len() < 70 {
198 return Ok(false);
199 }
200
201 if self.buffer[0..4] != MAGIC {
202 self.state = DecoderState::Error;
203 return Err("Invalid flo file: bad magic".into());
204 }
205
206 let header = Header {
207 version_major: self.buffer[4],
208 version_minor: self.buffer[5],
209 flags: u16::from_le_bytes([self.buffer[6], self.buffer[7]]),
210 sample_rate: u32::from_le_bytes([
211 self.buffer[8],
212 self.buffer[9],
213 self.buffer[10],
214 self.buffer[11],
215 ]),
216 channels: self.buffer[12],
217 bit_depth: self.buffer[13],
218 total_samples: u64::from_le_bytes([
219 self.buffer[14],
220 self.buffer[15],
221 self.buffer[16],
222 self.buffer[17],
223 self.buffer[18],
224 self.buffer[19],
225 self.buffer[20],
226 self.buffer[21],
227 ]),
228 compression_level: self.buffer[22],
229 data_crc32: u32::from_le_bytes([
230 self.buffer[26],
231 self.buffer[27],
232 self.buffer[28],
233 self.buffer[29],
234 ]),
235 header_size: u64::from_le_bytes([
236 self.buffer[30],
237 self.buffer[31],
238 self.buffer[32],
239 self.buffer[33],
240 self.buffer[34],
241 self.buffer[35],
242 self.buffer[36],
243 self.buffer[37],
244 ]),
245 toc_size: u64::from_le_bytes([
246 self.buffer[38],
247 self.buffer[39],
248 self.buffer[40],
249 self.buffer[41],
250 self.buffer[42],
251 self.buffer[43],
252 self.buffer[44],
253 self.buffer[45],
254 ]),
255 data_size: u64::from_le_bytes([
256 self.buffer[46],
257 self.buffer[47],
258 self.buffer[48],
259 self.buffer[49],
260 self.buffer[50],
261 self.buffer[51],
262 self.buffer[52],
263 self.buffer[53],
264 ]),
265 extra_size: u64::from_le_bytes([
266 self.buffer[54],
267 self.buffer[55],
268 self.buffer[56],
269 self.buffer[57],
270 self.buffer[58],
271 self.buffer[59],
272 self.buffer[60],
273 self.buffer[61],
274 ]),
275 meta_size: u64::from_le_bytes([
276 self.buffer[62],
277 self.buffer[63],
278 self.buffer[64],
279 self.buffer[65],
280 self.buffer[66],
281 self.buffer[67],
282 self.buffer[68],
283 self.buffer[69],
284 ]),
285 };
286
287 if header.sample_rate == 0 || header.channels == 0 {
288 self.state = DecoderState::Error;
289 return Err("Invalid audio format in header".into());
290 }
291
292 self.is_lossy = (header.flags & 0x01) != 0;
293 if self.is_lossy {
294 self.lossy_decoder = Some(TransformDecoder::new(header.sample_rate, header.channels));
295 }
296
297 self.header = Some(header);
298 Ok(true)
299 }
300
301 fn try_parse_toc(&mut self) -> FloResult<bool> {
302 let header = self.header.as_ref().ok_or("No header")?;
303 let toc_start: usize = 70;
304 let toc_size = usize::try_from(header.toc_size)
305 .map_err(|_| crate::core::FloError::from("TOC size does not fit in memory"))?;
306 let toc_end = toc_start.checked_add(toc_size).ok_or_else(|| {
307 crate::core::FloError::from("TOC size overflows memory address space")
308 })?;
309
310 if self.buffer.len() < toc_end {
311 return Ok(false);
312 }
313
314 if header.toc_size >= 4 {
315 let num_entries = u32::from_le_bytes([
316 self.buffer[toc_start],
317 self.buffer[toc_start + 1],
318 self.buffer[toc_start + 2],
319 self.buffer[toc_start + 3],
320 ]) as usize;
321
322 if num_entries > 100_000 {
323 return Err("Invalid TOC: too many entries".into());
324 }
325
326 let entries_size = num_entries.checked_mul(20).ok_or_else(|| {
327 crate::core::FloError::from("TOC entry count overflows memory address space")
328 })?;
329 if entries_size > toc_size - 4 {
330 return Err("TOC entries exceed TOC size".into());
331 }
332
333 let entries_start = toc_start + 4;
334 for i in 0..num_entries {
335 let offset = entries_start + i * 20;
336
337 self.toc.push(TocEntry {
338 frame_index: u32::from_le_bytes([
339 self.buffer[offset],
340 self.buffer[offset + 1],
341 self.buffer[offset + 2],
342 self.buffer[offset + 3],
343 ]),
344 byte_offset: u64::from_le_bytes([
345 self.buffer[offset + 4],
346 self.buffer[offset + 5],
347 self.buffer[offset + 6],
348 self.buffer[offset + 7],
349 self.buffer[offset + 8],
350 self.buffer[offset + 9],
351 self.buffer[offset + 10],
352 self.buffer[offset + 11],
353 ]),
354 frame_size: u32::from_le_bytes([
355 self.buffer[offset + 12],
356 self.buffer[offset + 13],
357 self.buffer[offset + 14],
358 self.buffer[offset + 15],
359 ]),
360 timestamp_ms: u32::from_le_bytes([
361 self.buffer[offset + 16],
362 self.buffer[offset + 17],
363 self.buffer[offset + 18],
364 self.buffer[offset + 19],
365 ]),
366 });
367 }
368 }
369
370 self.data_offset = toc_end;
371 Ok(true)
372 }
373
374 fn count_complete_frames(&self) -> usize {
375 let mut count = 0;
376 for entry in &self.toc {
377 let Some(byte_offset) = usize::try_from(entry.byte_offset).ok() else {
378 break;
379 };
380 let Some(frame_start) = self.data_offset.checked_add(byte_offset) else {
381 break;
382 };
383 let Some(frame_end) = frame_start.checked_add(entry.frame_size as usize) else {
384 break;
385 };
386 if frame_end <= self.buffer.len() {
387 count += 1;
388 } else {
389 break;
390 }
391 }
392 count
393 }
394
395 fn parse_frame(&self, data: &[u8], channels: u8) -> FloResult<Frame> {
396 if data.len() < 6 {
397 return Err("Frame too small".into());
398 }
399
400 let frame_type_byte = data[0];
401 let frame_samples = u32::from_le_bytes([data[1], data[2], data[3], data[4]]);
402 let flags = data[5];
403
404 let frame_type = FrameType::from(frame_type_byte);
405 let mut frame = Frame::new(frame_type_byte, frame_samples);
406 frame.flags = flags;
407
408 let num_channels = if frame_type == FrameType::Transform {
409 1
410 } else {
411 channels as usize
412 };
413
414 let mut pos: usize = 6;
415 for _ in 0..num_channels {
416 if pos.checked_add(4).is_none_or(|end| end > data.len()) {
417 return Err("Frame truncated".into());
418 }
419
420 let ch_size =
421 u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]])
422 as usize;
423 pos += 4;
424
425 let channel_end = pos.checked_add(ch_size).ok_or_else(|| {
426 crate::core::FloError::from("Channel size overflows memory address space")
427 })?;
428 if channel_end > data.len() {
429 return Err("Channel data truncated".into());
430 }
431
432 let ch_data = &data[pos..channel_end];
433 pos = channel_end;
434
435 let channel = match frame_type {
436 FrameType::Silence => ChannelData::new_silence(),
437 FrameType::Raw | FrameType::Transform => ChannelData {
438 predictor_coeffs: vec![],
439 shift_bits: 0,
440 residual_encoding: ResidualEncoding::Raw,
441 rice_parameter: 0,
442 residuals: ch_data.to_vec(),
443 },
444 _ => self.parse_alpc_channel(ch_data, frame_type)?,
445 };
446
447 frame.channels.push(channel);
448 }
449
450 Ok(frame)
451 }
452
453 fn parse_alpc_channel(&self, data: &[u8], _frame_type: FrameType) -> FloResult<ChannelData> {
454 if data.is_empty() {
455 return Ok(ChannelData::new_silence());
456 }
457
458 let order = data[0] as usize;
459 if order > 12 {
460 return Err("Invalid LPC order".into());
461 }
462
463 let coeff_bytes = order * 4;
464 let min_size = 1 + coeff_bytes + 2; if data.len() < min_size {
466 return Err("ALPC channel too small".into());
467 }
468
469 let mut coefficients = Vec::with_capacity(order);
471 for i in 0..order {
472 let offset = 1 + i * 4;
473 let coeff = i32::from_le_bytes([
474 data[offset],
475 data[offset + 1],
476 data[offset + 2],
477 data[offset + 3],
478 ]);
479 coefficients.push(coeff);
480 }
481
482 let mut pos = 1 + coeff_bytes;
483
484 let shift_bits = data[pos];
486 pos += 1;
487
488 let residual_encoding_byte = data[pos];
490 let residual_encoding = ResidualEncoding::from(residual_encoding_byte);
491 pos += 1;
492
493 let rice_parameter = if residual_encoding == ResidualEncoding::Rice {
495 if pos >= data.len() {
496 return Err("Missing rice parameter".into());
497 }
498 let rp = data[pos];
499 pos += 1;
500 rp
501 } else {
502 0
503 };
504
505 let residuals = data[pos..].to_vec();
507
508 Ok(ChannelData {
509 predictor_coeffs: coefficients,
510 shift_bits,
511 residual_encoding,
512 rice_parameter,
513 residuals,
514 })
515 }
516
517 fn decode_frame(&mut self, frame: &Frame, header: &Header) -> FloResult<Vec<f32>> {
518 let frame_type = FrameType::from(frame.frame_type);
519
520 if frame_type == FrameType::Transform {
522 if frame.channels.is_empty() {
523 return Ok(Vec::new());
524 }
525
526 let frame_data = &frame.channels[0].residuals;
527 if let Some(transform_frame) = deserialize_frame(frame_data) {
528 let decoder = self.lossy_decoder.get_or_insert_with(|| {
529 TransformDecoder::new(header.sample_rate, header.channels)
530 });
531 let samples = decoder.decode_frame(&transform_frame);
532
533 if !self.skipped_preroll {
535 self.skipped_preroll = true;
536 return Ok(Vec::new());
537 }
538
539 return Ok(samples);
540 }
541 return Ok(Vec::new());
542 }
543
544 let channels = header.channels as usize;
546 let frame_samples = frame.frame_samples as usize;
547 let use_mid_side = channels == 2 && (frame.flags & 0x01) != 0;
548
549 let mut frame_channels: Vec<Vec<i32>> = Vec::with_capacity(channels);
550
551 for ch_data in &frame.channels {
552 let samples = self.decode_channel_int(ch_data, frame_samples)?;
553 frame_channels.push(samples);
554 }
555
556 let mut all_samples: Vec<Vec<i32>> = vec![vec![]; channels];
558 if use_mid_side && frame_channels.len() == 2 {
559 let (left, right) = self.decode_mid_side(
560 &frame_channels[0],
561 &frame_channels[1],
562 header.version_minor >= 2,
563 );
564 all_samples[0] = left;
565 all_samples[1] = right;
566 } else {
567 for (ch_idx, samples) in frame_channels.into_iter().enumerate() {
568 if ch_idx < channels {
569 all_samples[ch_idx] = samples;
570 }
571 }
572 }
573
574 let max_len = all_samples.iter().map(|v| v.len()).max().unwrap_or(0);
576 let mut interleaved = Vec::with_capacity(max_len * channels);
577
578 for i in 0..max_len {
579 for ch in 0..channels {
580 let sample = all_samples[ch].get(i).copied().unwrap_or(0);
581 interleaved.push(i32_to_f32(sample));
582 }
583 }
584
585 Ok(interleaved)
586 }
587
588 fn decode_channel_int(
590 &self,
591 ch_data: &ChannelData,
592 frame_samples: usize,
593 ) -> FloResult<Vec<i32>> {
594 let has_coeffs = !ch_data.predictor_coeffs.is_empty();
595 let has_residuals = !ch_data.residuals.is_empty();
596 let shift_bits = ch_data.shift_bits;
597
598 let is_fixed_predictor = !has_coeffs && has_residuals && shift_bits >= 128;
600
601 if is_fixed_predictor {
602 let fixed_order = (shift_bits - 128) as usize;
603 let residuals =
604 rice::decode_i32(&ch_data.residuals, ch_data.rice_parameter, frame_samples);
605 return Ok(self.reconstruct_fixed(fixed_order, &residuals, frame_samples));
606 }
607
608 if has_coeffs {
609 let residuals = match ch_data.residual_encoding {
612 ResidualEncoding::Rice => {
613 rice::decode_i32(&ch_data.residuals, ch_data.rice_parameter, frame_samples)
614 }
615 ResidualEncoding::Raw | ResidualEncoding::Golomb => {
616 let mut res = Vec::with_capacity(frame_samples);
618 for chunk in ch_data.residuals.chunks(2) {
619 if chunk.len() == 2 {
620 res.push(i16::from_le_bytes([chunk[0], chunk[1]]) as i32);
621 }
622 }
623 while res.len() < frame_samples {
624 res.push(0);
625 }
626 res
627 }
628 };
629
630 let order = ch_data.predictor_coeffs.len();
631 let samples = self.reconstruct_lpc_int(
632 &ch_data.predictor_coeffs,
633 &residuals,
634 shift_bits,
635 order,
636 frame_samples,
637 );
638 return Ok(samples);
639 }
640
641 if has_residuals {
642 let mut samples = Vec::with_capacity(frame_samples);
644 for chunk in ch_data.residuals.chunks(2) {
645 if chunk.len() == 2 {
646 samples.push(i16::from_le_bytes([chunk[0], chunk[1]]) as i32);
647 }
648 }
649 while samples.len() < frame_samples {
650 samples.push(0);
651 }
652 return Ok(samples);
653 }
654
655 Ok(vec![0; frame_samples])
657 }
658
659 fn decode_mid_side(&self, mid: &[i32], side: &[i32], halved: bool) -> (Vec<i32>, Vec<i32>) {
661 if halved {
662 let left: Vec<i32> = mid
663 .iter()
664 .zip(side.iter())
665 .map(|(&m, &s)| m + ((s + (s & 1)) >> 1))
666 .collect();
667 let right: Vec<i32> = mid
668 .iter()
669 .zip(side.iter())
670 .map(|(&m, &s)| m - (s >> 1))
671 .collect();
672 (left, right)
673 } else {
674 let left: Vec<i32> = mid
675 .iter()
676 .zip(side.iter())
677 .map(|(&m, &s)| (m + s) / 2)
678 .collect();
679 let right: Vec<i32> = mid
680 .iter()
681 .zip(side.iter())
682 .map(|(&m, &s)| (m - s) / 2)
683 .collect();
684 (left, right)
685 }
686 }
687
688 fn reconstruct_lpc_int(
690 &self,
691 coeffs: &[i32],
692 residuals: &[i32],
693 shift: u8,
694 order: usize,
695 target_len: usize,
696 ) -> Vec<i32> {
697 let mut samples = Vec::with_capacity(target_len);
698
699 for i in 0..order.min(residuals.len()) {
701 samples.push(residuals[i]);
702 }
703
704 for i in order..target_len.min(residuals.len()) {
706 let mut prediction: i64 = 0;
707 for (j, &coeff) in coeffs.iter().enumerate() {
708 if i > j {
709 prediction += (coeff as i64) * (samples[i - j - 1] as i64);
710 }
711 }
712 prediction >>= shift;
713 samples.push((prediction as i32) + residuals[i]);
714 }
715
716 while samples.len() < target_len {
717 samples.push(0);
718 }
719
720 samples
721 }
722
723 fn reconstruct_fixed(&self, order: usize, residuals: &[i32], target_len: usize) -> Vec<i32> {
725 let mut samples = Vec::with_capacity(target_len);
726
727 if residuals.is_empty() {
728 return vec![0; target_len];
729 }
730
731 match order {
732 0 => samples.extend_from_slice(residuals),
733 1 => {
734 samples.push(residuals[0]);
735 for i in 1..residuals.len().min(target_len) {
736 samples.push(residuals[i].wrapping_add(samples[i - 1]));
737 }
738 }
739 2 => {
740 if !residuals.is_empty() {
741 samples.push(residuals[0]);
742 }
743 if residuals.len() > 1 {
744 samples.push(residuals[1].wrapping_add(samples[0]));
745 }
746 for i in 2..residuals.len().min(target_len) {
747 let pred = (2i64 * (samples[i - 1] as i64) - (samples[i - 2] as i64)) as i32;
748 samples.push(residuals[i].wrapping_add(pred));
749 }
750 }
751 3 => {
752 if !residuals.is_empty() {
753 samples.push(residuals[0]);
754 }
755 if residuals.len() > 1 {
756 samples.push(residuals[1].wrapping_add(samples[0]));
757 }
758 if residuals.len() > 2 {
759 let pred = (2i64 * (samples[1] as i64) - (samples[0] as i64)) as i32;
760 samples.push(residuals[2].wrapping_add(pred));
761 }
762 for i in 3..residuals.len().min(target_len) {
763 let pred = (3i64 * (samples[i - 1] as i64) - 3i64 * (samples[i - 2] as i64)
764 + (samples[i - 3] as i64)) as i32;
765 samples.push(residuals[i].wrapping_add(pred));
766 }
767 }
768 4 => {
769 if !residuals.is_empty() {
770 samples.push(residuals[0]);
771 }
772 if residuals.len() > 1 {
773 samples.push(residuals[1].wrapping_add(samples[0]));
774 }
775 if residuals.len() > 2 {
776 let pred = (2i64 * (samples[1] as i64) - (samples[0] as i64)) as i32;
777 samples.push(residuals[2].wrapping_add(pred));
778 }
779 if residuals.len() > 3 {
780 let pred = (3i64 * (samples[2] as i64) - 3i64 * (samples[1] as i64)
781 + (samples[0] as i64)) as i32;
782 samples.push(residuals[3].wrapping_add(pred));
783 }
784 for i in 4..residuals.len().min(target_len) {
785 let pred = (4i64 * (samples[i - 1] as i64) - 6i64 * (samples[i - 2] as i64)
786 + 4i64 * (samples[i - 3] as i64)
787 - (samples[i - 4] as i64)) as i32;
788 samples.push(residuals[i].wrapping_add(pred));
789 }
790 }
791 _ => samples.extend_from_slice(residuals),
792 }
793
794 while samples.len() < target_len {
795 samples.push(0);
796 }
797
798 samples
799 }
800
801 fn decode_with_standard_decoder(&self) -> FloResult<Vec<f32>> {
802 let reader = Reader::new();
803 let file = reader.read(&self.buffer)?;
804
805 let is_transform = file
806 .frames
807 .iter()
808 .any(|f| f.frame_type == (FrameType::Transform as u8));
809
810 if is_transform {
811 let mut decoder = TransformDecoder::new(file.header.sample_rate, file.header.channels);
812 let mut all_samples = Vec::new();
813 let mut frame_count = 0;
814
815 for frame in &file.frames {
816 if frame.channels.is_empty() {
817 continue;
818 }
819 let frame_data = &frame.channels[0].residuals;
820 if let Some(transform_frame) = deserialize_frame(frame_data) {
821 let samples = decoder.decode_frame(&transform_frame);
822 if frame_count > 0 {
823 all_samples.extend(samples);
824 }
825 frame_count += 1;
826 }
827 }
828 Ok(all_samples)
829 } else {
830 let decoder = LosslessDecoder::new();
831 decoder.decode_file(&file)
832 }
833 }
834}
835
836impl Default for StreamingDecoder {
837 fn default() -> Self {
838 Self::new()
839 }
840}