1pub use error::Error;
12pub use minimp3_sys as ffi;
13
14use slice_ring_buffer::SliceRingBuffer;
15use std::{io, marker::Send, mem};
16
17mod error;
18
19pub const MAX_SAMPLES_PER_FRAME: usize = ffi::MINIMP3_MAX_SAMPLES_PER_FRAME as usize;
21
22const BUFFER_SIZE: usize = MAX_SAMPLES_PER_FRAME * 15;
23const REFILL_TRIGGER: usize = MAX_SAMPLES_PER_FRAME * 8;
24
25pub struct Decoder<R> {
29 reader: R,
30 buffer: SliceRingBuffer<u8>,
31 buffer_refill: Box<[u8; MAX_SAMPLES_PER_FRAME * 5]>,
32 decoder: Box<ffi::mp3dec_t>,
33}
34
35unsafe impl<R: Send> Send for Decoder<R> {}
40
41#[derive(Debug, Clone)]
43pub struct Frame {
44 pub data: Vec<i16>,
46 pub sample_rate: i32,
48 pub channels: usize,
50 pub layer: usize,
52 pub bitrate: i32,
54}
55
56impl<R> Decoder<R> {
57 pub fn new(reader: R) -> Self {
59 let mut minidec = unsafe { Box::new(mem::zeroed()) };
60 unsafe { ffi::mp3dec_init(&mut *minidec) }
61
62 Self {
63 reader,
64 buffer: SliceRingBuffer::with_capacity(BUFFER_SIZE),
65 buffer_refill: Box::new([0; MAX_SAMPLES_PER_FRAME * 5]),
66 decoder: minidec,
67 }
68 }
69
70 pub fn reader(&self) -> &R {
72 &self.reader
73 }
74
75 pub fn reader_mut(&mut self) -> &mut R {
78 &mut self.reader
79 }
80
81 pub fn into_inner(self) -> R {
83 self.reader
84 }
85
86 fn decode_frame(&mut self) -> Result<Frame, Error> {
87 let mut frame_info = unsafe { mem::zeroed() };
88 let mut pcm = Vec::with_capacity(MAX_SAMPLES_PER_FRAME);
89 let samples: usize = unsafe {
90 ffi::mp3dec_decode_frame(
91 &mut *self.decoder,
92 self.buffer.as_ptr(),
93 self.buffer.len() as _,
94 pcm.as_mut_ptr(),
95 &mut frame_info,
96 ) as _
97 };
98
99 if samples > 0 {
100 unsafe {
101 pcm.set_len(samples * frame_info.channels as usize);
102 }
103 }
104
105 let frame = Frame {
106 data: pcm,
107 sample_rate: frame_info.hz,
108 channels: frame_info.channels as usize,
109 layer: frame_info.layer as usize,
110 bitrate: frame_info.bitrate_kbps,
111 };
112
113 let current_len = self.buffer.len();
114 self.buffer
115 .truncate_front(current_len - frame_info.frame_bytes as usize);
116
117 if samples == 0 {
118 if frame_info.frame_bytes > 0 {
119 Err(Error::SkippedData)
120 } else {
121 Err(Error::InsufficientData)
122 }
123 } else {
124 Ok(frame)
125 }
126 }
127}
128
129#[cfg(feature = "async_tokio")]
130impl<R: tokio::io::AsyncRead + std::marker::Unpin> Decoder<R> {
131 pub async fn next_frame_future(&mut self) -> Result<Frame, Error> {
134 loop {
135 let bytes_read = if self.buffer.len() < REFILL_TRIGGER {
137 Some(self.refill_future().await?)
138 } else {
139 None
140 };
141
142 match self.decode_frame() {
143 Ok(frame) => return Ok(frame),
144 Err(Error::InsufficientData) | Err(Error::SkippedData) => {
147 if let Some(0) = bytes_read {
149 return Err(Error::Eof);
150 }
151 }
152 Err(e) => return Err(e),
153 }
154 }
155 }
156
157 async fn refill_future(&mut self) -> Result<usize, io::Error> {
158 use tokio::io::AsyncReadExt;
159
160 let read_bytes = self.reader.read(&mut self.buffer_refill[..]).await?;
161 self.buffer.extend(self.buffer_refill[..read_bytes].iter());
162
163 Ok(read_bytes)
164 }
165}
166
167impl<R: io::Read> Decoder<R> {
171 pub fn next_frame(&mut self) -> Result<Frame, Error> {
174 loop {
175 let bytes_read = if self.buffer.len() < REFILL_TRIGGER {
177 Some(self.refill()?)
178 } else {
179 None
180 };
181
182 match self.decode_frame() {
183 Ok(frame) => return Ok(frame),
184 Err(Error::InsufficientData) | Err(Error::SkippedData) => {
187 if let Some(0) = bytes_read {
189 return Err(Error::Eof);
190 }
191 }
192 Err(e) => return Err(e),
193 }
194 }
195 }
196
197 fn refill(&mut self) -> Result<usize, io::Error> {
198 let read_bytes = self.reader.read(&mut self.buffer_refill[..])?;
199 self.buffer.extend(self.buffer_refill[..read_bytes].iter());
200
201 Ok(read_bytes)
202 }
203}