symphonia_bundle_mp3/layer3/mod.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
// Symphonia
// Copyright (c) 2019-2022 The Project Symphonia Developers.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::fmt;
use symphonia_core::audio::{AudioBuffer, Signal};
use symphonia_core::errors::{decode_error, Error, Result};
use symphonia_core::io::{BitReaderLtr, BufReader, ReadBitsLtr, ReadBytes};
mod bitstream;
mod codebooks;
mod common;
mod hybrid_synthesis;
mod requantize;
mod stereo;
use crate::{common::*, synthesis};
use common::BlockType;
use log::warn;
/// `BitResevoir` implements the bit resevoir mechanism for main_data. Since frames have a
/// deterministic length based on the bit-rate, low-complexity portions of the audio may not need
/// every byte allocated to the frame. The bit resevoir mechanism allows these unused portions of
/// frames to be used by future frames.
pub struct BitResevoir {
buf: Box<[u8]>,
len: usize,
consumed: usize,
}
impl BitResevoir {
pub fn new() -> Self {
BitResevoir { buf: vec![0u8; 2048].into_boxed_slice(), len: 0, consumed: 0 }
}
pub fn fill(&mut self, pkt_main_data: &[u8], main_data_begin: usize) -> Result<u32> {
let main_data_len = pkt_main_data.len();
// The value `main_data_begin` indicates the number of bytes from the previous frame(s) to
// reuse. It must always be less than or equal to maximum amount of bytes the resevoir can
// hold taking into account the additional data being added to the resevoir.
let main_data_end = main_data_begin + main_data_len;
if main_data_end > self.buf.len() {
return decode_error("mpa: invalid main_data length, will exceed resevoir buffer");
}
let unread = self.len - self.consumed;
// If the offset is less-than or equal to the amount of unread data in the resevoir, shift
// the re-used bytes to the beginning of the resevoir, then copy the main data of the
// current packet into the resevoir.
let underflow = if main_data_begin <= unread {
// Shift all the re-used bytes as indicated by main_data_begin to the front of the
// resevoir.
self.buf.copy_within(self.len - main_data_begin..self.len, 0);
// Copy the new main data from the packet buffer after the re-used bytes.
self.buf[main_data_begin..main_data_end].copy_from_slice(pkt_main_data);
self.len = main_data_end;
0
}
else {
// Shift all the unread bytes to the front of the resevoir. Since this is an underflow
// condition, all unread bytes will be unconditionally reused.
self.buf.copy_within(self.len - unread..self.len, 0);
// If the offset is greater than the amount of data in the resevoir, then the stream is
// malformed. This can occur if the decoder is starting in the middle of a stream. This
// is particularly common with online radio streams. In this case, copy the main data
// of the current packet into the resevoir, then return the number of bytes that are
// missing.
self.buf[unread..unread + main_data_len].copy_from_slice(pkt_main_data);
self.len = unread + main_data_len;
// The number of bytes that will be missing.
let underflow = (main_data_begin - unread) as u32;
warn!("mpa: invalid main_data_begin, underflow by {} bytes", underflow);
underflow
};
self.consumed = 0;
Ok(underflow)
}
pub fn consume(&mut self, len: usize) {
self.consumed = self.len.min(self.consumed + len);
}
pub fn bytes_ref(&self) -> &[u8] {
&self.buf[self.consumed..self.len]
}
pub fn clear(&mut self) {
self.len = 0;
self.consumed = 0;
}
}
/// `FrameData` contains the side_info and main_data portions of a MPEG audio frame.
#[derive(Default, Debug)]
struct FrameData {
/// The byte offset into the bit resevoir indicating the location of the first bit of main_data.
/// If 0, main_data begins after the side_info of this frame.
main_data_begin: u16,
/// Scale factor selector information, per channel. Each channel has 4 groups of bands that may
/// be scaled in each granule. Scale factors may optionally be used by both granules to save
/// bits. Bands that share scale factors for both granules are indicated by a true. Otherwise,
/// each granule must store its own set of scale factors.
///
/// Mapping of array indicies to bands [0..6, 6..11, 11..16, 16..21].
scfsi: [[bool; 4]; 2],
/// The granules.
granules: [Granule; 2],
}
impl FrameData {
/// Get a mutable slice to the granule(s) in side_info. For MPEG1, a slice of 2 granules are
/// returned. For MPEG2/2.5, a single granule slice is returned.
#[inline(always)]
fn granules_mut(&mut self, version: MpegVersion) -> &mut [Granule] {
match version {
MpegVersion::Mpeg1 => &mut self.granules[..2],
_ => &mut self.granules[..1],
}
}
}
#[derive(Default, Debug)]
struct Granule {
/// Channels in the granule.
channels: [GranuleChannel; 2],
}
struct GranuleChannel {
/// Total number of bits used for scale factors (part2) and Huffman encoded data (part3).
part2_3_length: u16,
/// HALF the number of samples in the big_values partition (sum of all samples in
/// `region[0..3]`).
big_values: u16,
/// Logarithmic quantization step size.
global_gain: u8,
/// Depending on the MPEG version, `scalefac_compress` determines how many bits are allocated
/// per scale factor.
///
/// - For MPEG1 bitstreams, `scalefac_compress` is a 4-bit index into
/// `SCALE_FACTOR_SLEN[0..16]` to obtain a number of bits per scale factor pair.
///
/// - For MPEG2/2.5 bitstreams, `scalefac_compress` is a 9-bit value that decodes into
/// `slen[0..3]` (referred to as slen1-4 in the standard) for the number of bits per scale
/// factor, and depending on which range the value falls into, for which bands.
scalefac_compress: u16,
/// Indicates the block type (type of window) for the channel in the granule.
block_type: BlockType,
/// Gain factors for region[0..3] in big_values. Each gain factor has a maximum value of 7
/// (3 bits).
subblock_gain: [u8; 3],
/// The Huffman table to use for decoding `region[0..3]` of big_values.
table_select: [u8; 3],
/// The index of the first sample in region1 of big_values.
region1_start: usize,
/// The index of the first sample in region2 of big_values.
region2_start: usize,
/// Indicates if the pre-emphasis amount for each scale factor band should be added on to each
/// scale factor before requantization.
preflag: bool,
/// A 0.5x (false) or 1x (true) multiplier for scale factors.
scalefac_scale: bool,
/// Use Huffman Quads table A (0) or B (1), for decoding the count1 partition.
count1table_select: u8,
/// Long (scalefac_l) and short (scalefac_s) window scale factor bands. Must be interpreted
/// based on the block type of the granule.
///
/// For `block_type == BlockType::Short { is_mixed: false }`:
/// - `scalefac_s[0..36]` -> `scalefacs[0..36]`
///
/// For `block_type == BlockType::Short { is_mixed: true }`:
/// - `scalefac_l[0..8]` -> `scalefacs[0..8]`
/// - `scalefac_s[0..27]` -> `scalefacs[8..35]`
///
/// For `block_type != BlockType::Short { .. }`:
/// - `scalefac_l[0..21]` -> `scalefacs[0..21]`
///
/// Note: The standard doesn't explicitly call it out, but for Short blocks, there are three
/// additional scale factors, `scalefacs[36..39]`, that are always 0 and are not
/// transmitted in the bitstream.
///
/// For MPEG1, and MPEG2 without intensity stereo coding, a scale factor will not exceed 4 bits
/// in length (maximum value 15). For MPEG2 with intensity stereo, a scale factor will not
/// exceed 5 bits (maximum value 31) in length.
scalefacs: [u8; 39],
/// The starting sample index of the rzero partition, or the count of big_values and count1
/// samples.
rzero: usize,
}
impl Default for GranuleChannel {
fn default() -> Self {
GranuleChannel {
part2_3_length: 0,
big_values: 0,
global_gain: 0,
scalefac_compress: 0,
block_type: BlockType::Long,
subblock_gain: [0; 3],
table_select: [0; 3],
region1_start: 0,
region2_start: 0,
preflag: false,
scalefac_scale: false,
count1table_select: 0,
scalefacs: [0; 39],
rzero: 0,
}
}
}
impl fmt::Debug for GranuleChannel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "GranuleChannel {{")?;
writeln!(f, "\tpart2_3_length={}", self.part2_3_length)?;
writeln!(f, "\tbig_values={}", self.big_values)?;
writeln!(f, "\tglobal_gain={}", self.global_gain)?;
writeln!(f, "\tscalefac_compress={}", self.scalefac_compress)?;
writeln!(f, "\tblock_type={:?}", self.block_type)?;
writeln!(f, "\tsubblock_gain={:?}", self.subblock_gain)?;
writeln!(f, "\ttable_select={:?}", self.table_select)?;
writeln!(f, "\tregion1_start={}", self.region1_start)?;
writeln!(f, "\tregion2_start={}", self.region2_start)?;
writeln!(f, "\tpreflag={}", self.preflag)?;
writeln!(f, "\tscalefac_scale={}", self.scalefac_scale)?;
writeln!(f, "\tcount1table_select={}", self.count1table_select)?;
write!(f, "\tscalefacs=[ ")?;
for sf in &self.scalefacs[..] {
write!(f, "{}, ", sf)?;
}
writeln!(f, "]")?;
writeln!(f, "\trzero={}", self.rzero)?;
writeln!(f, "}}")
}
}
pub struct Layer3 {
pub samples: [[[f32; 576]; 2]; 2],
pub overlap: [[[f32; 18]; 32]; 2],
pub synthesis: [synthesis::SynthesisState; 2],
pub resevoir: BitResevoir,
}
impl Layer3 {
pub fn new() -> Self {
Self {
samples: [[[0f32; 576]; 2]; 2],
overlap: [[[0f32; 18]; 32]; 2],
synthesis: Default::default(),
resevoir: BitResevoir::new(),
}
}
/// Reads the main_data portion of a MPEG audio frame from a `BitStream` into `FrameData`.
fn read_main_data(
&mut self,
header: &FrameHeader,
underflow_bits: u32,
frame_data: &mut FrameData,
) -> Result<usize> {
let main_data = self.resevoir.bytes_ref();
let mut part2_3_begin = 0;
let mut part2_3_skipped = 0;
for gr in 0..header.n_granules() {
// If the resevoir underflowed (i.e., main_data_begin references bits not present in the
// resevoir) then skip the granule(s) the missing bits would belong to.
if part2_3_skipped < underflow_bits {
// Zero the samples in the granule channel(s) and sum the part2/3 bits that were
// skipped.
for ch in 0..header.n_channels() {
requantize::zero(&mut self.samples[gr][ch]);
part2_3_skipped +=
u32::from(frame_data.granules[gr].channels[ch].part2_3_length);
}
// Adjust the start position of the next granule in the buffer of main data that is
// available.
if part2_3_skipped > underflow_bits {
part2_3_begin = (part2_3_skipped - underflow_bits) as usize;
}
// Continue at the next granule.
continue;
}
for ch in 0..header.n_channels() {
let byte_index = part2_3_begin >> 3;
// Create a bit reader at the expected starting bit position.
let mut bs = if byte_index < main_data.len() {
let mut bs = BitReaderLtr::new(&main_data[byte_index..]);
let bit_index = part2_3_begin & 0x7;
if bit_index > 0 {
bs.ignore_bits(bit_index as u32)?;
}
bs
}
else {
return decode_error("mpa: invalid main_data offset");
};
// Read the scale factors (part2) and get the number of bits read.
let part2_len = if header.is_mpeg1() {
bitstream::read_scale_factors_mpeg1(&mut bs, gr, ch, frame_data)
}
else {
bitstream::read_scale_factors_mpeg2(
&mut bs,
ch > 0 && header.is_intensity_stereo(),
&mut frame_data.granules[gr].channels[ch],
)
}?;
let part2_3_length = u32::from(frame_data.granules[gr].channels[ch].part2_3_length);
// The part2 length must be less than or equal to the part2_3_length.
if part2_len > part2_3_length {
return decode_error("mpa: part2_3_length is not valid");
}
// The Huffman code length (part3).
let part3_len = part2_3_length - part2_len;
// Decode the Huffman coded spectral samples and get the starting index of the rzero
// partition.
let huffman_result = requantize::read_huffman_samples(
&mut bs,
&frame_data.granules[gr].channels[ch],
part3_len,
&mut self.samples[gr][ch],
);
// Huffman decoding errors are returned as an IO error by the bit reader. IO errors
// are unrecoverable, which is not the case for huffman decoding errors. Convert the
// IO error to a decode error.
frame_data.granules[gr].channels[ch].rzero = match huffman_result {
Ok(rzero) => rzero,
Err(Error::IoError(e)) if e.kind() == std::io::ErrorKind::Other => {
return decode_error("mpa: huffman decode overrun");
}
Err(err) => return Err(err),
};
part2_3_begin += part2_3_length as usize;
}
}
Ok((part2_3_begin + 7) >> 3)
}
}
impl Layer for Layer3 {
fn decode(
&mut self,
reader: &mut BufReader<'_>,
header: &FrameHeader,
out: &mut AudioBuffer<f32>,
) -> Result<()> {
// Initialize an empty FrameData to store the side_info and main_data portions of the
// frame.
let mut frame_data: FrameData = Default::default();
let _crc = if header.has_crc { Some(reader.read_be_u16()?) } else { None };
let buf = reader.read_buf_bytes_available_ref();
let mut bs = BitReaderLtr::new(buf);
// Read side_info into the frame data.
// TODO: Use a MonitorStream to compute the CRC.
let side_info_len = match bitstream::read_side_info(&mut bs, header, &mut frame_data) {
Ok(len) => len,
Err(e) => {
// A failure in reading this packet will cause a discontinuity in the codec
// bitstream. Therefore, clear the bit reservoir since it will not be valid for the
// next packet.
self.resevoir.clear();
return Err(e);
}
};
// Buffer main data into the bit resevoir.
let underflow =
self.resevoir.fill(&buf[side_info_len..], frame_data.main_data_begin as usize)?;
// Read the main data (scale factors and spectral samples).
match self.read_main_data(header, 8 * underflow, &mut frame_data) {
Ok(len) => {
// Consume the bytes of main data read from the resevoir.
self.resevoir.consume(len);
}
Err(e) => {
// The bit reservoir was likely filled with invalid data. Clear it for the next
// packet.
self.resevoir.clear();
return Err(e);
}
}
for gr in 0..header.n_granules() {
let granule = &mut frame_data.granules[gr];
// Requantize all non-zero (big_values and count1 partition) spectral samples.
requantize::requantize(header, &granule.channels[0], &mut self.samples[gr][0]);
// If there is a second channel...
if header.channel_mode != ChannelMode::Mono {
// Requantize all non-zero spectral samples in the second channel.
requantize::requantize(header, &granule.channels[1], &mut self.samples[gr][1]);
// Apply joint stereo processing if it is used.
stereo::stereo(header, granule, &mut self.samples[gr])?;
}
// Each granule will yield 576 samples. After reserving frames, all steps must be
// infalliable.
out.render_reserved(Some(576));
// The next steps are independant of channel count.
for ch in 0..header.n_channels() {
// Reorder the spectral samples in short blocks into sub-band order.
hybrid_synthesis::reorder(
header,
&mut granule.channels[ch],
&mut self.samples[gr][ch],
);
// Apply the anti-aliasing filter to all block types other than short.
hybrid_synthesis::antialias(&mut granule.channels[ch], &mut self.samples[gr][ch]);
// Perform hybrid-synthesis (IMDCT and windowing). After this step, rzero is invalid
// due to the overlap-add operation.
hybrid_synthesis::hybrid_synthesis(
&granule.channels[ch],
&mut self.overlap[ch],
&mut self.samples[gr][ch],
);
// Invert every second sample in every second sub-band to negate the frequency
// inversion of the polyphase filterbank.
hybrid_synthesis::frequency_inversion(&mut self.samples[gr][ch]);
// Perform polyphase synthesis and generate PCM samples.
let out_ch_samples = out.chan_mut(ch);
synthesis::synthesis(
&mut self.synthesis[ch],
18,
&self.samples[gr][ch],
&mut out_ch_samples[(gr * 576)..((gr + 1) * 576)],
);
}
}
Ok(())
}
}