symphonia-codec-vorbis-0.5.2/.cargo_vcs_info.json0000644000000001640000000000100154250ustar { "git": { "sha1": "412f44daab39920beeb81d78b0e4271b263d33e9" }, "path_in_vcs": "symphonia-codec-vorbis" }symphonia-codec-vorbis-0.5.2/Cargo.toml0000644000000021650000000000100134260ustar # 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-codec-vorbis" version = "0.5.2" authors = ["Philip Deljanov "] description = "Pure Rust Vorbis decoder (a part of project Symphonia)." homepage = "https://github.com/pdeljanov/Symphonia" readme = "README.md" keywords = [ "audio", "codec", "decoder", "vorbis", ] 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-utils-xiph] version = "0.5.2" symphonia-codec-vorbis-0.5.2/Cargo.toml.orig000064400000000000000000000012411046102023000171010ustar 00000000000000[package] name = "symphonia-codec-vorbis" version = "0.5.2" description = "Pure Rust Vorbis 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", "vorbis"] edition = "2018" rust-version = "1.53" [dependencies] log = "0.4" symphonia-core = { version = "0.5.2", path = "../symphonia-core" } symphonia-utils-xiph = { version = "0.5.2", path = "../symphonia-utils-xiph" }symphonia-codec-vorbis-0.5.2/README.md000064400000000000000000000013701046102023000154740ustar 00000000000000# Symphonia Vorbis Codec [![Docs](https://docs.rs/symphonia-codec-vorbis/badge.svg)](https://docs.rs/symphonia-codec-vorbis) Vorbis 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. ## 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-codec-vorbis-0.5.2/src/codebook.rs000075500000000000000000000361041046102023000171450ustar 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::usize; use symphonia_core::errors::{decode_error, Result}; use symphonia_core::io::{ vlc::{BitOrder, Codebook, CodebookBuilder, Entry32x32}, ReadBitsRtl, }; use super::common::*; /// As defined in section 9.2.2 of the Vorbis I specification. /// /// `float32_unpack` is intended to translate the packed binary representation of a Vorbis /// codebook float value into the representation used by the decoder for floating point numbers. #[inline(always)] fn float32_unpack(x: u32) -> f32 { let mantissa = x & 0x1fffff; let sign = x & 0x80000000; let exponent = (x & 0x7fe00000) >> 21; let value = (mantissa as f32) * 2.0f32.powi(exponent as i32 - 788); if sign == 0 { value } else { -value } } /// As defined in section 9.2.3 of the Vorbis I specification. /// /// The return value for this function is defined to be ’the greatest integer value for which the /// return value to the power of `dimensions` is less than or equal to `entries`. #[inline(always)] fn lookup1_values(entries: u32, dimensions: u16) -> u32 { // (value ^ dimensions) <= entries // [(value ^ dimensions) ^ (1 / dimensions)] = lower[entries ^ (1 / dimensions)] // value = lower[entries ^ (1 / dimensions)] let value = (entries as f32).powf(1.0f32 / f32::from(dimensions)).floor() as u32; assert!(value.pow(u32::from(dimensions)) <= entries); assert!((value + 1).pow(u32::from(dimensions)) > entries); value } /// As defined in section 3.2.1 of the Vorbis I specification. fn unpack_vq_lookup_type1( multiplicands: &[u16], min_value: f32, delta_value: f32, sequence_p: bool, codebook_entries: u32, codebook_dimensions: u16, lookup_values: u32, ) -> Vec { let mut vq_lookup = vec![0.0; codebook_entries as usize * codebook_dimensions as usize]; for (v, value_vector) in vq_lookup.chunks_exact_mut(codebook_dimensions as usize).enumerate() { let lookup_offset = v as u32; let mut last = 0.0; let mut index_divisor = 1; for value in value_vector.iter_mut() { let multiplicand_offset = ((lookup_offset / index_divisor) % lookup_values) as usize; *value = f32::from(multiplicands[multiplicand_offset]) * delta_value + min_value + last; if sequence_p { last = *value; } index_divisor *= lookup_values; } } vq_lookup } /// As defined in section 3.2.1 of the Vorbis I specification. fn unpack_vq_lookup_type2( multiplicands: &[u16], min_value: f32, delta_value: f32, sequence_p: bool, codebook_entries: u32, codebook_dimensions: u16, ) -> Vec { let mut vq_lookup = vec![0.0; codebook_entries as usize * codebook_dimensions as usize]; for (lookup_offset, value_vector) in vq_lookup.chunks_exact_mut(codebook_dimensions as usize).enumerate() { let mut last = 0.0; let mut multiplicand_offset = lookup_offset * codebook_dimensions as usize; for value in value_vector.iter_mut() { *value = f32::from(multiplicands[multiplicand_offset]) * delta_value + min_value + last; if sequence_p { last = *value; } multiplicand_offset += 1; } } vq_lookup } fn synthesize_codewords(code_lens: &[u8]) -> Result> { // This codeword generation algorithm works by maintaining a table of the next valid codeword for // each codeword length. // // Consider a huffman tree. Each level of the tree correlates to a specific length of codeword. // For example, given a leaf node at level 2 of the huffman tree, that codeword would be 2 bits // long. Therefore, the table being maintained contains the codeword that would identify the next // available left-most node in the huffman tree at a given level. Therefore, this table can be // interrogated to get the next codeword in a simple lookup and the tree will fill-out in the // canonical order. // // Note however that, after selecting a codeword, C, of length N, all codewords of length > N // cannot use C as a prefix anymore. Therefore, all table entries for codeword lengths > N must // be updated such that these codewords are skipped over. Likewise, the table must be updated for // lengths < N to account for jumping between nodes. // // This algorithm is a modified version of the one found in the Vorbis reference implementation. let mut codewords = Vec::new(); let mut next_codeword = [0u32; 33]; let mut num_sparse = 0; for &len in code_lens.iter() { // This should always be true. debug_assert!(len <= 32); if len == 0 { num_sparse += 1; codewords.push(0); continue; } // The codeword length, N. let codeword_len = usize::from(len); // The selected codeword, C. let codeword = next_codeword[codeword_len]; if len < 32 && (codeword >> len) > 0 { return decode_error("vorbis: codebook overspecified"); } for i in (0..codeword_len + 1).rev() { // If the least significant bit (LSb) of the next codeword for codewords of length N // toggles from 1 to 0, that indicates the next-least-LSb will toggle. This means that // the next codeword will branch off a new parent node. Therefore, the next codeword for // codewords of length N will use the next codeword for codewords of length N-1 as its // prefix. if next_codeword[i] & 1 == 1 { next_codeword[i] = next_codeword[i - 1] << 1; break; } // Otherwise, simply increment the next codeword for codewords of length N by 1. Iterate // again since there is now 1 branch dangling off the parent node. The parent must now be // incremented updated in the same way. next_codeword[i] += 1; } // Given a codeword, C, of length N bits, the codeword is a leaf on the tree and cannot have // any branches. Otherwise, another codeword would have C as its prefix and that is not // allowed. Therefore, if the next codeword for codewords of length N+1 uses codeword C as a // prefix, then the next codeword for codewords of length N+1 must be modified to branch off // the next codeword of length N instead. Then this modification must be propagated down the // tree in a similar pattern. In this way, all next codewords for codewords of lengths > N // that would've used C as a prefix are skipped over and can't be selected regardless of the // length of the next codeword. let branch = next_codeword[codeword_len]; for (i, next) in next_codeword[codeword_len..].iter_mut().enumerate().skip(1) { // If the next codeword for this length of codewords is using the selected codeword, C, // as a prefix, move it to the next branch. if *next == codeword << i { *next = branch << i; } else { break; } } // Push the codeword. codewords.push(codeword); } // Check that the tree is fully specified and complete. This means that the next codeword for // codes of length 1 to 32, inclusive, are saturated. let is_underspecified = next_codeword.iter().enumerate().skip(1).any(|(i, &c)| c & (u32::MAX >> (32 - i)) != 0); // Single entry codebooks are technically invalid, but must be supported as a special-case // per Vorbis I specification, errate 20150226. let is_single_entry_codebook = code_lens.len() - num_sparse == 1; if is_underspecified && !is_single_entry_codebook { return decode_error("vorbis: codebook underspecified"); } Ok(codewords) } pub struct VorbisCodebook { codebook: Codebook, dimensions: u16, vq_vec: Option>, } impl VorbisCodebook { pub fn read(bs: &mut B) -> Result { // Verify codebook synchronization word. let sync = bs.read_bits_leq32(24)?; if sync != 0x564342 { return decode_error("vorbis: invalid codebook sync"); } // Read codebook number of dimensions and entries. let codebook_dimensions = bs.read_bits_leq32(16)? as u16; let codebook_entries = bs.read_bits_leq32(24)?; // Ordered flag. let is_length_ordered = bs.read_bool()?; let mut code_lens = Vec::::with_capacity(codebook_entries as usize); if !is_length_ordered { // Codeword list is not length ordered. let is_sparse = bs.read_bool()?; if is_sparse { // Sparsely packed codeword entry list. for _ in 0..codebook_entries { let is_used = bs.read_bool()?; let code_len = if is_used { // Entry is used. bs.read_bits_leq32(5)? as u8 + 1 } else { // Unused entries have a length of 0. 0 }; code_lens.push(code_len); } } else { // Densely packed codeword entry list. for _ in 0..codebook_entries { let code_len = bs.read_bits_leq32(5)? as u8 + 1; code_lens.push(code_len) } } } else { // Codeword list is length ordered. let mut cur_entry = 0; let mut cur_len = bs.read_bits_leq32(5)? + 1; loop { let num_bits = if codebook_entries > cur_entry { ilog(codebook_entries - cur_entry) } else { 0 }; let num = bs.read_bits_leq32(num_bits)?; code_lens.extend(std::iter::repeat(cur_len as u8).take(num as usize)); cur_len += 1; cur_entry += num; if cur_entry > codebook_entries { return decode_error("vorbis: invalid codebook"); } if cur_entry == codebook_entries { break; } } } // Read and unpack vector quantization (VQ) lookup table. let lookup_type = bs.read_bits_leq32(4)?; let vq_vec = match lookup_type & 0xf { 0 => None, 1 | 2 => { let min_value = float32_unpack(bs.read_bits_leq32(32)?); let delta_value = float32_unpack(bs.read_bits_leq32(32)?); let value_bits = bs.read_bits_leq32(4)? + 1; let sequence_p = bs.read_bool()?; // Lookup type is either 1 or 2 as per outer match. let lookup_values = match lookup_type { 1 => lookup1_values(codebook_entries, codebook_dimensions), 2 => codebook_entries * u32::from(codebook_dimensions), _ => unreachable!(), }; let mut multiplicands = Vec::::new(); for _ in 0..lookup_values { multiplicands.push(bs.read_bits_leq32(value_bits)? as u16); } let vq_lookup = match lookup_type { 1 => unpack_vq_lookup_type1( &multiplicands, min_value, delta_value, sequence_p, codebook_entries, codebook_dimensions, lookup_values, ), 2 => unpack_vq_lookup_type2( &multiplicands, min_value, delta_value, sequence_p, codebook_entries, codebook_dimensions, ), _ => unreachable!(), }; Some(vq_lookup) } _ => return decode_error("vorbis: invalid codeword lookup type"), }; // Generate a canonical list of codewords given the set of codeword lengths. let code_words = synthesize_codewords(&code_lens)?; // Generate the values associated for each codeword. // TODO: Should unused entries be 0 or actually the correct value? let values: Vec = (0..codebook_entries).into_iter().collect(); // Finally, generate the codebook with a reverse (LSb) bit order. let mut builder = CodebookBuilder::new_sparse(BitOrder::Reverse); // Read in 8-bit blocks. builder.bits_per_read(8); let codebook = builder.make::(&code_words, &code_lens, &values)?; Ok(VorbisCodebook { codebook, dimensions: codebook_dimensions, vq_vec }) } #[inline(always)] pub fn read_scalar(&self, bs: &mut B) -> Result { // An entry in a scalar codebook is just the value. Ok(bs.read_codebook(&self.codebook)?.0) } #[inline(always)] pub fn read_vq(&self, bs: &mut B) -> Result<&[f32]> { // An entry in a VQ codebook is the index of the VQ vector. let entry = bs.read_codebook(&self.codebook)?.0; if let Some(vq) = &self.vq_vec { let dim = self.dimensions as usize; let start = dim * entry as usize; Ok(&vq[start..start + dim]) } else { decode_error("vorbis: not a vq codebook") } } #[inline(always)] pub fn dimensions(&self) -> u16 { self.dimensions } } #[cfg(test)] mod tests { use super::{ilog, lookup1_values, synthesize_codewords}; #[test] fn verify_ilog() { assert_eq!(ilog(0), 0); assert_eq!(ilog(1), 1); assert_eq!(ilog(2), 2); assert_eq!(ilog(3), 2); assert_eq!(ilog(4), 3); assert_eq!(ilog(7), 3); } fn naive_lookup1_values(entries: u32, dimensions: u16) -> u32 { let mut x = 1u32; loop { let xpow = x.pow(u32::from(dimensions)); if xpow > entries { break; } x += 1; } x - 1 } #[test] fn verify_lookup1_values() { assert_eq!(lookup1_values(1, 1), naive_lookup1_values(1, 1)); assert_eq!(lookup1_values(361, 2), naive_lookup1_values(361, 2)); } #[test] fn verify_synthesize_codewords() { const CODEWORD_LENGTHS: &[u8] = &[2, 4, 4, 4, 4, 2, 3, 3]; const EXPECTED_CODEWORDS: &[u32] = &[0, 0x4, 0x5, 0x6, 0x7, 0x2, 0x6, 0x7]; let codewords = synthesize_codewords(CODEWORD_LENGTHS).unwrap(); assert_eq!(&codewords, EXPECTED_CODEWORDS); } } symphonia-codec-vorbis-0.5.2/src/common.rs000064400000000000000000000101771046102023000166470ustar 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/. /// As defined in section 9.2.1 of the Vorbis I specification. /// /// The `ilog` function returns the position number (1 through n) of the highest set bit in the two’s /// complement integer value `x`. #[inline(always)] pub fn ilog(x: u32) -> u32 { 32 - x.leading_zeros() } pub struct BitSetIterator<'a> { bits: &'a [u32], pos: usize, count: usize, } impl<'a> Iterator for BitSetIterator<'a> { type Item = usize; fn next(&mut self) -> Option { if self.count == 0 { return None; } for bits in &self.bits[self.pos >> 5..] { let bits_read = self.pos & 0x1f; let offset = (bits >> bits_read).trailing_zeros() as usize; if offset < 32 - bits_read { self.pos += offset + 1; self.count -= 1; return Some(self.pos - 1); } else { self.pos += 32 - bits_read; } } None } } // TODO: When const generics allow division, switch to that. macro_rules! decl_bitset { ($name:ident, $size:expr) => { #[derive(Default)] pub struct $name { bits: [u32; $size >> 5], bit_count: usize, } impl $name { #[inline(always)] pub fn set(&mut self, idx: usize) { if !self.is_set(idx) { self.bits[idx >> 5] |= 1 << (idx & 0x1f); self.bit_count += 1; } } // #[inline(always)] // pub fn unset(&mut self, idx: usize) { // if self.is_set(idx) { // self.bits[idx >> 5] &= !(1 << (idx & 0x1f)); // self.bit_count -= 1; // } // } #[inline(always)] pub fn is_set(&self, idx: usize) -> bool { self.bits[idx >> 5] & (1 << (idx & 0x1f)) != 0 } #[inline(always)] pub fn count(&self) -> usize { self.bit_count } #[inline(always)] pub fn iter(&self) -> BitSetIterator<'_> { BitSetIterator { bits: &self.bits, pos: 0, count: self.bit_count } } } }; } decl_bitset!(BitSet256, 256); #[cfg(test)] mod tests { use super::BitSet256; #[test] fn verify_bitset_count() { let mut bitset: BitSet256 = Default::default(); bitset.set(1); bitset.set(2); bitset.set(56); bitset.set(64); bitset.set(127); bitset.set(128); bitset.set(250); bitset.set(251); bitset.set(252); bitset.set(253); bitset.set(254); bitset.set(255); assert_eq!(bitset.count(), 12); } #[test] fn verify_bitset_iter() { let mut bitset: BitSet256 = Default::default(); assert_eq!(bitset.count(), 0); for _ in bitset.iter() { panic!("Should be empty!"); } bitset.set(1); bitset.set(2); bitset.set(56); bitset.set(64); bitset.set(127); bitset.set(128); bitset.set(250); bitset.set(251); bitset.set(252); bitset.set(253); bitset.set(254); bitset.set(255); let mut iter = bitset.iter(); assert_eq!(iter.next(), Some(1)); assert_eq!(iter.next(), Some(2)); assert_eq!(iter.next(), Some(56)); assert_eq!(iter.next(), Some(64)); assert_eq!(iter.next(), Some(127)); assert_eq!(iter.next(), Some(128)); assert_eq!(iter.next(), Some(250)); assert_eq!(iter.next(), Some(251)); assert_eq!(iter.next(), Some(252)); assert_eq!(iter.next(), Some(253)); assert_eq!(iter.next(), Some(254)); assert_eq!(iter.next(), Some(255)); assert_eq!(iter.next(), None); } } symphonia-codec-vorbis-0.5.2/src/dsp.rs000064400000000000000000000114251046102023000161420ustar 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::dsp::mdct::Imdct; use super::window::Windows; pub struct LappingState { pub prev_block_flag: bool, } pub struct Dsp { /// DSP channels (max. 256 per-spec, but actually limited to 32 by Symphonia). pub channels: Vec, /// IMDCT for short-blocks. pub imdct_short: Imdct, /// IMDCT for long-blocks. pub imdct_long: Imdct, /// Windows for overlap-add. pub windows: Windows, /// Lapping state. pub lapping_state: Option, } impl Dsp { pub fn reset(&mut self) { for channel in &mut self.channels { channel.reset(); } self.lapping_state = None; } } pub struct DspChannel { /// The channel floor buffer. pub floor: Vec, /// The channel residue buffer. pub residue: Vec, /// Do not decode! pub do_not_decode: bool, /// The output buffer for the IMDCT. imdct: Vec, /// Samples saved from the last IMDCT for overlap-add. overlap: Vec, /// Short block size. bs0: usize, /// Long block size. bs1: usize, } impl DspChannel { pub fn new(bs0_exp: u8, bs1_exp: u8) -> Self { let bs0 = 1 << bs0_exp; let bs1 = 1 << bs1_exp; DspChannel { floor: vec![0.0; bs1 >> 1], residue: vec![0.0; bs1 >> 1], imdct: vec![0.0; bs1], overlap: vec![0.0; bs1 >> 1], do_not_decode: false, bs0, bs1, } } pub fn synth( &mut self, block_flag: bool, lap_state: &Option, windows: &Windows, imdct: &mut Imdct, buf: &mut [f32], ) { // Block size of the current block. let bs = if block_flag { self.bs1 } else { self.bs0 }; // Perform the inverse MDCT on the audio spectrum. imdct.imdct(&self.floor[..bs / 2], &mut self.imdct[..bs]); // Overlap-add and windowing with the previous buffer. if let Some(lap_state) = &lap_state { // Window for this block. let win = if block_flag && lap_state.prev_block_flag { &windows.long } else { &windows.short }; if lap_state.prev_block_flag == block_flag { // Both the previous and current blocks are either short or long. In this case, // there is a complete overlap between. overlap_add(buf, &self.overlap[..bs / 2], &self.imdct[..bs / 2], win); } else if lap_state.prev_block_flag && !block_flag { // The previous block is long and the current block is short. let start = (self.bs1 - self.bs0) / 4; let end = start + self.bs0 / 2; // Unity samples (no overlap). buf[..start].copy_from_slice(&self.overlap[..start]); // Overlapping samples. overlap_add( &mut buf[start..], &self.overlap[start..end], &self.imdct[..self.bs0 / 2], win, ); } else { // The previous block is short and the current block is long. let start = (self.bs1 - self.bs0) / 4; let end = start + self.bs0 / 2; // Overlapping samples. overlap_add( &mut buf[..self.bs0 / 2], &self.overlap[..self.bs0 / 2], &self.imdct[start..end], win, ); // Unity samples (no overlap). buf[self.bs0 / 2..].copy_from_slice(&self.imdct[end..self.bs1 / 2]); } // Clamp the output samples. for s in buf.iter_mut() { *s = s.clamp(-1.0, 1.0); } } // Save right-half of IMDCT buffer for later. self.overlap[..bs / 2].copy_from_slice(&self.imdct[bs / 2..bs]); } pub fn reset(&mut self) { // Clear the overlap buffer. Nothing else is used across packets. self.overlap.fill(0.0); } } #[inline(always)] fn overlap_add(out: &mut [f32], left: &[f32], right: &[f32], win: &[f32]) { assert!(left.len() == right.len()); assert!(left.len() == win.len()); assert!(left.len() == out.len()); let iter = left.iter().zip(right).zip(win.iter().rev()).zip(win).zip(out); for ((((&s0, &s1), &w0), &w1), out) in iter { *out = s0 * w0 + s1 * w1; } } symphonia-codec-vorbis-0.5.2/src/floor.rs000064400000000000000000000670171046102023000165050ustar 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::min; use std::collections::HashSet; use symphonia_core::errors::{decode_error, Error, Result}; use symphonia_core::io::{BitReaderRtl, ReadBitsRtl}; use super::codebook::VorbisCodebook; use super::common::*; /// As defined in section 10.1 of the Vorbis I specification. #[allow(clippy::unreadable_literal)] #[allow(clippy::excessive_precision)] #[rustfmt::skip] const FLOOR1_INVERSE_DB_TABLE: [f32; 256] = [ 1.0649863e-07, 1.1341951e-07, 1.2079015e-07, 1.2863978e-07, 1.3699951e-07, 1.4590251e-07, 1.5538408e-07, 1.6548181e-07, 1.7623575e-07, 1.8768855e-07, 1.9988561e-07, 2.1287530e-07, 2.2670913e-07, 2.4144197e-07, 2.5713223e-07, 2.7384213e-07, 2.9163793e-07, 3.1059021e-07, 3.3077411e-07, 3.5226968e-07, 3.7516214e-07, 3.9954229e-07, 4.2550680e-07, 4.5315863e-07, 4.8260743e-07, 5.1396998e-07, 5.4737065e-07, 5.8294187e-07, 6.2082472e-07, 6.6116941e-07, 7.0413592e-07, 7.4989464e-07, 7.9862701e-07, 8.5052630e-07, 9.0579828e-07, 9.6466216e-07, 1.0273513e-06, 1.0941144e-06, 1.1652161e-06, 1.2409384e-06, 1.3215816e-06, 1.4074654e-06, 1.4989305e-06, 1.5963394e-06, 1.7000785e-06, 1.8105592e-06, 1.9282195e-06, 2.0535261e-06, 2.1869758e-06, 2.3290978e-06, 2.4804557e-06, 2.6416497e-06, 2.8133190e-06, 2.9961443e-06, 3.1908506e-06, 3.3982101e-06, 3.6190449e-06, 3.8542308e-06, 4.1047004e-06, 4.3714470e-06, 4.6555282e-06, 4.9580707e-06, 5.2802740e-06, 5.6234160e-06, 5.9888572e-06, 6.3780469e-06, 6.7925283e-06, 7.2339451e-06, 7.7040476e-06, 8.2047000e-06, 8.7378876e-06, 9.3057248e-06, 9.9104632e-06, 1.0554501e-05, 1.1240392e-05, 1.1970856e-05, 1.2748789e-05, 1.3577278e-05, 1.4459606e-05, 1.5399272e-05, 1.6400004e-05, 1.7465768e-05, 1.8600792e-05, 1.9809576e-05, 2.1096914e-05, 2.2467911e-05, 2.3928002e-05, 2.5482978e-05, 2.7139006e-05, 2.8902651e-05, 3.0780908e-05, 3.2781225e-05, 3.4911534e-05, 3.7180282e-05, 3.9596466e-05, 4.2169667e-05, 4.4910090e-05, 4.7828601e-05, 5.0936773e-05, 5.4246931e-05, 5.7772202e-05, 6.1526565e-05, 6.5524908e-05, 6.9783085e-05, 7.4317983e-05, 7.9147585e-05, 8.4291040e-05, 8.9768747e-05, 9.5602426e-05, 0.00010181521, 0.00010843174, 0.00011547824, 0.00012298267, 0.00013097477, 0.00013948625, 0.00014855085, 0.00015820453, 0.00016848555, 0.00017943469, 0.00019109536, 0.00020351382, 0.00021673929, 0.00023082423, 0.00024582449, 0.00026179955, 0.00027881276, 0.00029693158, 0.00031622787, 0.00033677814, 0.00035866388, 0.00038197188, 0.00040679456, 0.00043323036, 0.00046138411, 0.00049136745, 0.00052329927, 0.00055730621, 0.00059352311, 0.00063209358, 0.00067317058, 0.00071691700, 0.00076350630, 0.00081312324, 0.00086596457, 0.00092223983, 0.00098217216, 0.0010459992, 0.0011139742, 0.0011863665, 0.0012634633, 0.0013455702, 0.0014330129, 0.0015261382, 0.0016253153, 0.0017309374, 0.0018434235, 0.0019632195, 0.0020908006, 0.0022266726, 0.0023713743, 0.0025254795, 0.0026895994, 0.0028643847, 0.0030505286, 0.0032487691, 0.0034598925, 0.0036847358, 0.0039241906, 0.0041792066, 0.0044507950, 0.0047400328, 0.0050480668, 0.0053761186, 0.0057254891, 0.0060975636, 0.0064938176, 0.0069158225, 0.0073652516, 0.0078438871, 0.0083536271, 0.0088964928, 0.009474637, 0.010090352, 0.010746080, 0.011444421, 0.012188144, 0.012980198, 0.013823725, 0.014722068, 0.015678791, 0.016697687, 0.017782797, 0.018938423, 0.020169149, 0.021479854, 0.022875735, 0.024362330, 0.025945531, 0.027631618, 0.029427276, 0.031339626, 0.033376252, 0.035545228, 0.037855157, 0.040315199, 0.042935108, 0.045725273, 0.048696758, 0.051861348, 0.055231591, 0.058820850, 0.062643361, 0.066714279, 0.071049749, 0.075666962, 0.080584227, 0.085821044, 0.091398179, 0.097337747, 0.10366330, 0.11039993, 0.11757434, 0.12521498, 0.13335215, 0.14201813, 0.15124727, 0.16107617, 0.17154380, 0.18269168, 0.19456402, 0.20720788, 0.22067342, 0.23501402, 0.25028656, 0.26655159, 0.28387361, 0.30232132, 0.32196786, 0.34289114, 0.36517414, 0.38890521, 0.41417847, 0.44109412, 0.46975890, 0.50028648, 0.53279791, 0.56742212, 0.60429640, 0.64356699, 0.68538959, 0.72993007, 0.77736504, 0.82788260, 0.88168307, 0.9389798, 1.0, ]; macro_rules! io_try_or_ret { ($expr:expr) => { match $expr { Ok(val) => val, // An end-of-bitstream error is classified under ErrorKind::Other. This condition // should not be treated as an error, rather, it should return from the function // immediately without error. Err(ref e) if e.kind() == std::io::ErrorKind::Other => return Ok(()), Err(e) => return Err(e.into()), } }; } macro_rules! try_or_ret { ($expr:expr) => { match $expr { Ok(val) => val, // An end-of-bitstream error is classified under ErrorKind::Other. This condition // should not be treated as an error, rather, it should return from the function // immediately without error. Err(Error::IoError(ref e)) if e.kind() == std::io::ErrorKind::Other => return Ok(()), Err(e) => return Err(e), } }; } pub trait Floor: Send + Sync { fn read_channel( &mut self, bs: &mut BitReaderRtl<'_>, codebooks: &[VorbisCodebook], ) -> Result<()>; fn is_unused(&self) -> bool; fn synthesis(&mut self, bs_exp: u8, floor: &mut [f32]) -> Result<()>; } #[derive(Debug)] struct Floor0Setup { floor0_order: u8, floor0_bark_map_size: u16, floor0_amplitude_bits: u8, floor0_amplitude_offset: u8, floor0_number_of_books: u8, floor0_book_list: [u8; 16], // The block size of the short Bark map. floor0_map_short_bs_exp: u8, // Pre-computed Bark map for short blocks. floor0_map_short: Vec, // Pre-computed Bark map for long blocks. floor0_map_long: Vec, } #[derive(Debug)] pub struct Floor0 { setup: Floor0Setup, is_unused: bool, amplitude: u64, coeffs: [f32; 256], } impl Floor0 { pub fn try_read( bs: &mut BitReaderRtl<'_>, bs0_exp: u8, bs1_exp: u8, max_codebook: u8, ) -> Result> { let setup = Self::read_setup(bs, bs0_exp, bs1_exp, max_codebook)?; Ok(Box::new(Floor0 { setup, is_unused: false, amplitude: 0, coeffs: [0.0; 256] })) } fn read_setup( bs: &mut BitReaderRtl<'_>, bs0_exp: u8, bs1_exp: u8, max_codebook: u8, ) -> Result { let floor0_order = bs.read_bits_leq32(8)? as u8; let floor0_rate = bs.read_bits_leq32(16)? as u16; let floor0_bark_map_size = bs.read_bits_leq32(16)? as u16; let floor0_amplitude_bits = bs.read_bits_leq32(6)? as u8; let floor0_amplitude_offset = bs.read_bits_leq32(8)? as u8; let floor0_number_of_books = bs.read_bits_leq32(4)? as u8 + 1; let mut floor0_book_list = [0; 16]; let end = usize::from(floor0_number_of_books); for book in &mut floor0_book_list[..end] { *book = bs.read_bits_leq32(8)? as u8; if *book >= max_codebook { return decode_error("vorbis: floor0, invalid codebook number"); } } // Pre-compute the Bark-scale maps. let floor0_map_short = bark_map(1 << (bs0_exp - 1), floor0_rate, floor0_bark_map_size); let floor0_map_long = bark_map(1 << (bs1_exp - 1), floor0_rate, floor0_bark_map_size); let floor_type0 = Floor0Setup { floor0_order, floor0_bark_map_size, floor0_amplitude_bits, floor0_amplitude_offset, floor0_number_of_books, floor0_book_list, floor0_map_short_bs_exp: bs0_exp, floor0_map_short, floor0_map_long, }; Ok(floor_type0) } } impl Floor for Floor0 { fn read_channel( &mut self, bs: &mut BitReaderRtl<'_>, codebooks: &[VorbisCodebook], ) -> Result<()> { // Assume the floor is unused until it is decoded successfully. self.is_unused = true; self.amplitude = io_try_or_ret!(bs.read_bits_leq64(u32::from(self.setup.floor0_amplitude_bits))); if self.amplitude != 0 { // Read the index into the floor's codebook list that contains the actual codebook // index. let floor_book_idx_bits = ilog(u32::from(self.setup.floor0_number_of_books)); let floor_book_idx = io_try_or_ret!(bs.read_bits_leq32(floor_book_idx_bits)) as usize; // Get the actual codebook index from the floor's codebook list. let codebook_idx = self.setup.floor0_book_list[floor_book_idx] as usize; if codebook_idx >= codebooks.len() { return decode_error("vorbis: floor0, invalid codebook"); } // Get the codebook for this floor. let codebook = &codebooks[codebook_idx]; let order = usize::from(self.setup.floor0_order); let mut i = 0; let mut last = 0.0; while i < order { let i0 = i; // Read and obtain the VQ vector from the codebook. let vq = try_or_ret!(codebook.read_vq(bs)); // The VQ vector may be much larger (up-to 65535 scalars) than the remaining number // of coefficients (up-to 255 scalars). Cap the amount of coefficients to be // processed. i += min(order - i0, vq.len()); // Add the value of last coefficient from the previous iteration to each scalar // value read from the VQ vector and append those valeus to the coefficient vector. for (c, &vq) in self.coeffs[i0..i].iter_mut().zip(vq) { *c = last + vq; } // Store the value of the last coefficient in the coefficient vector for the next // iteration. last = self.coeffs[i - 1]; } // Pre-compute the 2 times the cosine of all coefficients. for coeff in self.coeffs[..order].iter_mut() { *coeff = 2.0 * coeff.cos(); } } // The floor is used if the amplitude is not 0. self.is_unused = self.amplitude == 0; Ok(()) } fn is_unused(&self) -> bool { self.is_unused } fn synthesis(&mut self, bs_exp: u8, floor: &mut [f32]) -> Result<()> { debug_assert!(!self.is_unused); // Block size. let n = (1 << bs_exp) >> 1; // Select the correct Bark-scale map based on the block-size exponent. let map = if bs_exp == self.setup.floor0_map_short_bs_exp { &self.setup.floor0_map_short } else { &self.setup.floor0_map_long }; let omega_step = std::f32::consts::PI / f32::from(self.setup.floor0_bark_map_size); let mut i = 0; loop { let iter_cond = map[i]; let omega = omega_step * iter_cond as f32; let cos_omega = omega.cos(); let two_cos_omega = 2.0 * cos_omega; let mut p = 1.0; let mut q = 1.0; let mut iter = self.coeffs[..usize::from(self.setup.floor0_order)].chunks_exact(2); // Calculate p using coefficients with odd indicies, and q using coefficients with even // indicies. for coeffs in &mut iter { p *= coeffs[1] - two_cos_omega; q *= coeffs[0] - two_cos_omega; } // If order is an odd number, then there should be exactly one extra coefficient. let last_coeff = iter.remainder(); if !last_coeff.is_empty() { q *= last_coeff[0] - two_cos_omega; p = p * p * (1.0 - (cos_omega * cos_omega)); q = q * q * 0.25; } else { p = p * p * ((1.0 - cos_omega) / 2.0); q = q * q * ((1.0 + cos_omega) / 2.0); } if p + q == 0.0 { return decode_error("vorbis: invalid floor0 coefficients"); } let linear_floor_value = linear_floor0_value( p, q, self.amplitude, self.setup.floor0_amplitude_bits, self.setup.floor0_amplitude_offset, ); // Fill in the floor values where the map value is the same. for (floor, &map) in floor[i..n].iter_mut().zip(&map[i..n]) { if map != iter_cond { break; } *floor = linear_floor_value; i += 1; } if i >= n { break; } } Ok(()) } } /// Vorbis I specification, section 6.2.3. #[inline(always)] fn bark(x: f64) -> f64 { (13.1 * (0.00074 * x).atan()) + (2.24 * (0.0000000185 * x * x).atan()) + (0.0001 * x) } fn bark_map(n: u32, floor0_rate: u16, floor0_bark_map_size: u16) -> Vec { let mut map = Vec::with_capacity(n as usize); let foobar_min = i32::from(floor0_bark_map_size) - 1; let rate = f64::from(floor0_rate); let rate_by_2n = rate / (2.0 * f64::from(n)); let c = f64::from(floor0_bark_map_size) / bark(0.5 * rate); // Compute 0 to N-1 elements. for i in 0..n { let foobar = (bark(rate_by_2n * f64::from(i)) * c).floor() as i32; map.push(foobar.min(foobar_min)); } map } /// Calculate the linear floor value as per Vorbis I specification, section 6.2.3. #[inline(always)] fn linear_floor0_value( p: f32, q: f32, amplitude: u64, amplitude_bits: u8, amplitude_offset: u8, ) -> f32 { // Amplitude could be up-to 63-bits, and amplitude offset 8-bits. Therefore, 71-bits is required // in total. This is unreasonable since even an f64 can't represent more than 56-bits. Since // large values like this shouldn't happen in practice, use wrapping arithmetic to prevent // panics and truncate to 32-bits in the f32 conversion. let a = amplitude.wrapping_mul(u64::from(amplitude_offset)) as f32; let b = (p + q).sqrt() * ((1u64 << amplitude_bits) - 1) as f32; (0.11512925 * ((a / b) - f32::from(amplitude_offset))).exp() } #[derive(Debug, Default)] struct Floor1Class { /// Main codebook index. mainbook: u8, /// Class dimensions. dimensions: u8, /// Number of sub-classes expressed as a power-of-2 exponent (2 ^ subclass_bits). subclass_bits: u8, /// Codebook index for each sub-class. subbooks: [u8; 8], /// Bitset marking if a sub-class codebook is used or not. is_subbook_used: u8, } #[derive(Debug)] struct Floor1Setup { /// Number of partitions, range limited to 0..32. floor1_partitions: usize, /// Class index (range limited to 0..16), associated with each partition. floor1_partition_class_list: [u8; 32], /// Classes. floor1_classes: [Floor1Class; 16], /// Floor multiplier, range limited to 1..5. floor1_multiplier: u8, /// X-list. floor1_x_list: Vec, // Precomputed x-list sort order. floor1_x_list_sort_order: Vec, // Precomputed x-list neighbours. floor1_x_list_neighbors: Vec<(usize, usize)>, } #[derive(Debug)] pub struct Floor1 { setup: Floor1Setup, is_unused: bool, floor_y: Vec, floor_final_y: Vec, floor_step2_flag: Vec, } impl Floor1 { pub fn try_read(bs: &mut BitReaderRtl<'_>, max_codebook: u8) -> Result> { let setup = Self::read_setup(bs, max_codebook)?; let x_list_len = setup.floor1_x_list.len(); Ok(Box::new(Floor1 { setup, is_unused: false, floor_y: vec![0; x_list_len], floor_final_y: vec![0; x_list_len], floor_step2_flag: vec![false; x_list_len], })) } fn read_setup(bs: &mut BitReaderRtl<'_>, max_codebook: u8) -> Result { // The number of partitions. 5-bit value, 0..31 range. let floor1_partitions = bs.read_bits_leq32(5)? as usize; // Parition list of up-to 32 partitions (floor1_partitions), with each partition indicating // a 4-bit class (0..16) identifier. let mut floor1_partition_class_list = [0; 32]; let mut floor1_classes: [Floor1Class; 16] = Default::default(); if floor1_partitions > 0 { let mut max_class = 0; // 4-bits, 0..15 // Read the partition class list. for class_idx in &mut floor1_partition_class_list[..floor1_partitions] { *class_idx = bs.read_bits_leq32(4)? as u8; // Find the maximum class value. max_class = max_class.max(*class_idx); } let num_classes = usize::from(1 + max_class); for class in floor1_classes[..num_classes].iter_mut() { class.dimensions = bs.read_bits_leq32(3)? as u8 + 1; class.subclass_bits = bs.read_bits_leq32(2)? as u8; if class.subclass_bits != 0 { let masterbook = bs.read_bits_leq32(8)? as u8; if masterbook >= max_codebook { return decode_error("vorbis: floor1, invalid codebook for class"); } class.mainbook = masterbook; } let num_subclasses = 1 << class.subclass_bits; for (i, book) in class.subbooks[..num_subclasses].iter_mut().enumerate() { // Read the codebook number. *book = bs.read_bits_leq32(8)? as u8; // A codebook number > 0 indicates a codebook is used. if *book > 0 { // The actual codebook used is the number read minus one. *book -= 1; if *book >= max_codebook { return decode_error("vorbis: floor1, invalid codebook for subclass"); } class.is_subbook_used |= 1 << i; } } } } let floor1_multiplier = bs.read_bits_leq32(2)? as u8 + 1; let rangebits = bs.read_bits_leq32(4)?; let mut floor1_x_list = Vec::new(); let mut floor1_x_list_unique = HashSet::new(); floor1_x_list.push(0); floor1_x_list.push(1 << rangebits); for &class_idx in &floor1_partition_class_list[..floor1_partitions] { let class = &floor1_classes[class_idx as usize]; // No more than 65 elements are allowed. if floor1_x_list.len() + usize::from(class.dimensions) > 65 { return decode_error("vorbis: floor1, x_list too long"); } for _ in 0..class.dimensions { let x = bs.read_bits_leq32(rangebits)?; // All elements in the x list must be unique. if !floor1_x_list_unique.insert(x) { return decode_error("vorbis: floor1, x_list is not unique"); } floor1_x_list.push(x); } } let mut floor1_x_list_neighbors = Vec::with_capacity(floor1_x_list.len()); let mut floor1_x_list_sort_order = Vec::with_capacity(floor1_x_list.len()); // Precompute neighbors. for i in 0..floor1_x_list.len() { floor1_x_list_neighbors.push(find_neighbors(&floor1_x_list, i)); floor1_x_list_sort_order.push(i as u8); } // Precompute sort-order. floor1_x_list_sort_order.sort_by_key(|&i| floor1_x_list[i as usize]); let floor_type1 = Floor1Setup { floor1_partitions, floor1_partition_class_list, floor1_classes, floor1_multiplier, floor1_x_list, floor1_x_list_neighbors, floor1_x_list_sort_order, }; Ok(floor_type1) } fn synthesis_step1(&mut self) { // Step 1. let range = get_range(self.setup.floor1_multiplier); self.floor_step2_flag[0] = true; self.floor_step2_flag[1] = true; self.floor_final_y[0] = self.floor_y[0] as i32; self.floor_final_y[1] = self.floor_y[1] as i32; for i in 2..self.setup.floor1_x_list.len() { // Find the neighbours. let (low_neighbor_offset, high_neighbor_offset) = self.setup.floor1_x_list_neighbors[i]; let predicted = render_point( self.setup.floor1_x_list[low_neighbor_offset], self.floor_final_y[low_neighbor_offset], self.setup.floor1_x_list[high_neighbor_offset], self.floor_final_y[high_neighbor_offset], self.setup.floor1_x_list[i], ); let val = self.floor_y[i] as i32; let highroom = range as i32 - predicted; let lowroom = predicted; if val != 0 { let room = 2 * if highroom < lowroom { highroom } else { lowroom }; self.floor_step2_flag[low_neighbor_offset] = true; self.floor_step2_flag[high_neighbor_offset] = true; self.floor_step2_flag[i] = true; self.floor_final_y[i] = if val >= room { if highroom > lowroom { val - lowroom + predicted } else { predicted - val + highroom - 1 } } else { // If val is odd. if val & 1 == 1 { predicted - ((val + 1) / 2) } else { // If val is even. predicted + (val / 2) } } } else { self.floor_step2_flag[i] = false; self.floor_final_y[i] = predicted; } } } fn synthesis_step2(&mut self, n: u32, floor: &mut [f32]) { let multiplier = self.setup.floor1_multiplier as i32; let floor_final_y0 = self.floor_final_y[self.setup.floor1_x_list_sort_order[0] as usize]; let mut hx = 0; let mut hy = 0; let mut lx = 0; let mut ly = floor_final_y0 * multiplier; // Iterate in sort-order. for i in self.setup.floor1_x_list_sort_order[1..].iter().map(|i| *i as usize) { if self.floor_step2_flag[i] { hy = self.floor_final_y[i] * multiplier; hx = self.setup.floor1_x_list[i]; render_line(lx, ly, hx, hy, n as usize, floor); lx = hx; ly = hy; } } if hx < n { render_line(hx, hy, n, hy, n as usize, floor); } } } impl Floor for Floor1 { fn read_channel( &mut self, bs: &mut BitReaderRtl<'_>, codebooks: &[VorbisCodebook], ) -> Result<()> { // Assume the floor is unused until it is decoded successfully. self.is_unused = true; // First bit marks if this floor is used. Exit early if it is not. let is_used = io_try_or_ret!(bs.read_bool()); if !is_used { return Ok(()); } // Section 7.3.2 let range = get_range(self.setup.floor1_multiplier); // The number of bits required to represent range. let range_bits = ilog(range - 1); self.floor_y[0] = io_try_or_ret!(bs.read_bits_leq32(range_bits)); self.floor_y[1] = io_try_or_ret!(bs.read_bits_leq32(range_bits)); let mut offset = 2; for &class_idx in &self.setup.floor1_partition_class_list[0..self.setup.floor1_partitions] { // The class. let class = &self.setup.floor1_classes[class_idx as usize]; let cdim = class.dimensions as usize; let cbits = class.subclass_bits; let csub = (1 << cbits) - 1; let mut cval = 0; if cbits > 0 { let mainbook_idx = class.mainbook as usize; cval = try_or_ret!(codebooks[mainbook_idx].read_scalar(bs)); } for floor_y in self.floor_y[offset..offset + cdim].iter_mut() { let subclass_idx = cval & csub; // Is the sub-book used for this sub-class. let is_subbook_used = class.is_subbook_used & (1 << subclass_idx) != 0; cval >>= cbits; *floor_y = if is_subbook_used { let subbook_idx = class.subbooks[subclass_idx as usize] as usize; try_or_ret!(codebooks[subbook_idx].read_scalar(bs)) } else { 0 }; } offset += cdim; } // If this point is reached then the floor is used. self.is_unused = false; Ok(()) } fn is_unused(&self) -> bool { self.is_unused } fn synthesis(&mut self, bs_exp: u8, floor: &mut [f32]) -> Result<()> { debug_assert!(!self.is_unused); self.synthesis_step1(); self.synthesis_step2((1 << bs_exp) >> 1, floor); Ok(()) } } #[inline(always)] fn get_range(multiplier: u8) -> u32 { match multiplier - 1 { 0 => 256, 1 => 128, 2 => 86, 3 => 64, _ => unreachable!(), } } #[inline(always)] fn find_neighbors(vec: &[u32], x: usize) -> (usize, usize) { let bound = vec[x]; let mut low = u32::MIN; // TODO: Should be -1? let mut high = u32::MAX; let mut res: (usize, usize) = (0, 0); // Sections 9.2.4 and 9.2.5 for (i, &xv) in vec[..x].iter().enumerate() { // low_neighbor(v,x) finds the position n in vector [v] of the greatest value scalar element // for which n is less than x and vector [v] element n is less than vector [v] element [x]. if xv > low && xv < bound { low = xv; res.0 = i; } // high_neighbor(v,x) finds the position n in vector [v] of the lowest value scalar element // for which n is less than x and vector [v] element n is greater than vector [v] element [x]. if xv < high && xv > bound { high = xv; res.1 = i; } } res } #[inline(always)] fn render_point(x0: u32, y0: i32, x1: u32, y1: i32, x: u32) -> i32 { let dy = y1 - y0; let adx = x1 - x0; let err = dy.unsigned_abs() * (x - x0); let off = err / adx; if dy < 0 { y0 - off as i32 } else { y0 + off as i32 } } #[inline(always)] fn render_line(x0: u32, y0: i32, x1: u32, y1: i32, n: usize, v: &mut [f32]) { let dy = y1 - y0; let adx = (x1 - x0) as i32; let base = dy / adx; let mut y = y0; let sy = if dy < 0 { base - 1 } else { base + 1 }; let ady = dy.abs() - base.abs() * adx; v[x0 as usize] = FLOOR1_INVERSE_DB_TABLE[y as usize]; let mut err = 0; let x_begin = x0 as usize + 1; let x_end = min(n, x1 as usize); for v in v[x_begin..x_end].iter_mut() { err += ady; y += if err >= adx { err -= adx; sy } else { base }; *v = FLOOR1_INVERSE_DB_TABLE[y as usize]; } } symphonia-codec-vorbis-0.5.2/src/lib.rs000064400000000000000000000577021046102023000161320ustar 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)] // Disable to better express the specification. #![allow(clippy::collapsible_else_if)] use symphonia_core::audio::{AsAudioBufferRef, AudioBuffer, AudioBufferRef}; use symphonia_core::audio::{Signal, SignalSpec}; use symphonia_core::codecs::{CodecDescriptor, CodecParameters, CODEC_TYPE_VORBIS}; use symphonia_core::codecs::{Decoder, DecoderOptions, FinalizeResult}; use symphonia_core::dsp::mdct::Imdct; use symphonia_core::errors::{decode_error, unsupported_error, Result}; use symphonia_core::formats::Packet; use symphonia_core::io::{BitReaderRtl, BufReader, FiniteBitStream, ReadBitsRtl, ReadBytes}; use symphonia_core::support_codec; use symphonia_utils_xiph::vorbis::*; use log::{debug, warn}; mod codebook; mod common; mod dsp; mod floor; mod residue; mod window; use codebook::VorbisCodebook; use common::*; use dsp::*; use floor::*; use residue::*; use window::Windows; /// Vorbis decoder. pub struct VorbisDecoder { /// Codec paramters. params: CodecParameters, /// Identity header. ident: IdentHeader, /// Codebooks (max. 256). codebooks: Vec, /// Floors (max. 64). floors: Vec>, /// Residues (max. 64). residues: Vec, /// Modes (max. 64). modes: Vec, /// Mappings (max. 64). mappings: Vec, /// DSP. dsp: Dsp, /// Output buffer. buf: AudioBuffer, } impl VorbisDecoder { fn decode_inner(&mut self, packet: &Packet) -> Result<()> { let mut bs = BitReaderRtl::new(packet.buf()); // Section 4.3.1 - Packet Type, Mode, and Window Decode // First bit must be 0 to indicate audio packet. if bs.read_bool()? { return decode_error("vorbis: not an audio packet"); } let num_modes = self.modes.len() - 1; let mode_number = bs.read_bits_leq32(common::ilog(num_modes as u32))? as usize; if mode_number >= self.modes.len() { return decode_error("vorbis: invalid packet mode number"); } let mode = &self.modes[mode_number]; let mapping = &self.mappings[usize::from(mode.mapping)]; let (bs_exp, imdct) = if mode.block_flag { // This packet (block) uses a long window. Do not use the window flags since they may // be wrong. let _prev_window_flag = bs.read_bool()?; let _next_window_flag = bs.read_bool()?; (self.ident.bs1_exp, &mut self.dsp.imdct_long) } else { // This packet (block) uses a short window. (self.ident.bs0_exp, &mut self.dsp.imdct_short) }; // Block, and half-block size let n = 1 << bs_exp; let n2 = n >> 1; // Section 4.3.2 - Floor Curve Decode // Read the floors from the packet. There is one floor per audio channel. Each mapping will // have one multiplex (submap number) per audio channel. Therefore, iterate over all // muxes in the mapping, and read the floor. for (&submap_num, ch) in mapping.multiplex.iter().zip(&mut self.dsp.channels) { let submap = &mapping.submaps[submap_num as usize]; let floor = &mut self.floors[submap.floor as usize]; // Read the floor from the bitstream. floor.read_channel(&mut bs, &self.codebooks)?; ch.do_not_decode = floor.is_unused(); if !ch.do_not_decode { // Since the same floor can be used by multiple channels and thus overwrite the // data just read from the bitstream, synthesize the floor curve for this channel // now and save it for audio synthesis later. floor.synthesis(bs_exp, &mut ch.floor)?; } else { // If the channel is unused, zero the floor vector. ch.floor[..n2].fill(0.0); } } // Section 4.3.3 - Non-zero Vector Propagate // If within a pair of coupled channels, one channel has an unused floor (do_not_decode // is true for that channel), but the other channel is used, then both channels must have // do_not_decode unset. for couple in &mapping.couplings { let magnitude_ch_idx = usize::from(couple.magnitude_ch); let angle_ch_idx = usize::from(couple.angle_ch); if self.dsp.channels[magnitude_ch_idx].do_not_decode != self.dsp.channels[angle_ch_idx].do_not_decode { self.dsp.channels[magnitude_ch_idx].do_not_decode = false; self.dsp.channels[angle_ch_idx].do_not_decode = false; } } // Section 4.3.4 - Residue Decode for (submap_idx, submap) in mapping.submaps.iter().enumerate() { let mut residue_channels: BitSet256 = Default::default(); // Find the channels using this submap. for (c, &ch_submap_idx) in mapping.multiplex.iter().enumerate() { if submap_idx == usize::from(ch_submap_idx) { residue_channels.set(c) } } let residue = &mut self.residues[submap.residue as usize]; residue.read_residue( &mut bs, bs_exp, &self.codebooks, &residue_channels, &mut self.dsp.channels, )?; } // Section 4.3.5 - Inverse Coupling for coupling in mapping.couplings.iter() { debug_assert!(coupling.magnitude_ch != coupling.angle_ch); // Get mutable reference to each channel in the pair. let (magnitude_ch, angle_ch) = if coupling.magnitude_ch < coupling.angle_ch { // Magnitude channel index < angle channel index. let (a, b) = self.dsp.channels.split_at_mut(coupling.angle_ch as usize); (&mut a[coupling.magnitude_ch as usize], &mut b[0]) } else { // Angle channel index < magnitude channel index. let (a, b) = self.dsp.channels.split_at_mut(coupling.magnitude_ch as usize); (&mut b[0], &mut a[coupling.angle_ch as usize]) }; for (m, a) in magnitude_ch.residue[..n2].iter_mut().zip(&mut angle_ch.residue[..n2]) { let (new_m, new_a) = if *m > 0.0 { if *a > 0.0 { (*m, *m - *a) } else { (*m + *a, *m) } } else { if *a > 0.0 { (*m, *m + *a) } else { (*m - *a, *m) } }; *m = new_m; *a = new_a; } } // Section 4.3.6 - Dot Product for channel in self.dsp.channels.iter_mut() { // If the channel is marked as do not decode, the floor vector is all 0. Therefore the // dot product will be 0. if channel.do_not_decode { continue; } for (f, r) in channel.floor[..n2].iter_mut().zip(&mut channel.residue[..n2]) { *f *= *r; } } // Combined Section 4.3.7 and 4.3.8 - Inverse MDCT and Overlap-add (Synthesis) self.buf.clear(); // Calculate the output length and reserve space in the output buffer. If there was no // previous packet, then return an empty audio buffer since the decoder will need another // packet before being able to produce audio. if let Some(lap_state) = &self.dsp.lapping_state { // The previous block size. let prev_block_n = if lap_state.prev_block_flag { 1 << self.ident.bs1_exp } else { 1 << self.ident.bs0_exp }; let render_len = (prev_block_n + n) / 4; self.buf.render_reserved(Some(render_len)); } // Render all the audio channels. for (i, channel) in self.dsp.channels.iter_mut().enumerate() { channel.synth( mode.block_flag, &self.dsp.lapping_state, &self.dsp.windows, imdct, self.buf.chan_mut(map_vorbis_channel(self.ident.n_channels, i)), ); } // Trim self.buf.trim(packet.trim_start() as usize, packet.trim_end() as usize); // Save the new lapping state. self.dsp.lapping_state = Some(LappingState { prev_block_flag: mode.block_flag }); Ok(()) } } impl Decoder for VorbisDecoder { fn try_new(params: &CodecParameters, _: &DecoderOptions) -> Result { // This decoder only supports Vorbis. if params.codec != CODEC_TYPE_VORBIS { return unsupported_error("vorbis: invalid codec type"); } // Get the extra data (mandatory). let extra_data = match params.extra_data.as_ref() { Some(buf) => buf, _ => return unsupported_error("vorbis: missing extra data"), }; // The extra data contains the identification and setup headers. let mut reader = BufReader::new(extra_data); // Read ident header. let ident = read_ident_header(&mut reader)?; // Read setup data. let setup = read_setup(&mut reader, &ident)?; // Initialize static DSP data. let windows = Windows::new(1 << ident.bs0_exp, 1 << ident.bs1_exp); // Initialize dynamic DSP for each channel. let dsp_channels = (0..ident.n_channels).map(|_| DspChannel::new(ident.bs0_exp, ident.bs1_exp)).collect(); // Map the channels let channels = match vorbis_channels_to_channels(ident.n_channels) { Some(channels) => channels, _ => return unsupported_error("vorbis: unknown channel map (fix me)"), }; // Initialize the output buffer. let spec = SignalSpec::new(ident.sample_rate, channels); let imdct_short = Imdct::new((1 << ident.bs0_exp) >> 1); let imdct_long = Imdct::new((1 << ident.bs1_exp) >> 1); // TODO: Should this be half the block size? let duration = 1u64 << ident.bs1_exp; let dsp = Dsp { windows, channels: dsp_channels, imdct_short, imdct_long, lapping_state: None }; Ok(VorbisDecoder { params: params.clone(), ident, codebooks: setup.codebooks, floors: setup.floors, residues: setup.residues, modes: setup.modes, mappings: setup.mappings, dsp, buf: AudioBuffer::new(duration, spec), }) } fn reset(&mut self) { self.dsp.reset(); } fn supported_codecs() -> &'static [CodecDescriptor] { &[support_codec!(CODEC_TYPE_VORBIS, "vorbis", "Vorbis")] } 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 { Default::default() } fn last_decoded(&self) -> AudioBufferRef<'_> { self.buf.as_audio_buffer_ref() } } #[derive(Debug)] struct IdentHeader { n_channels: u8, sample_rate: u32, bs0_exp: u8, bs1_exp: u8, } /// The packet type for an identification header. const VORBIS_PACKET_TYPE_IDENTIFICATION: u8 = 1; /// The packet type for a setup header. const VORBIS_PACKET_TYPE_SETUP: u8 = 5; /// The common header packet signature. const VORBIS_HEADER_PACKET_SIGNATURE: &[u8] = b"vorbis"; /// The Vorbis version supported by this mapper. const VORBIS_VERSION: u32 = 0; /// The minimum block size (64) expressed as a power-of-2 exponent. const VORBIS_BLOCKSIZE_MIN: u8 = 6; /// The maximum block size (8192) expressed as a power-of-2 exponent. const VORBIS_BLOCKSIZE_MAX: u8 = 13; fn read_ident_header(reader: &mut B) -> Result { // The packet type must be an identification header. let packet_type = reader.read_u8()?; if packet_type != VORBIS_PACKET_TYPE_IDENTIFICATION { return decode_error("vorbis: invalid packet type for identification header"); } // Next, the header packet signature must be correct. let mut packet_sig_buf = [0; 6]; reader.read_buf_exact(&mut packet_sig_buf)?; if packet_sig_buf != VORBIS_HEADER_PACKET_SIGNATURE { return decode_error("vorbis: invalid header signature"); } // Next, the Vorbis version must be 0. let version = reader.read_u32()?; if version != VORBIS_VERSION { return unsupported_error("vorbis: only vorbis 1 is supported"); } // Next, the number of channels and sample rate must be non-zero. let n_channels = reader.read_u8()?; if n_channels == 0 { return decode_error("vorbis: number of channels cannot be 0"); } // This is a Symphonia limitation. if n_channels > 32 { return unsupported_error("vorbis: only a maximum of 32 channels are supported"); } let sample_rate = reader.read_u32()?; if sample_rate == 0 { return decode_error("vorbis: sample rate cannot be 0"); } // Read the bitrate range. let _bitrate_max = reader.read_u32()?; let _bitrate_nom = reader.read_u32()?; let _bitrate_min = reader.read_u32()?; // Next, blocksize_0 and blocksize_1 are packed into a single byte. let block_sizes = reader.read_u8()?; let bs0_exp = (block_sizes & 0x0f) >> 0; let bs1_exp = (block_sizes & 0xf0) >> 4; // The block sizes must not exceed the bounds. if bs0_exp < VORBIS_BLOCKSIZE_MIN || bs0_exp > VORBIS_BLOCKSIZE_MAX { return decode_error("vorbis: blocksize_0 out-of-bounds"); } if bs1_exp < VORBIS_BLOCKSIZE_MIN || bs1_exp > VORBIS_BLOCKSIZE_MAX { return decode_error("vorbis: blocksize_1 out-of-bounds"); } // Blocksize_0 must be >= blocksize_1 if bs0_exp > bs1_exp { return decode_error("vorbis: blocksize_0 exceeds blocksize_1"); } // Framing flag must be set. if reader.read_u8()? != 0x1 { return decode_error("vorbis: ident header framing flag unset"); } Ok(IdentHeader { n_channels, sample_rate, bs0_exp, bs1_exp }) } struct Setup { codebooks: Vec, floors: Vec>, residues: Vec, mappings: Vec, modes: Vec, } fn read_setup(reader: &mut BufReader<'_>, ident: &IdentHeader) -> Result { // The packet type must be an setup header. let packet_type = reader.read_u8()?; if packet_type != VORBIS_PACKET_TYPE_SETUP { return decode_error("vorbis: invalid packet type for setup header"); } // Next, the setup packet signature must be correct. let mut packet_sig_buf = [0; 6]; reader.read_buf_exact(&mut packet_sig_buf)?; if packet_sig_buf != VORBIS_HEADER_PACKET_SIGNATURE { return decode_error("vorbis: invalid setup header signature"); } // The remaining portion of the setup header packet is read bitwise. let mut bs = BitReaderRtl::new(reader.read_buf_bytes_available_ref()); // Read codebooks. let codebooks = read_codebooks(&mut bs)?; // Read time-domain transforms (placeholders in Vorbis 1). read_time_domain_transforms(&mut bs)?; // Read floors. let floors = read_floors(&mut bs, ident.bs0_exp, ident.bs1_exp, codebooks.len() as u8)?; // Read residues. let residues = read_residues(&mut bs, codebooks.len() as u8)?; // Read channel mappings. let mappings = read_mappings(&mut bs, ident.n_channels, floors.len() as u8, residues.len() as u8)?; // Read modes. let modes = read_modes(&mut bs, mappings.len() as u8)?; // Framing flag must be set. if !bs.read_bool()? { return decode_error("vorbis: setup header framing flag unset"); } if bs.bits_left() > 0 { debug!("vorbis: leftover bits in setup head extra data"); } Ok(Setup { codebooks, floors, residues, mappings, modes }) } fn read_codebooks(bs: &mut BitReaderRtl<'_>) -> Result> { let count = bs.read_bits_leq32(8)? + 1; (0..count).map(|_| VorbisCodebook::read(bs)).collect() } fn read_time_domain_transforms(bs: &mut BitReaderRtl<'_>) -> Result<()> { let count = bs.read_bits_leq32(6)? + 1; for _ in 0..count { // All these values are placeholders and must be 0. if bs.read_bits_leq32(16)? != 0 { return decode_error("vorbis: invalid time domain tranform"); } } Ok(()) } fn read_floors( bs: &mut BitReaderRtl<'_>, bs0_exp: u8, bs1_exp: u8, max_codebook: u8, ) -> Result>> { let count = bs.read_bits_leq32(6)? + 1; (0..count).map(|_| read_floor(bs, bs0_exp, bs1_exp, max_codebook)).collect() } fn read_floor( bs: &mut BitReaderRtl<'_>, bs0_exp: u8, bs1_exp: u8, max_codebook: u8, ) -> Result> { let floor_type = bs.read_bits_leq32(16)?; match floor_type { 0 => Floor0::try_read(bs, bs0_exp, bs1_exp, max_codebook), 1 => Floor1::try_read(bs, max_codebook), _ => decode_error("vorbis: invalid floor type"), } } fn read_residues(bs: &mut BitReaderRtl<'_>, max_codebook: u8) -> Result> { let count = bs.read_bits_leq32(6)? + 1; (0..count).map(|_| read_residue(bs, max_codebook)).collect() } fn read_residue(bs: &mut BitReaderRtl<'_>, max_codebook: u8) -> Result { let residue_type = bs.read_bits_leq32(16)? as u16; match residue_type { 0 | 1 | 2 => Residue::try_read(bs, residue_type, max_codebook), _ => decode_error("vorbis: invalid residue type"), } } fn read_mappings( bs: &mut BitReaderRtl<'_>, audio_channels: u8, max_floor: u8, max_residue: u8, ) -> Result> { let count = bs.read_bits_leq32(6)? + 1; (0..count).map(|_| read_mapping(bs, audio_channels, max_floor, max_residue)).collect() } fn read_mapping( bs: &mut BitReaderRtl<'_>, audio_channels: u8, max_floor: u8, max_residue: u8, ) -> Result { let mapping_type = bs.read_bits_leq32(16)?; match mapping_type { 0 => read_mapping_type0(bs, audio_channels, max_floor, max_residue), _ => decode_error("vorbis: invalid mapping type"), } } fn read_modes(bs: &mut BitReaderRtl<'_>, max_mapping: u8) -> Result> { let count = bs.read_bits_leq32(6)? + 1; (0..count).map(|_| read_mode(bs, max_mapping)).collect() } #[derive(Debug)] struct ChannelCouple { magnitude_ch: u8, angle_ch: u8, } #[derive(Debug)] struct SubMap { floor: u8, residue: u8, } #[derive(Debug)] struct Mapping { couplings: Vec, multiplex: Vec, submaps: Vec, } fn read_mapping_type0( bs: &mut BitReaderRtl<'_>, audio_channels: u8, max_floor: u8, max_residue: u8, ) -> Result { let num_submaps = if bs.read_bool()? { bs.read_bits_leq32(4)? as u8 + 1 } else { 1 }; let mut couplings = Vec::new(); if bs.read_bool()? { // Number of channel couplings (up-to 256). let coupling_steps = bs.read_bits_leq32(8)? as u16 + 1; // Reserve space. couplings.reserve_exact(usize::from(coupling_steps)); // The maximum channel number. let max_ch = audio_channels - 1; // The number of bits to read for the magnitude and angle channel numbers. Never exceeds 8. let coupling_bits = ilog(u32::from(max_ch)); debug_assert!(coupling_bits <= 8); // Read each channel coupling. for _ in 0..coupling_steps { let magnitude_ch = bs.read_bits_leq32(coupling_bits)? as u8; let angle_ch = bs.read_bits_leq32(coupling_bits)? as u8; // Ensure the channels to be coupled are not the same, and that neither channel number // exceeds the maximum channel in the stream. if magnitude_ch == angle_ch || magnitude_ch > max_ch || angle_ch > max_ch { return decode_error("vorbis: invalid channel coupling"); } couplings.push(ChannelCouple { magnitude_ch, angle_ch }); } } if bs.read_bits_leq32(2)? != 0 { return decode_error("vorbis: reserved mapping bits non-zero"); } let mut multiplex = Vec::with_capacity(usize::from(audio_channels)); // If the number of submaps is > 1 read the multiplex numbers from the bitstream, otherwise // they're all 0. if num_submaps > 1 { for _ in 0..audio_channels { let mux = bs.read_bits_leq32(4)? as u8; if mux >= num_submaps { return decode_error("vorbis: invalid channel multiplex"); } multiplex.push(mux); } } else { multiplex.resize(usize::from(audio_channels), 0); } let mut submaps = Vec::with_capacity(usize::from(num_submaps)); for _ in 0..num_submaps { // Unused. let _ = bs.read_bits_leq32(8)?; // The floor to use. let floor = bs.read_bits_leq32(8)? as u8; if floor >= max_floor { return decode_error("vorbis: invalid floor for mapping"); } // The residue to use. let residue = bs.read_bits_leq32(8)? as u8; if residue >= max_residue { return decode_error("vorbis: invalid residue for mapping"); } submaps.push(SubMap { floor, residue }); } let mapping = Mapping { couplings, multiplex, submaps }; Ok(mapping) } #[derive(Debug)] struct Mode { block_flag: bool, mapping: u8, } fn read_mode(bs: &mut BitReaderRtl<'_>, max_mapping: u8) -> Result { let block_flag = bs.read_bool()?; let window_type = bs.read_bits_leq32(16)? as u16; let transform_type = bs.read_bits_leq32(16)? as u16; let mapping = bs.read_bits_leq32(8)? as u8; // Only window type 0 is allowed in Vorbis 1 (section 4.2.4). if window_type != 0 { return decode_error("vorbis: invalid window type for mode"); } // Only transform type 0 is allowed in Vorbis 1 (section 4.2.4). if transform_type != 0 { return decode_error("vorbis: invalid transform type for mode"); } // Mapping number must be exist. if mapping >= max_mapping { return decode_error("vorbis: invalid mode mapping"); } let mode = Mode { block_flag, mapping }; Ok(mode) } /// Map a Vorbis channel index to an audio buffer channel index given the channel map implied by the /// total number of channels. /// /// See channel map as defined in section 4.3.9 of the Vorbis I specification. pub fn map_vorbis_channel(num_channels: u8, ch: usize) -> usize { // This pre-condition should always be true. assert!(ch < usize::from(num_channels)); let mapped_ch: u8 = match num_channels { 1 => [0][ch], // FL 2 => [0, 1][ch], // FL, FR 3 => [0, 2, 1][ch], // FL, FC, FR 4 => [0, 1, 2, 3][ch], // FL, FR, RL, RR 5 => [0, 2, 1, 3, 4][ch], // FL, FC, FR, RL, RR 6 => [0, 2, 1, 4, 5, 3][ch], // FL, FC, FR, RL, RR, LFE 7 => [0, 2, 1, 5, 6, 4, 3][ch], // FL, FC, FR, SL, SR, RC, LFE 8 => [0, 2, 1, 6, 7, 4, 5, 3][ch], // FL, FC, FR, SL, SR, RL, RR, LFE _ => return ch, }; usize::from(mapped_ch) } symphonia-codec-vorbis-0.5.2/src/residue.rs000064400000000000000000000372421046102023000170210ustar 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::min; use std::convert::TryInto; use std::io; use symphonia_core::errors::{decode_error, Error, Result}; use symphonia_core::io::{BitReaderRtl, ReadBitsRtl}; use super::codebook::VorbisCodebook; use super::common::*; use super::DspChannel; #[derive(Debug, Default)] struct ResidueVqClass { books: [u8; 8], is_used: u8, } impl ResidueVqClass { #[inline(always)] fn is_used(&self, pass: usize) -> bool { debug_assert!(pass < 8); self.is_used & (1 << pass) != 0 } } #[derive(Debug)] struct ResidueSetup { /// The residue format. residue_type: u16, /// The residue's starting offset. residue_begin: u32, /// The residue's ending offset. residue_end: u32, /// Residue partition size (max. value 2^24). residue_partition_size: u32, /// Residue classifications (max. value 64). residue_classifications: u8, /// Codebook for reading partition classifications. residue_classbook: u8, /// Codebooks for each partition classification. residue_vq_class: Vec, /// The maximum pass. residue_max_pass: usize, } #[derive(Debug)] pub struct Residue { setup: ResidueSetup, /// Classifications vector. part_classes: Vec, /// Vector to read interleaved format 2 residuals. type2_buf: Vec, } impl Residue { pub fn try_read( bs: &mut BitReaderRtl<'_>, residue_type: u16, max_codebook: u8, ) -> Result { let setup = Self::read_setup(bs, residue_type, max_codebook)?; Ok(Residue { setup, part_classes: Default::default(), type2_buf: Default::default() }) } fn read_setup( bs: &mut BitReaderRtl<'_>, residue_type: u16, max_codebook: u8, ) -> Result { let residue_begin = bs.read_bits_leq32(24)?; let residue_end = bs.read_bits_leq32(24)?; let residue_partition_size = bs.read_bits_leq32(24)? + 1; let residue_classifications = bs.read_bits_leq32(6)? as u8 + 1; let residue_classbook = bs.read_bits_leq32(8)? as u8; if residue_end < residue_begin { return decode_error("vorbis: invalid residue begin and end"); } let mut residue_vq_books = Vec::::new(); for _ in 0..residue_classifications { let low_bits = bs.read_bits_leq32(3)? as u8; let high_bits = if bs.read_bool()? { bs.read_bits_leq32(5)? as u8 } else { 0 }; let is_used = (high_bits << 3) | low_bits; residue_vq_books.push(ResidueVqClass { is_used, books: [0; 8] }); } let mut residue_max_pass = 0; for vq_books in &mut residue_vq_books { // For each set of residue codebooks, if the codebook is used, read the codebook // number. for (j, book) in vq_books.books.iter_mut().enumerate() { // Is a codebook used? let is_codebook_used = vq_books.is_used & (1 << j) != 0; if is_codebook_used { // Read the codebook number. *book = bs.read_bits_leq32(8)? as u8; // The codebook number cannot be 0 or exceed the number of codebooks in this // stream. if *book == 0 || *book >= max_codebook { return decode_error("vorbis: invalid codebook for residue"); } residue_max_pass = residue_max_pass.max(j); } } } let residue = ResidueSetup { residue_type, residue_begin, residue_end, residue_partition_size, residue_classifications, residue_classbook, residue_vq_class: residue_vq_books, residue_max_pass, }; Ok(residue) } pub fn read_residue( &mut self, bs: &mut BitReaderRtl<'_>, bs_exp: u8, codebooks: &[VorbisCodebook], residue_channels: &BitSet256, channels: &mut [DspChannel], ) -> Result<()> { // Read the residue, and ignore end-of-bitstream errors which are legal. match self.read_residue_inner(bs, bs_exp, codebooks, residue_channels, channels) { Ok(_) => (), // An end-of-bitstream error is classified under ErrorKind::Other. This condition // should not be treated as an error. Err(Error::IoError(ref e)) if e.kind() == io::ErrorKind::Other => (), Err(e) => return Err(e), }; if self.setup.residue_type == 2 { // For format 2, the residue vectors for all channels are interleaved together into one // large vector. This vector is in the scratch-pad buffer and can now be de-interleaved // into the channel buffers. let stride = residue_channels.count(); for (i, ch) in residue_channels.iter().enumerate() { let channel = &mut channels[ch]; let iter = self.type2_buf.chunks_exact(stride).map(|c| c[i]); for (o, i) in channel.residue.iter_mut().zip(iter) { *o = i; } } } Ok(()) } fn read_residue_inner( &mut self, bs: &mut BitReaderRtl<'_>, bs_exp: u8, codebooks: &[VorbisCodebook], residue_channels: &BitSet256, channels: &mut [DspChannel], ) -> Result<()> { let class_book = &codebooks[self.setup.residue_classbook as usize]; // The actual length of the entire residue vector for a channel (formats 0 and 1), or all // interleaved channels (format 2). let full_residue_len = match self.setup.residue_type { 2 => ((1 << bs_exp) >> 1) * residue_channels.count(), _ => (1 << bs_exp) >> 1, }; // The range of the residue vector being decoded. let limit_residue_begin = min(self.setup.residue_begin as usize, full_residue_len); let limit_residue_end = min(self.setup.residue_end as usize, full_residue_len); // Length of the decoded part of the residue vector. let residue_len = limit_residue_end - limit_residue_begin; // Number of partitions per classword. let parts_per_classword = class_book.dimensions(); // Number of partitions to read. let parts_to_read = residue_len / self.setup.residue_partition_size as usize; let is_fmt2 = self.setup.residue_type == 2; // Setup the scratch-pad. if is_fmt2 { // Reserve partition classification space in the scratch-pad. self.setup_part_classes(parts_to_read); // Reserve interleave buffer storage in the scratch-pad. self.setup_type2_buf(full_residue_len); } else { self.setup_part_classes(parts_to_read * residue_channels.count()); } let mut has_channel_to_decode = false; // Zero unused residue channels. for ch in residue_channels.iter() { let channel = &mut channels[ch]; // Zero the channel residue if not type 2. if !is_fmt2 { channel.residue[..full_residue_len].fill(0.0); } has_channel_to_decode |= !channel.do_not_decode; } // If all channels are marked do-not-decode then immediately exit. if !has_channel_to_decode { return Ok(()); } let part_size = self.setup.residue_partition_size as usize; // Residues may be encoded in up-to 8 passes. Fewer passes may be encoded by prematurely // "ending" the packet. This means that an end-of-bitstream error is actually NOT an error. for pass in 0..self.setup.residue_max_pass + 1 { // Iterate over the partitions in batches grouped by classword. for part_first in (0..parts_to_read).step_by(parts_per_classword as usize) { // The class assignments for each partition in the classword group are only // encoded in the first pass. if pass == 0 { // If using format 2, there is only a single classification list. if is_fmt2 { let code = class_book.read_scalar(bs)?; decode_classes( code, parts_per_classword, self.setup.residue_classifications as u32, &mut self.part_classes[part_first..], ); } else { // For formats 0 and 1, each channel has its own classification list. for (i, ch) in residue_channels.iter().enumerate() { let channel = &channels[ch]; // If the channel is marked do-not-decode then advance to the next // channel. if channel.do_not_decode { continue; } let code = class_book.read_scalar(bs)?; decode_classes( code, parts_per_classword, self.setup.residue_classifications as u32, &mut self.part_classes[part_first + i * parts_to_read..], ); } } } // The last partition in this batch of partitions, being careful not to exceed the // total number of partitions. let part_last = min(parts_to_read, part_first + parts_per_classword as usize); // Iterate over all partitions belonging to the current classword group. for part in part_first..part_last { // Iterate over each channel vector in the partition. for (i, ch) in residue_channels.iter().enumerate() { let channel = &mut channels[ch]; let vq_class = if !is_fmt2 { // If the channel is marked do-no-decode, then advance to the next // channels. if channel.do_not_decode { continue; } let class_idx = self.part_classes[part + parts_to_read * i] as usize; &self.setup.residue_vq_class[class_idx] } else { &self.setup.residue_vq_class[self.part_classes[part] as usize] }; if vq_class.is_used(pass) { let vq_book = &codebooks[vq_class.books[pass] as usize]; let part_start = limit_residue_begin + part_size * part; match self.setup.residue_type { 0 => read_residue_partition_format0( bs, vq_book, &mut channel.residue[part_start..part_start + part_size], ), 1 => read_residue_partition_format1( bs, vq_book, &mut channel.residue[part_start..part_start + part_size], ), 2 => { // Residue type 2 is implemented in term of type 1. read_residue_partition_format1( bs, vq_book, &mut self.type2_buf[part_start..part_start + part_size], ) } _ => unreachable!(), }?; } if is_fmt2 { break; } } } // End of partition batch iteration. } // End of pass iteration. } Ok(()) } /// Ensures there is enough storage for `len` partition classes. #[inline] fn setup_part_classes(&mut self, len: usize) { if self.part_classes.len() < len { self.part_classes.resize(len, Default::default()); } } /// Ensures the interleave buffer for type 2 residues can accomodate `len` samples, and that the /// samples are zeroed. #[inline] fn setup_type2_buf(&mut self, len: usize) { if self.type2_buf.len() < len { self.type2_buf.resize(len, Default::default()); } self.type2_buf[..len].fill(0.0); } } fn decode_classes(mut val: u32, parts_per_classword: u16, classifications: u32, out: &mut [u8]) { let parts_per_classword = usize::from(parts_per_classword); // The number of partitions that need a class assignment. let num_parts = out.len(); // If the number of partitions per classword is greater than the number of partitions that need // a class assignment, then the excess classes must be dropped because class assignments are // assigned in reverse order. let skip = if parts_per_classword > num_parts { let skip = parts_per_classword - num_parts; for _ in 0..skip { val /= classifications; } skip } else { 0 }; for out in out[..parts_per_classword - skip].iter_mut().rev() { *out = (val % classifications) as u8; val /= classifications; } } fn read_residue_partition_format0( bs: &mut BitReaderRtl<'_>, codebook: &VorbisCodebook, out: &mut [f32], ) -> Result<()> { let step = out.len() / codebook.dimensions() as usize; for i in 0..step { let vq = codebook.read_vq(bs)?; for (o, &v) in out[i..].iter_mut().step_by(step).zip(vq) { *o += v; } } Ok(()) } #[inline(always)] fn read_residue_partition_format1( bs: &mut BitReaderRtl<'_>, codebook: &VorbisCodebook, out: &mut [f32], ) -> Result<()> { let dim = codebook.dimensions() as usize; // For small dimensions it is too expensive to use iterator loops. Special case small sizes // to improve performance. match dim { 2 => { for out in out.chunks_exact_mut(2) { let vq = codebook.read_vq(bs)?; // Amortize the cost of the bounds check. let v: [f32; 2] = vq.try_into().unwrap(); out[0] += v[0]; out[1] += v[1]; } } 4 => { for out in out.chunks_exact_mut(4) { let vq = codebook.read_vq(bs)?; let v: [f32; 4] = vq.try_into().unwrap(); out[0] += v[0]; out[1] += v[1]; out[2] += v[2]; out[3] += v[3]; } } _ => { for out in out.chunks_exact_mut(dim) { let vq = codebook.read_vq(bs)?; for (o, &v) in out.iter_mut().zip(vq) { *o += v; } } } } Ok(()) } symphonia-codec-vorbis-0.5.2/src/window.rs000064400000000000000000000021731046102023000166630ustar 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::f64::consts; /// For a given window size, generates the curve of the left-half of the window. fn generate_win_curve(bs: usize) -> Vec { let len = bs / 2; let denom = f64::from(len as u32); let mut slope = vec![0.0; len]; for (i, s) in slope.iter_mut().enumerate() { let num = f64::from(i as u32) + 0.5; let frac = consts::FRAC_PI_2 * (num / denom); *s = (consts::FRAC_PI_2 * frac.sin().powi(2)).sin() as f32 } slope } pub struct Windows { /// Short block window left-half curve. pub short: Vec, /// Long block window left-half curve. pub long: Vec, } impl Windows { pub fn new(blocksize0: usize, blocksize1: usize) -> Self { let short = generate_win_curve(blocksize0); let long = generate_win_curve(blocksize1); Windows { short, long } } }