symphonia_bundle_mp3/
decoder.rs1use symphonia_core::audio::{AsAudioBufferRef, AudioBuffer, AudioBufferRef, Signal};
9use symphonia_core::codecs::{CodecDescriptor, CodecParameters, CodecType};
10use symphonia_core::codecs::{Decoder, DecoderOptions, FinalizeResult};
11use symphonia_core::errors::{decode_error, unsupported_error, Result};
12use symphonia_core::formats::Packet;
13use symphonia_core::io::FiniteStream;
14use symphonia_core::support_codec;
15
16#[cfg(feature = "mp1")]
17use symphonia_core::codecs::CODEC_TYPE_MP1;
18#[cfg(feature = "mp2")]
19use symphonia_core::codecs::CODEC_TYPE_MP2;
20#[cfg(feature = "mp3")]
21use symphonia_core::codecs::CODEC_TYPE_MP3;
22
23use super::{common::*, header};
24
25#[cfg(feature = "mp1")]
26use crate::layer1;
27#[cfg(feature = "mp2")]
28use crate::layer2;
29#[cfg(feature = "mp3")]
30use crate::layer3;
31
32enum State {
33 #[cfg(feature = "mp1")]
34 Layer1(layer1::Layer1),
35 #[cfg(feature = "mp2")]
36 Layer2(layer2::Layer2),
37 #[cfg(feature = "mp3")]
38 Layer3(Box<layer3::Layer3>),
39}
40
41impl State {
42 fn new(codec: CodecType) -> Self {
43 match codec {
44 #[cfg(feature = "mp1")]
45 CODEC_TYPE_MP1 => State::Layer1(layer1::Layer1::new()),
46 #[cfg(feature = "mp2")]
47 CODEC_TYPE_MP2 => State::Layer2(layer2::Layer2::new()),
48 #[cfg(feature = "mp3")]
49 CODEC_TYPE_MP3 => State::Layer3(Box::new(layer3::Layer3::new())),
50 _ => unreachable!(),
51 }
52 }
53}
54
55pub struct MpaDecoder {
57 params: CodecParameters,
58 state: State,
59 buf: AudioBuffer<f32>,
60}
61
62impl MpaDecoder {
63 fn decode_inner(&mut self, packet: &Packet) -> Result<()> {
64 let mut reader = packet.as_buf_reader();
65
66 let header = header::read_frame_header(&mut reader)?;
67
68 if header.frame_size != reader.bytes_available() as usize {
70 return decode_error("mpa: invalid packet length");
71 }
72
73 if self.buf.is_unused() {
75 self.buf = AudioBuffer::new(1152, header.spec());
76 }
77 else {
78 if self.buf.spec() != &header.spec() {
83 return decode_error("mpa: invalid audio buffer signal spec for packet");
84 }
85 }
86
87 self.buf.clear();
89
90 match &mut self.state {
92 #[cfg(feature = "mp1")]
93 State::Layer1(layer) if header.layer == MpegLayer::Layer1 => {
94 layer.decode(&mut reader, &header, &mut self.buf)?;
95 }
96 #[cfg(feature = "mp2")]
97 State::Layer2(layer) if header.layer == MpegLayer::Layer2 => {
98 layer.decode(&mut reader, &header, &mut self.buf)?;
99 }
100 #[cfg(feature = "mp3")]
101 State::Layer3(layer) if header.layer == MpegLayer::Layer3 => {
102 layer.decode(&mut reader, &header, &mut self.buf)?;
103 }
104 _ => return decode_error("mpa: invalid mpeg audio layer"),
105 }
106
107 self.buf.trim(packet.trim_start() as usize, packet.trim_end() as usize);
108
109 Ok(())
110 }
111}
112
113impl Decoder for MpaDecoder {
114 fn try_new(params: &CodecParameters, _: &DecoderOptions) -> Result<Self> {
115 match params.codec {
117 #[cfg(feature = "mp1")]
118 CODEC_TYPE_MP1 => (),
119 #[cfg(feature = "mp2")]
120 CODEC_TYPE_MP2 => (),
121 #[cfg(feature = "mp3")]
122 CODEC_TYPE_MP3 => (),
123 _ => return unsupported_error("mpa: invalid codec type"),
124 }
125
126 let state = State::new(params.codec);
128
129 Ok(MpaDecoder { params: params.clone(), state, buf: AudioBuffer::unused() })
130 }
131
132 fn supported_codecs() -> &'static [CodecDescriptor] {
133 &[
134 #[cfg(feature = "mp1")]
135 support_codec!(CODEC_TYPE_MP1, "mp1", "MPEG Audio Layer 1"),
136 #[cfg(feature = "mp2")]
137 support_codec!(CODEC_TYPE_MP2, "mp2", "MPEG Audio Layer 2"),
138 #[cfg(feature = "mp3")]
139 support_codec!(CODEC_TYPE_MP3, "mp3", "MPEG Audio Layer 3"),
140 ]
141 }
142
143 fn codec_params(&self) -> &CodecParameters {
144 &self.params
145 }
146
147 fn reset(&mut self) {
148 self.state = State::new(self.params.codec);
150 }
151
152 fn decode(&mut self, packet: &Packet) -> Result<AudioBufferRef<'_>> {
153 if let Err(e) = self.decode_inner(packet) {
154 self.buf.clear();
155 Err(e)
156 }
157 else {
158 Ok(self.buf.as_audio_buffer_ref())
159 }
160 }
161
162 fn finalize(&mut self) -> FinalizeResult {
163 Default::default()
164 }
165
166 fn last_decoded(&self) -> AudioBufferRef<'_> {
167 self.buf.as_audio_buffer_ref()
168 }
169}