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}