symphonia-bundle-flac-0.5.4/.cargo_vcs_info.json0000644000000001630000000000100152230ustar { "git": { "sha1": "d3b7742fa73674b70d9ab80cc5f8384cc653df3a" }, "path_in_vcs": "symphonia-bundle-flac" }symphonia-bundle-flac-0.5.4/Cargo.toml0000644000000022610000000000100132220ustar # 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.4" 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.4" [dependencies.symphonia-metadata] version = "0.5.4" [dependencies.symphonia-utils-xiph] version = "0.5.4" symphonia-bundle-flac-0.5.4/Cargo.toml.orig000064400000000000000000000013631046102023000167050ustar 00000000000000[package] name = "symphonia-bundle-flac" version = "0.5.4" 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.4", path = "../symphonia-core" } symphonia-metadata = { version = "0.5.4", path = "../symphonia-metadata" } symphonia-utils-xiph = { version = "0.5.4", path = "../symphonia-utils-xiph" }symphonia-bundle-flac-0.5.4/README.md000064400000000000000000000020001046102023000152620ustar 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 a free and open-source project that welcomes contributions! To get started, please read our [Contribution Guidelines](https://github.com/pdeljanov/Symphonia/tree/master/CONTRIBUTING.md). symphonia-bundle-flac-0.5.4/src/decoder.rs000064400000000000000000000642011046102023000165600ustar 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::convert::TryInto; 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 (1-16). 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 { let mut qlp_coeffs = [0i32; 32]; for c in qlp_coeffs.iter_mut().rev().take(order as usize) { *c = sign_extend_leq32_to_i32(bs.read_bits_leq32(qlp_precision)?, qlp_precision); } decode_residual(bs, order, buf)?; // Helper function to dispatch to a predictor with a maximum order of N. #[inline(always)] fn lpc(order: u32, coeffs: &[i32; 32], coeff_shift: i32, buf: &mut [i32]) { let coeffs_n = (&coeffs[32 - N..32]).try_into().unwrap(); lpc_predict::(order as usize, coeffs_n, coeff_shift as u32, buf); } // Pick the best length linear predictor to use based on the order. Most FLAC streams use // the subset format and have an order <= 12. Therefore, for orders <= 12, dispatch to // predictors that roughly match the order. If a predictor is too long for a given order, // then there will be wasted computations. On the other hand, it is not worth the code bloat // to specialize for every order <= 12. match order { 0..=4 => lpc::<4>(order, &qlp_coeffs, qlp_coeff_shift, buf), 5..=6 => lpc::<6>(order, &qlp_coeffs, qlp_coeff_shift, buf), 7..=8 => lpc::<8>(order, &qlp_coeffs, qlp_coeff_shift, buf), 9..=10 => lpc::<10>(order, &qlp_coeffs, qlp_coeff_shift, buf), 11..=12 => lpc::<12>(order, &qlp_coeffs, qlp_coeff_shift, buf), _ => lpc::<32>(order, &qlp_coeffs, qlp_coeff_shift, 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 partitions 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]) { 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!(), }; } /// Generalized Linear Predictive Coding (LPC) decoder. 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 indices less than 31 - `order` must be 0. /// It is expected that the first `order` samples in `buf` are warm-up samples. fn lpc_predict(order: usize, coeffs: &[i32; N], coeff_shift: u32, buf: &mut [i32]) { // Order must be less than or equal to the number of coefficients. debug_assert!(order <= coeffs.len()); // Order must be less than to equal to the number of samples the buffer can hold. debug_assert!(order <= buf.len()); // The main, efficient, predictor loop needs N previous samples to run. Since order <= N, // calculate enough samples to reach N. let n_prefill = cmp::min(N, buf.len()) - order; for i in order..order + n_prefill { let predicted = coeffs[N - order..N] .iter() .zip(&buf[i - order..i]) .map(|(&c, &sample)| c as i64 * sample as i64) .sum::(); buf[i] += (predicted >> coeff_shift) as i32; } // If the pre-fill operation filled the entire sample buffer, return immediately. if buf.len() <= N { return; } // Main predictor loop. Calculate each sample by applying what is essentially an IIR filter. for i in N..buf.len() { let predicted = coeffs .iter() .zip(&buf[i - N..i]) .map(|(&c, &s)| i64::from(c) * i64::from(s)) .sum::(); buf[i] += (predicted >> coeff_shift) as i32; } } symphonia-bundle-flac-0.5.4/src/demuxer.rs000064400000000000000000000361021046102023000166230ustar 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 precedes 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.4/src/frame.rs000064400000000000000000000277731046102023000162620ustar 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.4/src/lib.rs000064400000000000000000000013121046102023000157130ustar 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.4/src/parser.rs000064400000000000000000000521261046102023000164520ustar 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 frame_pos; let header = loop { let sync = sync_frame(reader)?; frame_pos = 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; } } // If the header check failed, then seek to one byte past the start of the false frame // and continue trying to resynchronize. reader.seek_buffered(frame_pos + 1); }; let sync = calc_sync_info(&self.info, &header); // Rewind reader back to the start of the frame. reader.seek_buffered(frame_pos); // 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.4/src/validate.rs000064400000000000000000000101151046102023000167370ustar 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);