symphonia-codec-vorbis-0.5.4/.cargo_vcs_info.json0000644000000001640000000000100154270ustar { "git": { "sha1": "d3b7742fa73674b70d9ab80cc5f8384cc653df3a" }, "path_in_vcs": "symphonia-codec-vorbis" }symphonia-codec-vorbis-0.5.4/Cargo.toml0000644000000021650000000000100134300ustar # 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.4" 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.4" [dependencies.symphonia-utils-xiph] version = "0.5.4" symphonia-codec-vorbis-0.5.4/Cargo.toml.orig000064400000000000000000000012411046102023000171030ustar 00000000000000[package] name = "symphonia-codec-vorbis" version = "0.5.4" 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.4", path = "../symphonia-core" } symphonia-utils-xiph = { version = "0.5.4", path = "../symphonia-utils-xiph" }symphonia-codec-vorbis-0.5.4/README.md000064400000000000000000000012021046102023000154700ustar 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 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-codec-vorbis-0.5.4/src/codebook.rs000064400000000000000000000360701046102023000171460ustar 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).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.4/src/common.rs000064400000000000000000000101771046102023000166510ustar 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.4/src/dsp.rs000064400000000000000000000114251046102023000161440ustar 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.4/src/floor.rs000064400000000000000000000670171046102023000165070ustar 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.4/src/lib.rs000064400000000000000000000576761046102023000161460ustar 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..=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.4/src/residue.rs000064400000000000000000000455741046102023000170320ustar 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<()> { let result = if self.setup.residue_type == 2 { self.read_residue_inner_type_2(bs, bs_exp, codebooks, residue_channels, channels) } else { self.read_residue_inner_type_0_1(bs, bs_exp, codebooks, residue_channels, channels) }; // Read the residue, and ignore end-of-bitstream errors which are legal. match result { 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), }; // 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. if self.setup.residue_type == 2 { self.deinterleave_2(residue_channels, channels); } Ok(()) } /// Deinterleave samples from the type 2 format buffer into channel buffers. fn deinterleave_2(&mut self, residue_channels: &BitSet256, channels: &mut [DspChannel]) { match residue_channels.count() { 2 => { // Two channel deinterleave. let (ch0, ch1) = { let mut iter = residue_channels.iter(); // Get indicies of first two channels in the residue. let ch0 = iter.next().unwrap(); let ch1 = iter.next().unwrap(); // Get references to the channels. let (a, b) = channels.split_at_mut(ch0).1.split_at_mut(ch1); (&mut a[0], &mut b[0]) }; // Deinterleave. for ((buf, chan0), chan1) in self .type2_buf .chunks_exact(2) .zip(ch0.residue.iter_mut()) .zip(ch1.residue.iter_mut()) { *chan0 = buf[0]; *chan1 = buf[1]; } } stride => { // Generic deinterleave. 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; } } } } } fn read_residue_inner_type_2( &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 = ((1 << bs_exp) >> 1) * residue_channels.count(); // 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; // Reserve partition classification space. self.prepare_partition_classes(parts_to_read); // Reserve the type 2 interleave buffer storage, and zero all samples. self.prepare_type_2_format_buffer(full_residue_len); // If all channels are marked do-not-decode then exit immediately. let has_channel_to_decode = residue_channels.iter().fold(false, |val, ch| val | !channels[ch].do_not_decode); 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 { 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..], ); } // 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 { let vq_class = &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; // 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], )?; } } // End of partition batch iteration. } // End of pass iteration. } Ok(()) } fn read_residue_inner_type_0_1( &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 = (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; // Reserve partition classification space. self.prepare_partition_classes(parts_to_read * residue_channels.count()); let mut has_channel_to_decode = false; for ch in residue_channels.iter() { // Record if the channel needs to be decoded. has_channel_to_decode |= !channels[ch].do_not_decode; // Zero the channel residue buffer. channels[ch].residue[..full_residue_len].fill(0.0); } // If all channels are marked do-not-decode then exit immediately. 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 { 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]; // If the channel is marked do-not-decode, then advance to the next channel. if channel.do_not_decode { continue; } let class_idx = self.part_classes[part + parts_to_read * i] as usize; let vq_class = &self.setup.residue_vq_class[class_idx]; 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], ), _ => unreachable!(), }?; } } } // End of partition batch iteration. } // End of pass iteration. } Ok(()) } /// Ensures enough storage for `len` partition classes. #[inline] fn prepare_partition_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 /// buffer is zeroed. #[inline] fn prepare_type_2_format_buffer(&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.4/src/window.rs000064400000000000000000000021731046102023000166650ustar 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 } } }