1use symphonia_core::errors::{decode_error, unsupported_error, Result};
9use symphonia_core::io::ReadBytes;
10
11use crate::common::*;
12
13pub const MPEG_HEADER_LEN: usize = 4;
15
16pub const MAX_MPEG_FRAME_SIZE: u64 = 2881;
18
19const BIT_RATES_MPEG1_L1: [u32; 15] = [
21 0, 32_000, 64_000, 96_000, 128_000, 160_000, 192_000, 224_000, 256_000, 288_000, 320_000,
22 352_000, 384_000, 416_000, 448_000,
23];
24
25const BIT_RATES_MPEG1_L2: [u32; 15] = [
27 0, 32_000, 48_000, 56_000, 64_000, 80_000, 96_000, 112_000, 128_000, 160_000, 192_000, 224_000,
28 256_000, 320_000, 384_000,
29];
30
31const BIT_RATES_MPEG1_L3: [u32; 15] = [
33 0, 32_000, 40_000, 48_000, 56_000, 64_000, 80_000, 96_000, 112_000, 128_000, 160_000, 192_000,
34 224_000, 256_000, 320_000,
35];
36
37const BIT_RATES_MPEG2_L1: [u32; 15] = [
39 0, 32_000, 48_000, 56_000, 64_000, 80_000, 96_000, 112_000, 128_000, 144_000, 160_000, 176_000,
40 192_000, 224_000, 256_000,
41];
42
43const BIT_RATES_MPEG2_L23: [u32; 15] = [
45 0, 8_000, 16_000, 24_000, 32_000, 40_000, 48_000, 56_000, 64_000, 80_000, 96_000, 112_000,
46 128_000, 144_000, 160_000,
47];
48
49#[inline]
51pub fn check_header(header: u32) -> bool {
52 if (header >> 19) & 0x3 == 0x1 {
54 return false;
55 }
56 if (header >> 17) & 0x3 == 0x0 {
58 return false;
59 }
60 if (header >> 12) & 0xf == 0xf {
62 return false;
63 }
64 if (header >> 10) & 0x3 == 0x3 {
66 return false;
67 }
68 true
69}
70
71#[inline(always)]
73pub fn is_frame_header_word_synced(sync: u32) -> bool {
74 (sync & 0xffe0_0000) == 0xffe0_0000
75}
76
77pub fn sync_frame<B: ReadBytes>(reader: &mut B) -> Result<u32> {
80 let mut sync = 0u32;
81
82 loop {
83 while !is_frame_header_word_synced(sync) {
87 sync = (sync << 8) | u32::from(reader.read_u8()?);
88 }
89
90 if check_header(sync) {
93 break;
94 }
95
96 sync = (sync << 8) | u32::from(reader.read_u8()?);
97 }
98
99 Ok(sync)
100}
101
102pub fn parse_frame_header(header: u32) -> Result<FrameHeader> {
103 let version = match (header & 0x18_0000) >> 19 {
112 0b00 => MpegVersion::Mpeg2p5,
113 0b10 => MpegVersion::Mpeg2,
114 0b11 => MpegVersion::Mpeg1,
115 _ => return decode_error("mpa: invalid MPEG version"),
116 };
117
118 let layer = match (header & 0x6_0000) >> 17 {
119 0b01 => MpegLayer::Layer3,
120 0b10 => MpegLayer::Layer2,
121 0b11 => MpegLayer::Layer1,
122 _ => return decode_error("mpa: invalid MPEG layer"),
123 };
124
125 let bitrate = match ((header & 0xf000) >> 12, version, layer) {
126 (0b0000, _, _) => return unsupported_error("mpa: free bit-rate is not supported"),
129 (0b1111, _, _) => return decode_error("mpa: invalid bit-rate"),
131 (i, MpegVersion::Mpeg1, MpegLayer::Layer1) => BIT_RATES_MPEG1_L1[i as usize],
133 (i, MpegVersion::Mpeg1, MpegLayer::Layer2) => BIT_RATES_MPEG1_L2[i as usize],
134 (i, MpegVersion::Mpeg1, MpegLayer::Layer3) => BIT_RATES_MPEG1_L3[i as usize],
135 (i, _, MpegLayer::Layer1) => BIT_RATES_MPEG2_L1[i as usize],
137 (i, _, _) => BIT_RATES_MPEG2_L23[i as usize],
138 };
139
140 let (sample_rate, sample_rate_idx) = match ((header & 0xc00) >> 10, version) {
141 (0b00, MpegVersion::Mpeg1) => (44_100, 0),
142 (0b01, MpegVersion::Mpeg1) => (48_000, 1),
143 (0b10, MpegVersion::Mpeg1) => (32_000, 2),
144 (0b00, MpegVersion::Mpeg2) => (22_050, 3),
145 (0b01, MpegVersion::Mpeg2) => (24_000, 4),
146 (0b10, MpegVersion::Mpeg2) => (16_000, 5),
147 (0b00, MpegVersion::Mpeg2p5) => (11_025, 6),
148 (0b01, MpegVersion::Mpeg2p5) => (12_000, 7),
149 (0b10, MpegVersion::Mpeg2p5) => (8_000, 8),
150 _ => return decode_error("mpa: invalid sample rate"),
151 };
152
153 let channel_mode = match ((header & 0xc0) >> 6, layer) {
154 (0b00, _) => ChannelMode::Stereo,
156 (0b10, _) => ChannelMode::DualMono,
158 (0b11, _) => ChannelMode::Mono,
160 (0b01, MpegLayer::Layer3) => ChannelMode::JointStereo(Mode::Layer3 {
163 mid_side: header & 0x20 != 0x0,
164 intensity: header & 0x10 != 0x0,
165 }),
166 (0b01, _) => {
169 ChannelMode::JointStereo(Mode::Intensity { bound: (1 + ((header & 0x30) >> 4)) << 2 })
170 }
171 _ => unreachable!(),
172 };
173
174 if layer == MpegLayer::Layer2 {
177 if channel_mode == ChannelMode::Mono {
178 if bitrate == 224_000 || bitrate == 256_000 || bitrate == 320_000 || bitrate == 384_000
179 {
180 return decode_error("mpa: invalid Layer 2 bitrate for mono channel mode");
181 }
182 }
183 else if bitrate == 32_000 || bitrate == 48_000 || bitrate == 56_000 || bitrate == 80_000 {
184 return decode_error("mpa: invalid Layer 2 bitrate for non-mono channel mode");
185 }
186 }
187
188 let emphasis = match header & 0x3 {
189 0b01 => Emphasis::Fifty15,
190 0b11 => Emphasis::CcitJ17,
191 _ => Emphasis::None,
192 };
193
194 let is_copyrighted = header & 0x8 != 0x0;
195 let is_original = header & 0x4 != 0x0;
196 let has_padding = header & 0x200 != 0;
197
198 let has_crc = header & 0x1_0000 == 0;
199
200 let factor = match layer {
202 MpegLayer::Layer1 => 12,
203 MpegLayer::Layer2 => 144,
204 MpegLayer::Layer3 if version == MpegVersion::Mpeg1 => 144,
205 MpegLayer::Layer3 => 72,
206 };
207
208 let slot_size = match layer {
211 MpegLayer::Layer1 => 4,
212 _ => 1,
213 };
214
215 let frame_size_slots = (factor * bitrate / sample_rate) as usize + usize::from(has_padding);
217
218 let frame_size = (frame_size_slots * slot_size) - 4;
220
221 Ok(FrameHeader {
222 version,
223 layer,
224 bitrate,
225 sample_rate,
226 sample_rate_idx,
227 channel_mode,
228 emphasis,
229 is_copyrighted,
230 is_original,
231 has_padding,
232 has_crc,
233 frame_size,
234 })
235}
236
237#[inline]
240#[allow(dead_code)]
241pub fn read_frame_header<B: ReadBytes>(reader: &mut B) -> Result<FrameHeader> {
242 parse_frame_header(sync_frame(reader)?)
244}
245
246#[inline]
249pub fn read_frame_header_word_no_sync<B: ReadBytes>(reader: &mut B) -> Result<u32> {
250 Ok(reader.read_be_u32()?)
251}