sea_codec/
decoder.rs

1use alloc::vec::Vec;
2
3use crate::{
4    codec::{
5        common::SeaError,
6        file::{SeaFile, SeaFileHeader},
7    },
8    cursor::Cursor,
9};
10
11pub struct SeaDecoder<'inp> {
12    cursor: Cursor<'inp>,
13    file: SeaFile,
14    frames_read: usize,
15}
16
17impl<'inp> SeaDecoder<'inp> {
18    #[cfg(feature = "std")]
19    pub fn from_reader<R: std::io::Read + 'inp>(reader: R) -> Result<Self, SeaError> {
20        let mut cursor = Cursor::from_reader(reader);
21
22        let file = SeaFile::from_reader(&mut cursor)?;
23
24        Ok(Self {
25            cursor,
26            file,
27            frames_read: 0,
28        })
29    }
30
31    pub fn from_slice(data: &'inp [u8]) -> Result<Self, SeaError> {
32        let mut cursor = Cursor::from_slice(data);
33
34        let file = SeaFile::from_reader(&mut cursor)?;
35
36        Ok(Self {
37            cursor,
38            file,
39            frames_read: 0,
40        })
41    }
42
43    pub fn decode_frame(&mut self, result: &mut Vec<i16>) -> Result<bool, SeaError> {
44        if self.file.header.total_frames != 0
45            && (self.file.header.total_frames as usize) <= self.frames_read
46        {
47            return Ok(false);
48        }
49
50        let remaining_frames = if self.file.header.total_frames > 0 {
51            Some(self.file.header.total_frames as usize - self.frames_read)
52        } else {
53            None
54        };
55
56        let samples_written =
57            self.file
58                .samples_from_reader(&mut self.cursor, remaining_frames, result)?;
59
60        if samples_written == 0 {
61            Ok(false)
62        } else {
63            self.frames_read += samples_written / self.file.header.channels as usize;
64            Ok(true)
65        }
66    }
67
68    pub fn get_header(&self) -> SeaFileHeader {
69        self.file.header.clone()
70    }
71}