symphonia-bundle-flac-0.5.2/.cargo_vcs_info.json0000644000000001630000000000100152210ustar { "git": { "sha1": "412f44daab39920beeb81d78b0e4271b263d33e9" }, "path_in_vcs": "symphonia-bundle-flac" }symphonia-bundle-flac-0.5.2/Cargo.toml0000644000000022610000000000100132200ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" rust-version = "1.53" name = "symphonia-bundle-flac" version = "0.5.2" authors = ["Philip Deljanov "] description = "Pure Rust FLAC demuxer and decoder (a part of project Symphonia)." homepage = "https://github.com/pdeljanov/Symphonia" readme = "README.md" keywords = [ "audio", "codec", "decoder", "flac", ] categories = [ "multimedia", "multimedia::audio", "multimedia::encoding", ] license = "MPL-2.0" repository = "https://github.com/pdeljanov/Symphonia" [dependencies.log] version = "0.4" [dependencies.symphonia-core] version = "0.5.2" [dependencies.symphonia-metadata] version = "0.5.2" [dependencies.symphonia-utils-xiph] version = "0.5.2" symphonia-bundle-flac-0.5.2/Cargo.toml.orig000064400000000000000000000013631046102023000167030ustar 00000000000000[package] name = "symphonia-bundle-flac" version = "0.5.2" description = "Pure Rust FLAC demuxer and decoder (a part of project Symphonia)." homepage = "https://github.com/pdeljanov/Symphonia" repository = "https://github.com/pdeljanov/Symphonia" authors = ["Philip Deljanov "] license = "MPL-2.0" readme = "README.md" categories = ["multimedia", "multimedia::audio", "multimedia::encoding"] keywords = ["audio", "codec", "decoder", "flac"] edition = "2018" rust-version = "1.53" [dependencies] log = "0.4" symphonia-core = { version = "0.5.2", path = "../symphonia-core" } symphonia-metadata = { version = "0.5.2", path = "../symphonia-metadata" } symphonia-utils-xiph = { version = "0.5.2", path = "../symphonia-utils-xiph" }symphonia-bundle-flac-0.5.2/README.md000064400000000000000000000021661046102023000152750ustar 00000000000000# Symphonia FLAC Codec [![Docs](https://docs.rs/symphonia-bundle-flac/badge.svg)](https://docs.rs/symphonia-bundle-flac) > Come for the fidelity, stay for the memory safety! FLAC decoder for Project Symphonia. **Note:** This crate is part of Symphonia. Please use the [`symphonia`](https://crates.io/crates/symphonia) crate instead of this one directly. ## License Symphonia is provided under the MPL v2.0 license. Please refer to the LICENSE file for more details. ## Acknowledgements * [The FLAC Reference Library](https://github.com/xiph/flac), for format specification and algorithm clarifications * [FFmpeg](https://github.com/FFmpeg/FFmpeg), for algorithm clarifications * [Claxon](https://github.com/ruuda/claxon), for inspiration on how to structure a decoder written in idiomatic Rust ## Contributing Symphonia is an open-source project and contributions are very welcome! If you would like to make a large contribution, please raise an issue ahead of time to make sure your efforts fit into the project goals, and that no duplication of efforts occurs. All contributors will be credited within the CONTRIBUTORS file. symphonia-bundle-flac-0.5.2/src/decoder.rs000064400000000000000000000673751046102023000165750ustar 00000000000000// 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::cmp; use std::num::Wrapping; use symphonia_core::audio::{AsAudioBufferRef, AudioBuffer, AudioBufferRef}; use symphonia_core::audio::{Signal, SignalSpec}; use symphonia_core::codecs::{ CodecDescriptor, CodecParameters, VerificationCheck, CODEC_TYPE_FLAC, }; use symphonia_core::codecs::{Decoder, DecoderOptions, FinalizeResult}; use symphonia_core::errors::{decode_error, unsupported_error, Result}; use symphonia_core::formats::Packet; use symphonia_core::io::{BitReaderLtr, BufReader, ReadBitsLtr}; use symphonia_core::support_codec; use symphonia_core::units::TimeBase; use symphonia_core::util::bits::sign_extend_leq32_to_i32; use symphonia_utils_xiph::flac::metadata::StreamInfo; use log::{debug, log_enabled, warn}; use super::frame::*; use super::validate::Validator; fn decorrelate_left_side(left: &[i32], side: &mut [i32]) { for (s, l) in side.iter_mut().zip(left) { *s = *l - *s; } } fn decorrelate_mid_side(mid: &mut [i32], side: &mut [i32]) { for (m, s) in mid.iter_mut().zip(side) { // Mid (M) is given as M = L/2 + R/2, while Side (S) is given as S = L - R. // // To calculate the individual channels, the following equations can be used: // - L = S/2 + M // - R = M - S/2 // // Ideally, this would work, but since samples are represented as integers, division yields // the floor of the divided value. Therefore, the channel restoration equations actually // yield: // - L = floor(S/2) + M // - R = M - floor(S/2) // // This will produce incorrect samples whenever the sample S is odd. For example: // - 2/2 = 1 // - 3/2 = 1 (should be 2 if rounded!) // // To get the proper rounding behaviour, the solution is to add one to the result if S is // odd: // - L = floor(S/2) + M + (S%2) = M + (S%2) + floor(S/2) // - R = M - floor(S/2) + (S%2) = M + (S%2) - floor(S/2) // // Further, to prevent loss of accuracy, instead of dividing S/2 and adding or subtracting // it from M, multiply M*2, then add or subtract S, and then divide the whole result by 2. // This gives one extra bit of precision for the intermediate computations. // // Conveniently, since M should be doubled, the LSB will always be 0. This allows S%2 to // be added simply by bitwise ORing S&1 to M<<1. // // Therefore the final equations yield: // - L = (2*M + (S%2) + S) / 2 // - R = (2*M + (S%2) - S) / 2 let mid = (*m << 1) | (*s & 1); let side = *s; *m = (mid + side) >> 1; *s = (mid - side) >> 1; } } fn decorrelate_right_side(right: &[i32], side: &mut [i32]) { for (s, r) in side.iter_mut().zip(right) { *s += *r; } } /// Free Lossless Audio Codec (FLAC) decoder. pub struct FlacDecoder { params: CodecParameters, is_validating: bool, validator: Validator, buf: AudioBuffer, } impl FlacDecoder { fn decode_inner(&mut self, packet: &Packet) -> Result<()> { let mut reader = packet.as_buf_reader(); // Synchronize to a frame and get the synchronization code. let sync = sync_frame(&mut reader)?; let header = read_frame_header(&mut reader, sync)?; // Use the bits per sample and sample rate as stated in the frame header, falling back to // the stream information if provided. If neither are available, return an error. let bits_per_sample = if let Some(bps) = header.bits_per_sample { bps } else if let Some(bps) = self.params.bits_per_sample { bps } else { return decode_error("flac: bits per sample not provided"); }; // trace!("frame: [{:?}] strategy={:?}, n_samples={}, bps={}, channels={:?}", // header.block_sequence, // header.blocking_strategy, // header.block_num_samples, // bits_per_sample, // &header.channel_assignment); // Reserve a writeable chunk in the buffer equal to the number of samples in the block. self.buf.clear(); self.buf.render_reserved(Some(header.block_num_samples as usize)); // Only Bitstream reading for subframes. { // Sub-frames don't have any byte-aligned content, so use a BitReader. let mut bs = BitReaderLtr::new(reader.read_buf_bytes_available_ref()); // Read each subframe based on the channel assignment into a planar buffer. match header.channel_assignment { ChannelAssignment::Independant(channels) => { for i in 0..channels as usize { read_subframe(&mut bs, bits_per_sample, self.buf.chan_mut(i))?; } } // For Left/Side, Mid/Side, and Right/Side channel configurations, the Side // (Difference) channel requires an extra bit per sample. ChannelAssignment::LeftSide => { let (left, side) = self.buf.chan_pair_mut(0, 1); read_subframe(&mut bs, bits_per_sample, left)?; read_subframe(&mut bs, bits_per_sample + 1, side)?; decorrelate_left_side(left, side); } ChannelAssignment::MidSide => { let (mid, side) = self.buf.chan_pair_mut(0, 1); read_subframe(&mut bs, bits_per_sample, mid)?; read_subframe(&mut bs, bits_per_sample + 1, side)?; decorrelate_mid_side(mid, side); } ChannelAssignment::RightSide => { let (side, right) = self.buf.chan_pair_mut(0, 1); read_subframe(&mut bs, bits_per_sample + 1, side)?; read_subframe(&mut bs, bits_per_sample, right)?; decorrelate_right_side(right, side); } } } // Feed the validator if validation is enabled. if self.is_validating { self.validator.update(&self.buf, bits_per_sample); } // The decoder uses a 32bit sample format as a common denominator, but that doesn't mean // the encoded audio samples are actually 32bit. Shift all samples in the output buffer // so that regardless the encoded bits/sample, the output is always 32bits/sample. if bits_per_sample < 32 { let shift = 32 - bits_per_sample; self.buf.transform(|sample| sample << shift); } Ok(()) } } impl Decoder for FlacDecoder { fn try_new(params: &CodecParameters, options: &DecoderOptions) -> Result { // This decoder only supports FLAC. if params.codec != CODEC_TYPE_FLAC { return unsupported_error("flac: invalid codec type"); } // Obtain the extra data. let extra_data = match params.extra_data.as_ref() { Some(buf) => buf, _ => return unsupported_error("flac: missing extra data"), }; // Read the stream information block. let info = StreamInfo::read(&mut BufReader::new(extra_data))?; // Clone the codec parameters so that the parameters can be supplemented and/or amended. let mut params = params.clone(); // Amend the provided codec parameters with information from the stream information block. params .with_sample_rate(info.sample_rate) .with_time_base(TimeBase::new(1, info.sample_rate)) .with_bits_per_sample(info.bits_per_sample) .with_max_frames_per_packet(u64::from(info.block_len_max)) .with_channels(info.channels); if let Some(md5) = info.md5 { params.with_verification_code(VerificationCheck::Md5(md5)); } if let Some(n_frames) = info.n_samples { params.with_n_frames(n_frames); } let spec = SignalSpec::new(info.sample_rate, info.channels); let buf = AudioBuffer::new(u64::from(info.block_len_max), spec); // TODO: Verify packet integrity if the demuxer is not. // if !params.packet_data_integrity { // return unsupported_error("flac: packet integrity is required"); // } Ok(FlacDecoder { params, is_validating: options.verify, validator: Default::default(), buf, }) } fn supported_codecs() -> &'static [CodecDescriptor] { &[support_codec!(CODEC_TYPE_FLAC, "flac", "Free Lossless Audio Codec")] } fn reset(&mut self) { // No state is stored between packets, therefore do nothing. } fn codec_params(&self) -> &CodecParameters { &self.params } fn decode(&mut self, packet: &Packet) -> Result> { if let Err(e) = self.decode_inner(packet) { self.buf.clear(); Err(e) } else { Ok(self.buf.as_audio_buffer_ref()) } } fn finalize(&mut self) -> FinalizeResult { let mut result: FinalizeResult = Default::default(); // If verifying... if self.is_validating { // Try to get the expected MD5 checksum and compare it against the decoded checksum. if let Some(VerificationCheck::Md5(expected)) = self.params.verification_check { let decoded = self.validator.md5(); // Only generate the expected and decoded MD5 checksum strings if logging is // enabled at the debug level. if log_enabled!(log::Level::Debug) { use std::fmt::Write; let mut expected_s = String::with_capacity(32); let mut decoded_s = String::with_capacity(32); expected.iter().for_each(|b| write!(expected_s, "{:02x}", b).unwrap()); decoded.iter().for_each(|b| write!(decoded_s, "{:02x}", b).unwrap()); debug!("verification: expected md5 = {}", expected_s); debug!("verification: decoded md5 = {}", decoded_s); } result.verify_ok = Some(decoded == expected) } else { warn!("verification requested but the expected md5 checksum was not provided"); } } result } fn last_decoded(&self) -> AudioBufferRef<'_> { self.buf.as_audio_buffer_ref() } } // Subframe business #[derive(Debug)] enum SubFrameType { Constant, Verbatim, FixedLinear(u32), Linear(u32), } fn read_subframe(bs: &mut B, frame_bps: u32, buf: &mut [i32]) -> Result<()> { // First sub-frame bit must always 0. if bs.read_bool()? { return decode_error("flac: subframe padding is not 0"); } // Next 6 bits designate the sub-frame type. let subframe_type_enc = bs.read_bits_leq32(6)?; let subframe_type = match subframe_type_enc { 0x00 => SubFrameType::Constant, 0x01 => SubFrameType::Verbatim, 0x08..=0x0f => { let order = subframe_type_enc & 0x07; // The Fixed Predictor only supports orders between 0 and 4. if order > 4 { return decode_error("flac: fixed predictor orders of greater than 4 are invalid"); } SubFrameType::FixedLinear(order) } 0x20..=0x3f => SubFrameType::Linear((subframe_type_enc & 0x1f) + 1), _ => { return decode_error("flac: subframe type set to reserved value"); } }; // Bit 7 of the sub-frame header designates if there are any dropped (wasted in FLAC terms) // bits per sample in the audio sub-block. If the bit is set, unary decode the number of // dropped bits per sample. let dropped_bps = if bs.read_bool()? { bs.read_unary_zeros()? + 1 } else { 0 }; // The bits per sample stated in the frame header is for the decoded audio sub-block samples. // However, it is likely that the lower order bits of all the samples are simply 0. Therefore, // the encoder will truncate `dropped_bps` of lower order bits for every sample in a sub-block. // The decoder simply needs to shift left all samples by `dropped_bps` after decoding the // sub-frame and obtaining the truncated audio sub-block samples. let bps = frame_bps - dropped_bps; // trace!("\tsubframe: type={:?}, bps={}, dropped_bps={}", // &subframe_type, // bps, // dropped_bps); match subframe_type { SubFrameType::Constant => decode_constant(bs, bps, buf)?, SubFrameType::Verbatim => decode_verbatim(bs, bps, buf)?, SubFrameType::FixedLinear(order) => decode_fixed_linear(bs, bps, order, buf)?, SubFrameType::Linear(order) => decode_linear(bs, bps, order, buf)?, }; // Shift the samples to account for the dropped bits. samples_shl(dropped_bps, buf); Ok(()) } #[inline(always)] fn samples_shl(shift: u32, buf: &mut [i32]) { if shift > 0 { for sample in buf.iter_mut() { *sample = sample.wrapping_shl(shift); } } } fn decode_constant(bs: &mut B, bps: u32, buf: &mut [i32]) -> Result<()> { let const_sample = sign_extend_leq32_to_i32(bs.read_bits_leq32(bps)?, bps); for sample in buf.iter_mut() { *sample = const_sample; } Ok(()) } fn decode_verbatim(bs: &mut B, bps: u32, buf: &mut [i32]) -> Result<()> { for sample in buf.iter_mut() { *sample = sign_extend_leq32_to_i32(bs.read_bits_leq32(bps)?, bps); } Ok(()) } fn decode_fixed_linear( bs: &mut B, bps: u32, order: u32, buf: &mut [i32], ) -> Result<()> { // The first `order` samples are encoded verbatim to warm-up the LPC decoder. decode_verbatim(bs, bps, &mut buf[..order as usize])?; // Decode the residuals for the predicted samples. decode_residual(bs, order, buf)?; // Run the Fixed predictor (appends to residuals). // // TODO: The fixed predictor uses 64-bit accumulators by default to support bps > 26. On 64-bit // machines, this is preferable, but on 32-bit machines if bps <= 26, run a 32-bit predictor, // and fallback to the 64-bit predictor if necessary (which is basically never). fixed_predict(order, buf)?; Ok(()) } fn decode_linear(bs: &mut B, bps: u32, order: u32, buf: &mut [i32]) -> Result<()> { // The order of the Linear Predictor should be between 1 and 32. debug_assert!(order > 0 && order <= 32); // The first `order` samples are encoded verbatim to warm-up the LPC decoder. decode_verbatim(bs, bps, &mut buf[0..order as usize])?; // Quantized linear predictor (QLP) coefficients precision in bits. let qlp_precision = bs.read_bits_leq32(4)? + 1; if qlp_precision > 15 { return decode_error("flac: qlp precision set to reserved value"); } // QLP coefficients bit shift [-16, 15]. let qlp_coeff_shift = sign_extend_leq32_to_i32(bs.read_bits_leq32(5)?, 5); if qlp_coeff_shift >= 0 { // Pick the best sized linear predictor to use based on the order. Most if not all FLAC // streams apppear to have an order <= 12. Specializing a predictor for orders <= 6 and // <= 12 appears to give the best performance. // // TODO: Reduce code duplication here. if order <= 4 { let mut qlp_coeffs = [0i32; 4]; for c in qlp_coeffs[4 - order as usize..4].iter_mut().rev() { *c = sign_extend_leq32_to_i32(bs.read_bits_leq32(qlp_precision)?, qlp_precision); } decode_residual(bs, order, buf)?; lpc_predict_4(order as usize, &qlp_coeffs, qlp_coeff_shift as u32, buf)?; } else if order <= 8 { let mut qlp_coeffs = [0i32; 8]; for c in qlp_coeffs[8 - order as usize..8].iter_mut().rev() { *c = sign_extend_leq32_to_i32(bs.read_bits_leq32(qlp_precision)?, qlp_precision); } decode_residual(bs, order, buf)?; lpc_predict_8(order as usize, &qlp_coeffs, qlp_coeff_shift as u32, buf)?; } else if order <= 12 { let mut qlp_coeffs = [0i32; 12]; for c in qlp_coeffs[12 - order as usize..12].iter_mut().rev() { *c = sign_extend_leq32_to_i32(bs.read_bits_leq32(qlp_precision)?, qlp_precision); } decode_residual(bs, order, buf)?; lpc_predict_12(order as usize, &qlp_coeffs, qlp_coeff_shift as u32, buf)?; } else { let mut qlp_coeffs = [0i32; 32]; for c in qlp_coeffs[32 - order as usize..32].iter_mut().rev() { *c = sign_extend_leq32_to_i32(bs.read_bits_leq32(qlp_precision)?, qlp_precision); } decode_residual(bs, order, buf)?; lpc_predict_32(order as usize, &qlp_coeffs, qlp_coeff_shift as u32, buf)?; } } else { return unsupported_error("flac: lpc shifts less than 0 are not supported"); } Ok(()) } fn decode_residual( bs: &mut B, n_prelude_samples: u32, buf: &mut [i32], ) -> Result<()> { let method_enc = bs.read_bits_leq32(2)?; // The FLAC specification defines two residual coding methods: Rice and Rice2. The // only difference between the two is the bit width of the Rice parameter. Note the // bit width based on the residual encoding method and use the same code path for // both cases. let param_bit_width = match method_enc { 0x0 => 4, 0x1 => 5, _ => { return decode_error("flac: residual method set to reserved value"); } }; // Read the partition order. let order = bs.read_bits_leq32(4)?; // The number of paritions is equal to 2^order. let n_partitions = 1usize << order; // In general, all partitions have the same number of samples such that the sum of all partition // lengths equal the block length. The number of samples in a partition can therefore be // calculated with block_size / 2^order *in general*. However, since there are warm-up samples // stored verbatim, the first partition has n_prelude_samples less samples. Likewise, if there // is only one partition, then it too has n_prelude_samples less samples. let n_partition_samples = buf.len() >> order; // The size of the first (and/or only) partition as per the specification is n_partition_samples // minus the number of warm-up samples (which is the predictor order). Ensure the number of // samples in these types of partitions cannot be negative. if n_prelude_samples as usize > n_partition_samples { return decode_error("flac: residual partition too small for given predictor order"); } // Ensure that the sum of all partition lengths equal the block size. if n_partitions * n_partition_samples != buf.len() { return decode_error("flac: block size is not same as encoded residual"); } // trace!("\t\tresidual: n_partitions={}, n_partition_samples={}, n_prelude_samples={}", // n_partitions, // n_partition_samples, // n_prelude_samples); // Decode the first partition as it may have less than n_partition_samples samples. decode_rice_partition( bs, param_bit_width, &mut buf[n_prelude_samples as usize..n_partition_samples], )?; // Decode the remaining partitions. for buf_chunk in buf[n_partition_samples..].chunks_mut(n_partition_samples) { decode_rice_partition(bs, param_bit_width, buf_chunk)?; } Ok(()) } fn decode_rice_partition( bs: &mut B, param_bit_width: u32, buf: &mut [i32], ) -> Result<()> { // Read the encoding parameter, generally the Rice parameter. let rice_param = bs.read_bits_leq32(param_bit_width)?; // If the Rice parameter is all 1s (e.g., 0xf for a 4bit parameter, 0x1f for a 5bit parameter), // then it indicates that residuals in this partition are not Rice encoded, rather they are // binary encoded. Conversely, if the parameter is less than this value, the residuals are Rice // encoded. if rice_param < (1 << param_bit_width) - 1 { // println!("\t\t\tPartition (Rice): n_residuals={}, rice_param={}", buf.len(), rice_param); // Read each rice encoded residual and store in buffer. for sample in buf.iter_mut() { let q = bs.read_unary_zeros()?; let r = bs.read_bits_leq32(rice_param)?; *sample = rice_signed_to_i32((q << rice_param) | r); } } else { let residual_bits = bs.read_bits_leq32(5)?; // trace!( // "\t\t\tpartition (Binary): n_residuals={}, residual_bits={}", // buf.len(), // residual_bits // ); // Read each binary encoded residual and store in buffer. for sample in buf.iter_mut() { *sample = sign_extend_leq32_to_i32(bs.read_bits_leq32(residual_bits)?, residual_bits); } } Ok(()) } #[inline(always)] fn rice_signed_to_i32(word: u32) -> i32 { // Input => 0 1 2 3 4 5 6 7 8 9 10 // Output => 0 -1 1 -2 2 -3 3 -4 4 -5 5 // // - If even: output = input / 2 // - If odd: output = -(input + 1) / 2 // = (input / 2) - 1 // Divide the input by 2 and convert to signed. let div2 = (word >> 1) as i32; // Using the LSB of the input, create a new signed integer that's either // -1 (0b1111_11110) or 0 (0b0000_0000). For odd inputs, this will be -1, for even // inputs it'll be 0. let sign = -((word & 0x1) as i32); // XOR the div2 result with the sign. If sign is 0, the XOR produces div2. If sign is -1, then // -div2 - 1 is returned. // // Example: input = 9 => div2 = 0b0000_0100, sign = 0b1111_11110 // // div2 ^ sign = 0b0000_0100 // ^ 0b1111_1110 // ----------- // 0b1111_1011 (-5) div2 ^ sign } #[test] fn verify_rice_signed_to_i32() { assert_eq!(rice_signed_to_i32(0), 0); assert_eq!(rice_signed_to_i32(1), -1); assert_eq!(rice_signed_to_i32(2), 1); assert_eq!(rice_signed_to_i32(3), -2); assert_eq!(rice_signed_to_i32(4), 2); assert_eq!(rice_signed_to_i32(5), -3); assert_eq!(rice_signed_to_i32(6), 3); assert_eq!(rice_signed_to_i32(7), -4); assert_eq!(rice_signed_to_i32(8), 4); assert_eq!(rice_signed_to_i32(9), -5); assert_eq!(rice_signed_to_i32(10), 5); assert_eq!(rice_signed_to_i32(u32::max_value()), -2_147_483_648); } fn fixed_predict(order: u32, buf: &mut [i32]) -> Result<()> { debug_assert!(order <= 4); // The Fixed Predictor is just a hard-coded version of the Linear Predictor up to order 4 and // with fixed coefficients. Some cases may be simplified such as orders 0 and 1. For orders 2 // through 4, use the same IIR-style algorithm as the Linear Predictor. match order { // A 0th order predictor always predicts 0, and therefore adds nothing to any of the samples // in buf. Do nothing. 0 => (), // A 1st order predictor always returns the previous sample since the polynomial is: // s(i) = 1*s(i), 1 => { for i in 1..buf.len() { buf[i] += buf[i - 1]; } } // A 2nd order predictor uses the polynomial: s(i) = 2*s(i-1) - 1*s(i-2). 2 => { for i in 2..buf.len() { let a = Wrapping(-1) * Wrapping(i64::from(buf[i - 2])); let b = Wrapping(2) * Wrapping(i64::from(buf[i - 1])); buf[i] += (a + b).0 as i32; } } // A 3rd order predictor uses the polynomial: s(i) = 3*s(i-1) - 3*s(i-2) + 1*s(i-3). 3 => { for i in 3..buf.len() { let a = Wrapping(1) * Wrapping(i64::from(buf[i - 3])); let b = Wrapping(-3) * Wrapping(i64::from(buf[i - 2])); let c = Wrapping(3) * Wrapping(i64::from(buf[i - 1])); buf[i] += (a + b + c).0 as i32; } } // A 4th order predictor uses the polynomial: // s(i) = 4*s(i-1) - 6*s(i-2) + 4*s(i-3) - 1*s(i-4). 4 => { for i in 4..buf.len() { let a = Wrapping(-1) * Wrapping(i64::from(buf[i - 4])); let b = Wrapping(4) * Wrapping(i64::from(buf[i - 3])); let c = Wrapping(-6) * Wrapping(i64::from(buf[i - 2])); let d = Wrapping(4) * Wrapping(i64::from(buf[i - 1])); buf[i] += (a + b + c + d).0 as i32; } } _ => unreachable!(), }; Ok(()) } /// Generalized Linear Predictive Coding (LPC) decoder macro for orders >= 4. The exact number of /// coefficients given is specified by `order`. Coefficients must be stored in reverse order in /// `coeffs` with the first coefficient at index 31. Coefficients at indicies less than /// 31 - `order` must be 0. It is expected that the first `order` samples in `buf` are warm-up /// samples. macro_rules! lpc_predictor { ($func_name:ident, $order:expr) => { fn $func_name( order: usize, coeffs: &[i32; $order], coeff_shift: u32, buf: &mut [i32], ) -> Result<()> { // Order must be less than or equal to the number of coefficients. debug_assert!(order as usize <= coeffs.len()); // Order must be less than to equal to the number of samples the buffer can hold. debug_assert!(order as usize <= buf.len()); let n_prefill = cmp::min($order, buf.len()) - order; // If the pre-fill computation filled the entire sample buffer, return immediately since // the main predictor requires atleast 32 samples to be present in the buffer. for i in order..order + n_prefill { let predicted = coeffs[$order - order..$order] .iter() .zip(&buf[i - order..i]) .map(|(&c, &sample)| c as i64 * sample as i64) .sum::(); buf[i] += (predicted >> coeff_shift) as i32; } if buf.len() <= $order { return Ok(()); } for i in $order..buf.len() { // Predict each sample by applying what is essentially an IIR filter. // // This implementation supersedes an iterator based approach where coeffs and // samples were zipped together, multiplied together via map, and then summed. That // implementation did not pipeline well since summing was performed before the next // multiplication, introducing pipleine stalls. This unrolled approach is much // faster atleast on Intel hardware. let s = &buf[i - $order..i]; let mut predicted = 0i64; for j in 0..($order / 4) { let a = coeffs[4 * j + 0] as i64 * s[4 * j + 0] as i64; let b = coeffs[4 * j + 1] as i64 * s[4 * j + 1] as i64; let c = coeffs[4 * j + 2] as i64 * s[4 * j + 2] as i64; let d = coeffs[4 * j + 3] as i64 * s[4 * j + 3] as i64; predicted += a + b + c + d; } buf[i] += (predicted >> coeff_shift) as i32; } Ok(()) } }; } lpc_predictor!(lpc_predict_32, 32); lpc_predictor!(lpc_predict_12, 12); lpc_predictor!(lpc_predict_8, 8); lpc_predictor!(lpc_predict_4, 4); symphonia-bundle-flac-0.5.2/src/demuxer.rs000064400000000000000000000361011046102023000166200ustar 00000000000000// 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::io::{Seek, SeekFrom}; use symphonia_core::support_format; use symphonia_core::codecs::{CodecParameters, VerificationCheck, CODEC_TYPE_FLAC}; use symphonia_core::errors::{decode_error, seek_error, unsupported_error, Result, SeekErrorKind}; use symphonia_core::formats::prelude::*; use symphonia_core::formats::util::{SeekIndex, SeekSearchResult}; use symphonia_core::io::*; use symphonia_core::meta::{Metadata, MetadataBuilder, MetadataLog}; use symphonia_core::probe::{Descriptor, Instantiate, QueryDescriptor}; use symphonia_utils_xiph::flac::metadata::*; use log::{debug, info}; use super::parser::PacketParser; /// The FLAC start of stream marker: "fLaC" in ASCII. const FLAC_STREAM_MARKER: [u8; 4] = *b"fLaC"; /// Free Lossless Audio Codec (FLAC) native frame reader. pub struct FlacReader { reader: MediaSourceStream, metadata: MetadataLog, tracks: Vec, cues: Vec, index: Option, first_frame_offset: u64, parser: PacketParser, } impl FlacReader { /// Reads all the metadata blocks, returning a fully populated `FlacReader`. fn init_with_metadata(source: MediaSourceStream) -> Result { let mut metadata_builder = MetadataBuilder::new(); let mut reader = source; let mut tracks = Vec::new(); let mut cues = Vec::new(); let mut index = None; let mut parser = Default::default(); loop { let header = MetadataBlockHeader::read(&mut reader)?; // Create a scoped bytestream to error if the metadata block read functions exceed the // stated length of the block. let mut block_stream = ScopedStream::new(&mut reader, u64::from(header.block_len)); match header.block_type { MetadataBlockType::Application => { // TODO: Store vendor data. read_application_block(&mut block_stream, header.block_len)?; } // SeekTable blocks are parsed into a SeekIndex. MetadataBlockType::SeekTable => { // Check if a SeekTable has already be parsed. If one has, then the file is // invalid, atleast for seeking. Either way, it's a violation of the // specification. if index.is_none() { let mut new_index = SeekIndex::new(); read_seek_table_block(&mut block_stream, header.block_len, &mut new_index)?; index = Some(new_index); } else { return decode_error("flac: found more than one seek table block"); } } // VorbisComment blocks are parsed into Tags. MetadataBlockType::VorbisComment => { read_comment_block(&mut block_stream, &mut metadata_builder)?; } // Cuesheet blocks are parsed into Cues. MetadataBlockType::Cuesheet => { read_cuesheet_block(&mut block_stream, &mut cues)?; } // Picture blocks are read as Visuals. MetadataBlockType::Picture => { read_picture_block(&mut block_stream, &mut metadata_builder)?; } // StreamInfo blocks are parsed into Streams. MetadataBlockType::StreamInfo => { read_stream_info_block(&mut block_stream, &mut tracks, &mut parser)?; } // Padding blocks are skipped. MetadataBlockType::Padding => { block_stream.ignore_bytes(u64::from(header.block_len))?; } // Unknown block encountered. Skip these blocks as they may be part of a future // version of FLAC, but print a message. MetadataBlockType::Unknown(id) => { block_stream.ignore_bytes(u64::from(header.block_len))?; info!("ignoring {} bytes of block width id={}.", header.block_len, id); } } // If the stated block length is longer than the number of bytes from the block read, // ignore the remaining unread data. let block_unread_len = block_stream.bytes_available(); if block_unread_len > 0 { info!("under read block by {} bytes.", block_unread_len); block_stream.ignore_bytes(block_unread_len)?; } // Exit when the last header is read. if header.is_last { break; } } // Commit any read metadata to the metadata log. let mut metadata = MetadataLog::default(); metadata.push(metadata_builder.metadata()); // Synchronize the packet parser to the first audio frame. let _ = parser.resync(&mut reader)?; // The first frame offset is the byte offset from the beginning of the stream after all the // metadata blocks have been read. let first_frame_offset = reader.pos(); Ok(FlacReader { reader, metadata, tracks, cues, index, first_frame_offset, parser }) } } impl QueryDescriptor for FlacReader { fn query() -> &'static [Descriptor] { &[support_format!( "flac", "Free Lossless Audio Codec Native", &["flac"], &["audio/flac"], &[b"fLaC"] )] } fn score(_context: &[u8]) -> u8 { 255 } } impl FormatReader for FlacReader { fn try_new(mut source: MediaSourceStream, _options: &FormatOptions) -> Result { // Read the first 4 bytes of the stream. Ideally this will be the FLAC stream marker. let marker = source.read_quad_bytes()?; if marker != FLAC_STREAM_MARKER { return unsupported_error("flac: missing flac stream marker"); } // Strictly speaking, the first metadata block must be a StreamInfo block. There is // no technical need for this from the reader's point of view. Additionally, if the // reader is fed a stream mid-way there is no StreamInfo block. Therefore, just read // all metadata blocks and handle the StreamInfo block as it comes. let flac = Self::init_with_metadata(source)?; // Make sure that there is atleast one StreamInfo block. if flac.tracks.is_empty() { return decode_error("flac: no stream info block"); } Ok(flac) } fn next_packet(&mut self) -> Result { self.parser.parse(&mut self.reader) } fn metadata(&mut self) -> Metadata<'_> { self.metadata.metadata() } fn cues(&self) -> &[Cue] { &self.cues } fn tracks(&self) -> &[Track] { &self.tracks } fn seek(&mut self, _mode: SeekMode, to: SeekTo) -> Result { if self.tracks.is_empty() { return seek_error(SeekErrorKind::Unseekable); } let params = &self.tracks[0].codec_params; // Get the timestamp of the desired audio frame. let ts = match to { // Frame timestamp given. SeekTo::TimeStamp { ts, .. } => ts, // Time value given, calculate frame timestamp from sample rate. SeekTo::Time { time, .. } => { // Use the sample rate to calculate the frame timestamp. If sample rate is not // known, the seek cannot be completed. if let Some(sample_rate) = params.sample_rate { TimeBase::new(1, sample_rate).calc_timestamp(time) } else { return seek_error(SeekErrorKind::Unseekable); } } }; debug!("seeking to frame_ts={}", ts); // If the total number of frames in the stream is known, verify the desired frame timestamp // does not exceed it. if let Some(n_frames) = params.n_frames { if ts > n_frames { return seek_error(SeekErrorKind::OutOfRange); } } // If the reader supports seeking, coarsely seek to the nearest packet with a timestamp // lower than the desired timestamp using a binary search. if self.reader.is_seekable() { // The range formed by start_byte_offset..end_byte_offset defines an area where the // binary search for the packet containing the desired timestamp will be performed. The // lower bound is set to the byte offset of the first frame, while the upper bound is // set to the length of the stream. let mut start_byte_offset = self.first_frame_offset; let mut end_byte_offset = self.reader.seek(SeekFrom::End(0))?; // If there is an index, use it to refine the binary search range. if let Some(ref index) = self.index { // Search the index for the timestamp. Adjust the search based on the result. match index.search(ts) { // Search from the start of stream up-to an ending point. SeekSearchResult::Upper(upper) => { end_byte_offset = self.first_frame_offset + upper.byte_offset; } // Search from a starting point up-to the end of the stream. SeekSearchResult::Lower(lower) => { start_byte_offset = self.first_frame_offset + lower.byte_offset; } // Search between two points of the stream. SeekSearchResult::Range(lower, upper) => { start_byte_offset = self.first_frame_offset + lower.byte_offset; end_byte_offset = self.first_frame_offset + upper.byte_offset; } // Search the entire stream (default behaviour, so do nothing). SeekSearchResult::Stream => (), } } // Binary search the range of bytes formed by start_by_offset..end_byte_offset for the // desired frame timestamp. When the difference of the range reaches 2x the maximum // frame size, exit the loop and search from the start_byte_offset linearly. The binary // search becomes inefficient when the range is small. while end_byte_offset - start_byte_offset > 2 * 8096 { let mid_byte_offset = (start_byte_offset + end_byte_offset) / 2; self.reader.seek(SeekFrom::Start(mid_byte_offset))?; let sync = self.parser.resync(&mut self.reader)?; if ts < sync.ts { end_byte_offset = mid_byte_offset; } else if ts > sync.ts && ts < sync.ts + sync.dur { debug!("seeked to ts={} (delta={})", sync.ts, sync.ts as i64 - ts as i64); return Ok(SeekedTo { track_id: 0, actual_ts: sync.ts, required_ts: ts }); } else { start_byte_offset = mid_byte_offset; } } // The binary search did not find an exact frame, but the range has been narrowed. Seek // to the start of the range, and continue with a linear search. self.reader.seek(SeekFrom::Start(start_byte_offset))?; } // Linearly search the stream packet-by-packet for the packet that contains the desired // timestamp. This search is used to find the exact packet containing the desired timestamp // after the search range was narrowed by the binary search. It is also the ONLY way for a // unseekable stream to be "seeked" forward. let packet = loop { let sync = self.parser.resync(&mut self.reader)?; // The desired timestamp preceeds the current packet's timestamp. if ts < sync.ts { // Attempted to seek backwards on an unseekable stream. if !self.reader.is_seekable() { return seek_error(SeekErrorKind::ForwardOnly); } // Overshot a regular seek, or the stream is corrupted, not necessarily an error // per-say. else { break sync; } } // The desired timestamp is contained within the current packet. else if ts >= sync.ts && ts < sync.ts + sync.dur { break sync; } // Advance the reader such that the next iteration will sync to a different frame. self.reader.read_byte()?; }; debug!("seeked to packet_ts={} (delta={})", packet.ts, packet.ts as i64 - ts as i64); Ok(SeekedTo { track_id: 0, actual_ts: packet.ts, required_ts: ts }) } fn into_inner(self: Box) -> MediaSourceStream { self.reader } } /// Reads a StreamInfo block and populates the reader with stream information. fn read_stream_info_block( reader: &mut B, tracks: &mut Vec, parser: &mut PacketParser, ) -> Result<()> { // Only one StreamInfo block, and therefore only one Track, is allowed per media source stream. if tracks.is_empty() { // Ensure the block length is correct for a stream information block before allocating a // buffer for it. if !StreamInfo::is_valid_size(reader.byte_len()) { return decode_error("flac: invalid stream info block size"); } // Read the stream information block as a boxed slice so that it may be attached as extra // data on the codec parameters. let extra_data = reader.read_boxed_slice_exact(reader.byte_len() as usize)?; // Parse the stream info block. let info = StreamInfo::read(&mut BufReader::new(&extra_data))?; // Populate the codec parameters with the basic audio parameters of the track. let mut codec_params = CodecParameters::new(); codec_params .for_codec(CODEC_TYPE_FLAC) .with_packet_data_integrity(true) .with_extra_data(extra_data) .with_sample_rate(info.sample_rate) .with_time_base(TimeBase::new(1, info.sample_rate)) .with_bits_per_sample(info.bits_per_sample) .with_channels(info.channels); if let Some(md5) = info.md5 { codec_params.with_verification_code(VerificationCheck::Md5(md5)); } // Total samples per channel (the total number of frames) is optional. if let Some(n_frames) = info.n_samples { codec_params.with_n_frames(n_frames); } // Reset the packet parser. parser.reset(info); // Add the track. tracks.push(Track::new(0, codec_params)); } else { return decode_error("flac: found more than one stream info block"); } Ok(()) } symphonia-bundle-flac-0.5.2/src/frame.rs000064400000000000000000000277731046102023000162600ustar 00000000000000// 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 symphonia_core::checksum::Crc8Ccitt; use symphonia_core::errors::{decode_error, Result}; use symphonia_core::io::{Monitor, MonitorStream, ReadBytes}; /// The minimum FLAC frame header size including the sync bytes. pub const FLAC_MIN_FRAME_HEADER_SIZE: usize = 6; /// The maximum FLAC frame header size including the sync bytes. pub const FLAC_MAX_FRAME_HEADER_SIZE: usize = 16; /// The maximum FLAC frame size. pub const FLAC_MAX_FRAME_SIZE: usize = 16 * 1024 * 1024; #[derive(Debug)] enum BlockingStrategy { Fixed, Variable, } #[derive(Debug)] pub enum BlockSequence { BySample(u64), ByFrame(u32), } /// `ChannelAssignment` describes the mapping between the samples decoded from a subframe and the /// channel those samples belong to. It is also through the `ChannelAssignment` that the decoder is /// instructed on how to decorrelate stereo channels. // /// For LeftSide or RightSide channel assignments, one channel is stored independently while the /// other stores a difference. The Difference is always stored as Left - Right. For the MidSide /// channel assignment, no channels are stored independently, rather, a Mid (average) channel and a /// Difference channel are stored. #[derive(Debug)] pub enum ChannelAssignment { /// All channels are independantly coded and no decorrelation step is required. Independant(u32), /// Channel 0 is the Left channel, and channel 1 is a Difference channel. The Right channel /// is restored by subtracting the Difference channel from the Left channel (R = L - D). LeftSide, /// Channel 0 is the Mid channel (Left/2 + Right/2), and channel 1 is the Difference channel /// (Left - Right). Therefore, if M = L/2 + R/2 and D = L - R, solving for L and R the left /// and right channels are: L = S/2 + M, and R = M - S/2. MidSide, /// Channel 0 is the Difference channel, and channel 1 is the Right channel. The Left channel /// is restored by adding the Difference channel to the Right channel (L = R + D). RightSide, } pub struct FrameHeader { pub block_sequence: BlockSequence, pub block_num_samples: u16, pub channel_assignment: ChannelAssignment, pub bits_per_sample: Option, pub sample_rate: Option, } pub fn sync_frame(reader: &mut B) -> Result { let mut sync = 0u16; // Synchronize stream to Frame Header. FLAC specifies a byte-aligned 14 bit sync code of // `0b11_1111_1111_1110`. This would be difficult to find on its own. Expand the search to // a 16-bit field of `0b1111_1111_1111_10xx` and search a word at a time. while (sync & 0xfffc) != 0xfff8 { sync = sync.wrapping_shl(8) | u16::from(reader.read_u8()?); } Ok(sync) } pub fn read_frame_header(reader: &mut B, sync: u16) -> Result { // The header is checksummed with a CRC8 hash. Include the sync code in this CRC. let mut crc8 = Crc8Ccitt::new(0); crc8.process_buf_bytes(&sync.to_be_bytes()); let mut reader_crc8 = MonitorStream::new(reader, crc8); // Extract the blocking strategy from the expanded synchronization code. let blocking_strategy = match sync & 0x1 { 0 => BlockingStrategy::Fixed, _ => BlockingStrategy::Variable, }; // Read all the standard frame description fields as one 16-bit value and extract the // fields. let desc = reader_crc8.read_be_u16()?; let block_size_enc = u32::from((desc & 0xf000) >> 12); let sample_rate_enc = u32::from((desc & 0x0f00) >> 8); let channels_enc = u32::from((desc & 0x00f0) >> 4); let bits_per_sample_enc = u32::from((desc & 0x000e) >> 1); if (desc & 0x0001) == 1 { return decode_error("flac: frame header reserved bit is not set to mandatory value"); } let block_sequence = match blocking_strategy { // Fixed-blocksize stream sequence blocks by a frame number. BlockingStrategy::Fixed => { let frame = match utf8_decode_be_u64(&mut reader_crc8)? { Some(frame) => frame, None => return decode_error("flac: frame sequence number is not valid"), }; // The frame number should only be 31-bits. Since it is UTF8 encoded, the actual length // cannot be enforced by the decoder. Return an error if the frame number exceeds the // maximum 31-bit value. if frame > 0x7fff_ffff { return decode_error("flac: frame sequence number exceeds 31-bits"); } BlockSequence::ByFrame(frame as u32) } // Variable-blocksize streams sequence blocks by a sample number. BlockingStrategy::Variable => { let sample = match utf8_decode_be_u64(&mut reader_crc8)? { Some(sample) => sample, None => return decode_error("flac: sample sequence number is not valid"), }; // The sample number should only be 36-bits. Since it is UTF8 encoded, the actual length // cannot be enforced by the decoder. Return an error if the frame number exceeds the // maximum 36-bit value. if sample > 0x000f_ffff_ffff { return decode_error("flac: sample sequence number exceeds 36-bits"); } BlockSequence::BySample(sample) } }; let block_num_samples = match block_size_enc { 0x1 => 192, 0x2..=0x5 => 576 * (1 << (block_size_enc - 2)), 0x6 => u16::from(reader_crc8.read_u8()?) + 1, 0x7 => { let block_size = reader_crc8.read_be_u16()?; if block_size == 0xffff { return decode_error("flac: block size not allowed to be greater than 65535"); } block_size + 1 } 0x8..=0xf => 256 * (1 << (block_size_enc - 8)), _ => { return decode_error("flac: block size set to reserved value"); } }; let sample_rate = match sample_rate_enc { 0x0 => None, // Get from StreamInfo if possible. 0x1 => Some(88_200), 0x2 => Some(176_400), 0x3 => Some(192_000), 0x4 => Some(8_000), 0x5 => Some(16_000), 0x6 => Some(22_050), 0x7 => Some(24_000), 0x8 => Some(32_000), 0x9 => Some(44_100), 0xa => Some(48_000), 0xb => Some(96_000), 0xc => Some(u32::from(reader_crc8.read_u8()?)), 0xd => Some(u32::from(reader_crc8.read_be_u16()?)), 0xe => Some(u32::from(reader_crc8.read_be_u16()?) * 10), _ => { return decode_error("flac: sample rate set to reserved value"); } }; if let Some(rate) = sample_rate { if rate < 1 || rate > 655_350 { return decode_error("flac: sample rate out of bounds"); } } let bits_per_sample = match bits_per_sample_enc { 0x0 => None, // Get from StreamInfo if possible. 0x1 => Some(8), 0x2 => Some(12), 0x4 => Some(16), 0x5 => Some(20), 0x6 => Some(24), _ => { return decode_error("flac: bits per sample set to reserved value"); } }; let channel_assignment = match channels_enc { 0x0..=0x7 => ChannelAssignment::Independant(channels_enc + 1), 0x8 => ChannelAssignment::LeftSide, 0x9 => ChannelAssignment::RightSide, 0xa => ChannelAssignment::MidSide, _ => { return decode_error("flac: channel assignment set to reserved value"); } }; // End of freame header, pop off CRC8 checksum. let crc8_computed = reader_crc8.monitor().crc(); // Get expected CRC8 checksum from the header. let crc8_expected = reader_crc8.into_inner().read_u8()?; if crc8_expected != crc8_computed && cfg!(not(fuzzing)) { return decode_error("flac: computed frame header CRC does not match expected CRC"); } Ok(FrameHeader { block_sequence, block_num_samples, channel_assignment, bits_per_sample, sample_rate, }) } /// A very quick check if the provided buffer is likely be a FLAC frame header. pub fn is_likely_frame_header(buf: &[u8]) -> bool { // Minimum frame header size. if buf.len() < FLAC_MIN_FRAME_HEADER_SIZE { return false; } // First sync word. if buf[0] != 0xff { return false; } // Second sync word. if (buf[1] & 0xfc) != 0xf8 { return false; } // Reserved block size. if (buf[2] & 0xf0) == 0x00 { return false; } // Reserved sample rate. if (buf[2] & 0x0f) == 0x0f { return false; } // Reserved channel assignments 0xb to 0xf. if ((buf[3] & 0xf0) >> 4) >= 0xb { return false; } // Reserved sample size. if (buf[3] & 0x0e == 0x6) || (buf[3] & 0x0e == 0x0e) { return false; } // Reserved bit. if buf[3] & 0x1 == 1 { return false; } true } /// Decodes a big-endian unsigned integer encoded via extended UTF8. In this context, extended UTF8 /// simply means the encoded UTF8 value may be up to 7 bytes for a maximum integer bit width of /// 36-bits. fn utf8_decode_be_u64(src: &mut B) -> Result> { // Read the first byte of the UTF8 encoded integer. let mut state = u64::from(src.read_u8()?); // UTF8 prefixes 1s followed by a 0 to indicate the total number of bytes within the multi-byte // sequence. Using ranges, determine the mask that will overlap the data bits within the first // byte of the sequence. For values 0-128, return the value immediately. If the value falls out // of range return None as this is either not the start of a UTF8 sequence or the prefix is // incorrect. let mask: u8 = match state { 0x00..=0x7f => return Ok(Some(state)), 0xc0..=0xdf => 0x1f, 0xe0..=0xef => 0x0f, 0xf0..=0xf7 => 0x07, 0xf8..=0xfb => 0x03, 0xfc..=0xfd => 0x01, 0xfe => 0x00, _ => return Ok(None), }; // Obtain the data bits from the first byte by using the data mask. state &= u64::from(mask); // Read the remaining bytes within the UTF8 sequence. Since the mask 0s out the UTF8 prefix // of 1s which indicate the length of the multi-byte sequence in bytes, plus an additional 0 // bit, the number of remaining bytes to read is the number of zeros in the mask minus 2. // To avoid extra computation, simply loop from 2 to the number of zeros. for _i in 2..mask.leading_zeros() { // Each subsequent byte after the first in UTF8 is prefixed with 0b10xx_xxxx, therefore // only 6 bits are useful. Append these six bits to the result by shifting the result left // by 6 bit positions, and appending the next subsequent byte with the first two high-order // bits masked out. state = (state << 6) | u64::from(src.read_u8()? & 0x3f); // TODO: Validation? Invalid if the byte is greater than 0x3f. } Ok(Some(state)) } #[cfg(test)] mod tests { use super::utf8_decode_be_u64; use symphonia_core::io::BufReader; #[test] fn verify_utf8_decode_be_u64() { let mut stream = BufReader::new(&[ 0x24, 0xc2, 0xa2, 0xe0, 0xa4, 0xb9, 0xe2, 0x82, // 0xac, 0xf0, 0x90, 0x8d, 0x88, 0xff, 0x80, 0xbf, // ]); assert_eq!(utf8_decode_be_u64(&mut stream).unwrap(), Some(36)); assert_eq!(utf8_decode_be_u64(&mut stream).unwrap(), Some(162)); assert_eq!(utf8_decode_be_u64(&mut stream).unwrap(), Some(2361)); assert_eq!(utf8_decode_be_u64(&mut stream).unwrap(), Some(8364)); assert_eq!(utf8_decode_be_u64(&mut stream).unwrap(), Some(66376)); assert_eq!(utf8_decode_be_u64(&mut stream).unwrap(), None); assert_eq!(utf8_decode_be_u64(&mut stream).unwrap(), None); assert_eq!(utf8_decode_be_u64(&mut stream).unwrap(), None); } } symphonia-bundle-flac-0.5.2/src/lib.rs000064400000000000000000000013121046102023000157110ustar 00000000000000// 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/. #![warn(rust_2018_idioms)] #![forbid(unsafe_code)] // The following lints are allowed in all Symphonia crates. Please see clippy.toml for their // justification. #![allow(clippy::comparison_chain)] #![allow(clippy::excessive_precision)] #![allow(clippy::identity_op)] #![allow(clippy::manual_range_contains)] mod decoder; mod demuxer; mod frame; mod parser; mod validate; pub use decoder::FlacDecoder; pub use demuxer::FlacReader; symphonia-bundle-flac-0.5.2/src/parser.rs000064400000000000000000000516601046102023000164520ustar 00000000000000// 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 symphonia_core::checksum::Crc16Ansi; use symphonia_core::errors::Result; use symphonia_core::formats::Packet; use symphonia_core::io::{BufReader, Monitor, ReadBytes, SeekBuffered}; use symphonia_core::util::bits; use symphonia_utils_xiph::flac::metadata::StreamInfo; use log::warn; use crate::frame::*; struct MovingAverage { samples: [usize; N], count: usize, } impl MovingAverage { /// Push a value onto the moving average filter. pub fn push(&mut self, value: usize) { self.samples[self.count % N] = value; self.count += 1; } /// Reset the moving average filter to 0. pub fn reset(&mut self) { self.count = 0; } /// Calculate the moving average. pub fn average(&self) -> usize { if self.count >= N { // If greater-than N values were pushed, then all samples must be averaged. self.samples.iter().sum::() / N } else if self.count > 0 { // If less-than N values were pushed, then only the first 0..N samples need to be // averaged. self.samples.iter().take(self.count).sum::() / self.count } else { // No samples. 0 } } } impl Default for MovingAverage { fn default() -> Self { Self { samples: [0; N], count: 0 } } } /// Frame synchronization information. pub struct SyncInfo { /// The timestamp of the first audio frame in the packet. pub ts: u64, /// The number of audio frames in the packet. pub dur: u64, } /// A parsed packet. struct ParsedPacket { /// The packet data. buf: Box<[u8]>, /// The packet's synchronization information. sync: SyncInfo, } /// A fragment footer. struct FragmentFooter { crc: u16, } impl FragmentFooter { fn new(buf: &[u8]) -> Self { let mut crc = [0; 2]; crc[0..2].copy_from_slice(buf); FragmentFooter { crc: u16::from_be_bytes(crc) } } } /// A FLAC packet fragment state tracker. struct FragmentState { /// A running total CRC16 of a packet if it started at the first byte of this fragment. crc16: Crc16Ansi, /// The running total size of a packet if it started at the first byte of this fragment. total_len: usize, } /// A FLAC packet fragment. struct Fragment { /// The fragment data. data: Box<[u8]>, /// The footer. If the fragment contains a footer (the fragment is either a whole packet, or /// the last fragment of a packet), then the footer contains a valid CRC16 for the packet. footer: FragmentFooter, /// True if the CRC16 of this fragment, excluding the footer, matches the CRC16 in the footer. crc_match: bool, /// The running fragment state. state: FragmentState, } impl Fragment { /// Create a new packet fragment with the given buffer. fn new(data: Box<[u8]>) -> Self { let total_len = data.len(); let (top, bottom) = data.split_at(total_len - 2); let footer = FragmentFooter::new(bottom); let mut crc16 = Crc16Ansi::new(0); crc16.process_buf_bytes(top); let crc_match = footer.crc == crc16.crc(); crc16.process_buf_bytes(bottom); Self { data, footer, crc_match, state: FragmentState { crc16, total_len } } } /// Append the buffer to the CRC. fn update(&mut self, frag: &Fragment) -> bool { let len = frag.data.len(); let (top, bottom) = frag.data.split_at(len - 2); self.state.crc16.process_buf_bytes(top); let crc_match = frag.footer.crc == self.state.crc16.crc(); self.state.crc16.process_buf_bytes(bottom); self.state.total_len += len; crc_match } /// Parse the frame header from the fragment. fn parse_header(&self) -> FrameHeader { let mut reader = BufReader::new(&self.data); let sync = reader.read_be_u16().unwrap(); read_frame_header(&mut reader, sync).unwrap() } } #[derive(Default)] struct PacketBuilder { /// Queue of fragments to merged to form a packet. frags: Vec, /// The maximum allowed size for a packet. This is the maximum frame size stated in the stream /// info header, if provided. max_size: Option, /// The average size of a packet. avg_size: Option, /// The last valid header, last_header: Option, } impl PacketBuilder { fn set_max_frame_size(&mut self, max_size: Option) { self.max_size = max_size; } fn get_max_frame_size(&self) -> usize { self.max_size.unwrap_or(FLAC_MAX_FRAME_SIZE) } fn set_avg_frame_size(&mut self, avg_size: Option) { self.avg_size = avg_size; } fn get_max_avg_frame_size(&self) -> usize { self.avg_size.map(|s| 4 * s).unwrap_or(FLAC_MAX_FRAME_SIZE) } fn last_header(&self) -> Option<&FrameHeader> { self.last_header.as_ref() } fn push_fragment(&mut self, frag: Fragment) { // Prune the fragment queue to guard against unbounded growth. if let Some(first) = self.frags.first() { // Pruning heuristics: // // 1) If the stream information block defines a maximum frame size, do not exceed that // frame size. // // 2) If a maximum frame size is not provided, a frame may never exceed 16MB as per // the FLAC specification. // // 3) If a maximum frame size is not established, but an average frame size size has // been determined, do not exceed it by a factor of 4. // // 4) If the fragment would have a depth > 4 after the new fragment is pushed. let prune = if first.state.total_len > self.get_max_frame_size() { warn!( "dropping fragment: packet would exceed maximum size of {} bytes", self.get_max_avg_frame_size() ); true } else if first.state.total_len > self.get_max_avg_frame_size() { warn!( "dropping fragment: packet would exeed 4x average historical size of {} bytes", self.get_max_avg_frame_size() ); true } else if self.frags.len() >= 4 { warn!("dropping fragment: packet would exceed fragment count limit"); true } else { false }; if prune { self.frags.remove(0); } } // debug!("saving fragment {}: len={}", self.frags.len(), frag.state.total_len); self.frags.push(frag); } fn try_build(&mut self, stream_info: &StreamInfo, frag: Fragment) -> Option { let (header, data) = if frag.crc_match { // The fragment has a CRC that matches the expected CRC. (frag.parse_header(), frag.data) } else { // The fragment does not have a CRC that matches the expected CRC. // // For each existing fragment, update its running CRC with the payload of the new // fragment. If an exisiting fragment, denoted as F, after having it's running CRC // updated matches the expected CRC of the new fragment. Then all fragments preceeding F // are discarded, and all fragments from F up-to and including the new fragment are // merged to form a packet. let start = self.frags.iter_mut().position(|f| f.update(&frag)); if let Some(i) = start { // A range of fragments has been found that forms a packet. let total_len = self.frags[i].state.total_len; // debug!("merging {} fragments: total_len={}", self.frags.len() - i + 1, total_len); // Merge fragment data buffers. let mut data = Vec::with_capacity(total_len); for f in self.frags[i..].iter() { data.extend_from_slice(&f.data); } data.extend_from_slice(&frag.data); (self.frags[i].parse_header(), data.into_boxed_slice()) } else { // A range of fragments has not been found that forms a packet. self.push_fragment(frag); return None; } }; // Drop all existing fragments. self.frags.clear(); let sync = calc_sync_info(stream_info, &header); self.last_header = Some(header); Some(ParsedPacket { buf: data, sync }) } fn reset(&mut self) { self.frags.clear(); self.last_header = None; } } #[derive(Default)] pub struct PacketParser { /// Stream information. info: StreamInfo, /// Frame size moving average. fsma: MovingAverage<4>, /// Packet builder. builder: PacketBuilder, } impl PacketParser { /// Perform a soft reset of the parser. Call this after a discontinuity in the stream. fn soft_reset(&mut self) { self.builder.reset(); self.fsma.reset(); } /// Tries to read a fragment upto the maximum size of a FLAC frame using the reader and returns /// it. If a fragment cannot be read, then the reader has lost synchronization and must be /// resynchronized. fn try_read_fragment( &self, reader: &mut B, avg_frame_size: usize, ) -> Result> where B: ReadBytes + SeekBuffered, { // The initial number of bytes to read. // // For this we use the average frame size clamped to a reasonable size with an added bias of // the maximum frame header size so that if the frame size is constant we don't do a second // read to synchronize to the next frame header. let init_read_size = avg_frame_size.clamp(1024, 32768) + FLAC_MAX_FRAME_HEADER_SIZE; // Buffer in which the fragment will be read. let mut buf: Vec = vec![0; init_read_size]; // Do the initial read. // // Note: This will always read atleast a single byte, or return an error (i.e., EOF). let mut end = reader.read_buf(&mut buf)?; // Invariant: The packet parser was synchronized before starting to read_fragment. // // If the previous call left the reader on a fragment boundary then we need to skip past one // byte so we don't get stuck synchronizing to the same frame header it synchronized to. // // If the last call could not fully read to the next frame header (due to IO errors, etc.), // then by definition there is more data to read belonging the previous call's fragment. // Therefore, the next byte should not be a new frame header so it is safe to also skip the // first byte. let mut pos = 1; // Read until the next frame header is found, or an IO error such as EOF. let size = 'found: loop { // Find the next frame header. Start by searching for the sync preamble. while let Some((offset, sync)) = scan_for_sync_preamble(&buf[pos..end]) { let size = pos + offset; let frame = &buf[size..]; // If the frame buffer passes a quick sanity check, then attempt to parse the // frame header in its entirety. if is_likely_frame_header(frame) { // Parse the frame header from the frame buffer. if let Ok(header) = read_frame_header(&mut BufReader::new(&frame[2..]), sync) { // Get the last header to check monotonicity in the strict header check. let last_header = self.builder.last_header(); // Perform a strict header check. if strict_frame_header_check(&self.info, &header, last_header) { // Rewind the reader such that the next read will start on the sync // word of the frame header. reader.seek_buffered_rev(end - size); break 'found size; } } } // Continue scanning one byte after the false-positive preamble. pos += offset + 1; } // If enough data has been read such even a FLAC frame of the maximum size should've // been fully read, and the header for the next frame found, then synchronization has // been lost. if end >= FLAC_MAX_FRAME_SIZE + FLAC_MAX_FRAME_HEADER_SIZE { return Ok(None); } // Calculate the required buffer size after reading a new 1kB chunk of data, and grow // the buffer if necessary. let next_read_end = end + 1024; if next_read_end > buf.len() { buf.resize(next_read_end, 0); } // After reading a new chunk of data, reconsider up-to 16 bytes (the maximum FLAC frame // header size) of old data such that if a frame header was partially read in the last // iteration it will be considered again in the next iteration. pos = end.saturating_sub(FLAC_MAX_FRAME_HEADER_SIZE); // Read the new chunk. end += match reader.read_buf(&mut buf[end..next_read_end]) { Ok(read) => read, Err(_) => break 'found end, } }; // trace!( // "read fragment: len={: >5}, avg_frame_size={: >5}, init_read_size={: >5}, discard={: >5}", // size, // avg_frame_size, // init_read_size, // end - size // ); // Truncate the buffer at the start of the new frame header. buf.truncate(size); Ok(Some(Fragment::new(buf.into_boxed_slice()))) } /// Reads a fragment using the reader and performs resynchronization when necessary. fn read_fragment(&mut self, reader: &mut B, avg_frame_size: usize) -> Result where B: ReadBytes + SeekBuffered, { loop { if let Some(fragment) = self.try_read_fragment(reader, avg_frame_size)? { return Ok(fragment); } // If a fragment could not be read, synchronization was lost. Try to resync. warn!("synchronization lost"); let _ = self.resync(reader)?; } } /// Parse the next packet from the stream. pub fn parse(&mut self, reader: &mut B) -> Result where B: ReadBytes + SeekBuffered, { let avg_frame_size = self.fsma.average(); // Update the packet builder with the latest average frame size. self.builder.set_avg_frame_size(Some(avg_frame_size)); // Build a packet. let parsed = loop { let fragment = self.read_fragment(reader, avg_frame_size)?; if let Some(packet) = self.builder.try_build(&self.info, fragment) { break packet; } }; // Update the frame size moving average. self.fsma.push(parsed.buf.len()); Ok(Packet::new_from_boxed_slice(0, parsed.sync.ts, parsed.sync.dur, parsed.buf)) } /// Resync the reader to the start of the next frame. pub fn resync(&mut self, reader: &mut B) -> Result where B: ReadBytes + SeekBuffered, { let init_pos = reader.pos(); let mut byte_offset; let header = loop { let sync = sync_frame(reader)?; byte_offset = reader.pos() - 2; if let Ok(header) = read_frame_header(reader, sync) { // Do a strict frame header check with no previous header. if strict_frame_header_check(&self.info, &header, None) { break header; } } }; let sync = calc_sync_info(&self.info, &header); // Rewind reader back to the start of the frame. reader.seek_buffered_rev((reader.pos() - byte_offset) as usize); // If the reader was moved, soft reset the parser. if init_pos != reader.pos() { self.soft_reset(); } Ok(sync) } /// Reset the packet parser for a new stream. pub fn reset(&mut self, info: StreamInfo) { let max_frame_size = if info.frame_byte_len_max > 0 { Some(info.frame_byte_len_max as usize) } else { None }; self.info = info; self.builder.set_max_frame_size(max_frame_size); self.soft_reset(); } } fn calc_sync_info(stream_info: &StreamInfo, header: &FrameHeader) -> SyncInfo { let is_fixed = stream_info.block_len_max == stream_info.block_len_min; let dur = u64::from(header.block_num_samples); let ts = match header.block_sequence { BlockSequence::BySample(sample) => sample, BlockSequence::ByFrame(frame) if is_fixed => { u64::from(frame) * u64::from(stream_info.block_len_min) } BlockSequence::ByFrame(frame) => { // This should not happen in practice. warn!("got a fixed size frame for a variable stream, the timestamp may be off"); u64::from(frame) * dur } }; SyncInfo { ts, dur } } fn strict_frame_header_check( stream_info: &StreamInfo, header: &FrameHeader, last_header: Option<&FrameHeader>, ) -> bool { // Sample rate is fixed for the stream. if let Some(sample_rate) = header.sample_rate { if sample_rate != stream_info.sample_rate { return false; } } // Bits per sample is fixed for the stream. if let Some(bps) = header.bits_per_sample { if bps != stream_info.bits_per_sample { return false; } } let is_fixed = stream_info.block_len_min == stream_info.block_len_max; // All blocks should have a block length within the stated bounds. However, the last block may // be shorter than the minimum. if header.block_num_samples > stream_info.block_len_max { return false; } // Get the last sequence number (frame or sample number). let last_seq = match last_header { Some(header) => match header.block_sequence { BlockSequence::BySample(sample) => sample, BlockSequence::ByFrame(frame) => u64::from(frame), }, _ => 0, }; // Sequence scoring: The fragment's blocking strategy is consistent with the stream // information block, and the sequence number (frame number or sample number) is // monotonic given the current state. let is_monotonic = match header.block_sequence { BlockSequence::BySample(sample) => !is_fixed && (sample > last_seq || sample == 0), BlockSequence::ByFrame(frame) => is_fixed && (u64::from(frame) > last_seq || frame == 0), }; if !is_monotonic { return false; } // Channel assignments. let num_frame_channels = match header.channel_assignment { ChannelAssignment::Independant(num) => num, ChannelAssignment::LeftSide => 2, ChannelAssignment::MidSide => 2, ChannelAssignment::RightSide => 2, }; if num_frame_channels != stream_info.channels.count() as u32 { return false; } true } #[inline(always)] fn may_contain_sync_preamble(buf: &[u8]) -> bool { let mut win = [0u8; 8]; win.copy_from_slice(&buf[..8]); // If, within the current 8 byte window, no single byte is 0xff then there cannot be a // frame synchronization preamble present. bits::contains_ones_byte_u64(u64::from_ne_bytes(win)) } /// Scan for frame synchronization premable, and if one is found, return the position of it in /// buf. fn scan_for_sync_preamble(buf: &[u8]) -> Option<(usize, u16)> { for (p, chunk) in buf.chunks_exact(8).enumerate() { // If there is no possibility of a preamble in this chunk (no 0xff byte), then skip to the // next chunk. if !may_contain_sync_preamble(chunk) { continue; } // Otherwise, there *may* be a frame synchronization preamble in this chunk, or partially in // this chunk. let mut sync = 0u16; // Starting from the beginning of this chunk, read up-to 9 bytes to find the synchronization // preamble. 9 bytes must be read to ensure that if the premable started on the last byte // of a chunk, then it will be found. for (i, byte) in buf[8 * p..].iter().take(8 + 1).enumerate() { sync = (sync << 8) | u16::from(*byte); if (sync & 0xfffc) == 0xfff8 { let offset = (8 * p) + i - 1; return Some((offset, sync)); } } } // No preamble found. None } symphonia-bundle-flac-0.5.2/src/validate.rs000075500000000000000000000101151046102023000167400ustar 00000000000000// 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::mem; use std::vec::Vec; use symphonia_core::audio::{AudioBuffer, Signal}; use symphonia_core::checksum::Md5; use symphonia_core::io::Monitor; /// `Validator` computes the MD5 checksum of an audio stream taking into account the peculiarities /// of FLAC's MD5 validation scheme. #[derive(Default)] pub struct Validator { state: Md5, buf: Vec, } impl Validator { /// Processes the audio buffer and updates the state of the validator. pub fn update(&mut self, buf: &AudioBuffer, bps: u32) { // The MD5 checksum is calculated on a buffer containing interleaved audio samples of the // correct sample width. While FLAC can encode and decode samples of arbitrary bit widths, // the samples in the buffer must be a multiple of 8-bits. // // Additionally, Symphonia's AudioBuffer's are in planar format, and the FLAC decoder works // internally on signed 32-bit samples exclusively. // // Therefore, to compute the checksum, the audio buffer samples must truncated to the // correct bit-width, interlaced, and converted to a little-endian byte buffer. The byte // buffer can then be passed to the MD5 algorithm for hashing. // Round the sample bit width up to the nearest byte. let bytes_per_sample = match bps { 0 => return, 1..=8 => 1, 9..=16 => 2, 17..=24 => 3, 25..=32 => 4, _ => unreachable!(), }; let n_channels = buf.spec().channels.count(); let n_frames = buf.frames(); // Calculate the total size of all the samples in bytes. let buf_len = n_channels * n_frames * bytes_per_sample; // Ensure the byte buffer length can accomodate all the samples. if self.buf.len() < buf_len { self.buf.resize(buf_len, 0u8); } // Populate the hash buffer with samples truncated to the correct width. A &[u8] slice of // all the samples in hash buffer will be returned. let buf_slice = match bytes_per_sample { 1 => copy_as_i8(buf, &mut self.buf, n_channels, n_frames), 2 => copy_as_i16(buf, &mut self.buf, n_channels, n_frames), 3 => copy_as_i24(buf, &mut self.buf, n_channels, n_frames), 4 => copy_as_i32(buf, &mut self.buf, n_channels, n_frames), _ => unreachable!(), }; // Update the MD5 state. self.state.process_buf_bytes(buf_slice); } /// Get the checksum. pub fn md5(&mut self) -> [u8; 16] { self.state.md5() } } fn copy_as_i24<'a>( samples: &AudioBuffer, buf: &'a mut [u8], n_channels: usize, n_frames: usize, ) -> &'a [u8] { const SIZE_OF_I24: usize = 24 / 8; for ch in 0..n_channels { for (out, sample) in buf.chunks_exact_mut(SIZE_OF_I24).skip(ch).step_by(n_channels).zip(samples.chan(ch)) { out.copy_from_slice(&sample.to_le_bytes()[0..SIZE_OF_I24]); } } &buf[..n_channels * n_frames * SIZE_OF_I24] } macro_rules! copy_as { ($name:ident, $type:ty) => { fn $name<'a>( samples: &AudioBuffer, buf: &'a mut [u8], n_channels: usize, n_frames: usize, ) -> &'a [u8] { for ch in 0..n_channels { for (out, sample) in buf .chunks_exact_mut(mem::size_of::<$type>()) .skip(ch) .step_by(n_channels) .zip(samples.chan(ch)) { out.copy_from_slice(&(*sample as $type).to_le_bytes()); } } &buf[..n_channels * n_frames * mem::size_of::<$type>()] } }; } copy_as!(copy_as_i8, i8); copy_as!(copy_as_i16, i16); copy_as!(copy_as_i32, i32);