Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace lazy_static with phf and once_cell #143

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ BlackHoleFox [https://github.com/blackholefox]
darksv [https://github.com/darksv]
djugei [https://github.com/djugei]
FelixMcFelix [https://github.com/FelixMcFelix]
Gnome! [https://github.com/GnomedDev]
Herohtar [https://github.com/herohtar]
nicholaswyoung [https://github.com/nicholaswyoung]
richardmitic [https://github.com/richardmitic]
Expand Down
4 changes: 2 additions & 2 deletions symphonia-bundle-mp3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ rust-version = "1.53"

[dependencies]
log = "0.4"
once_cell = "1"
bitflags = "1.2.1"
lazy_static = "1.4.0"
symphonia-core = { version = "0.5", path = "../symphonia-core" }
symphonia-metadata = { version = "0.5", path = "../symphonia-metadata" }
symphonia-metadata = { version = "0.5", path = "../symphonia-metadata" }
64 changes: 29 additions & 35 deletions symphonia-bundle-mp3/src/codebooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

use symphonia_core::io::vlc::*;

use lazy_static::lazy_static;
use once_cell::sync::Lazy;

#[rustfmt::skip]
const MPEG_CODES_0: [u32; 0] = [ ];
Expand Down Expand Up @@ -559,48 +559,42 @@ fn mpeg_gen_value(i: u16, wrap: u16) -> u16 {
((i / wrap) << 4) | (i % wrap)
}

lazy_static! {
pub static ref CODEBOOK_TABLES: [Codebook<Entry16x16>; 18] = {
let mut codebooks: [Codebook<Entry16x16>; 18] = Default::default();
pub static CODEBOOK_TABLES: Lazy<[Codebook<Entry16x16>; 18]> = Lazy::new(|| {
let mut codebooks: [Codebook<Entry16x16>; 18] = Default::default();

for (codebook, table) in codebooks.iter_mut().zip(&MPEG_TABLES) {
assert!(table.codes.len() == table.lens.len());
for (codebook, table) in codebooks.iter_mut().zip(&MPEG_TABLES) {
assert!(table.codes.len() == table.lens.len());

let len = table.codes.len() as u16;
let len = table.codes.len() as u16;

// Generate values for the codebook.
let values: Vec<u16> = (0..len).into_iter()
.map(|i| mpeg_gen_value(i, table.wrap))
.collect();
// Generate values for the codebook.
let values: Vec<u16> =
(0..len).into_iter().map(|i| mpeg_gen_value(i, table.wrap)).collect();

// Generate the codebook.
let mut builder = CodebookBuilder::new(BitOrder::Verbatim);
*codebook = builder.make(table.codes, table.lens, &values).unwrap();
}
// Generate the codebook.
let mut builder = CodebookBuilder::new(BitOrder::Verbatim);
*codebook = builder.make(table.codes, table.lens, &values).unwrap();
}

codebooks
};
}
codebooks
});

lazy_static! {
pub static ref QUADS_CODEBOOK_TABLE: [Codebook<Entry16x16>; 2] = {
let mut codebooks: [Codebook<Entry16x16>; 2] = Default::default();
pub static QUADS_CODEBOOK_TABLE: Lazy<[Codebook<Entry16x16>; 2]> = Lazy::new(|| {
let mut codebooks: [Codebook<Entry16x16>; 2] = Default::default();

for (codebook, table) in codebooks.iter_mut().zip(&MPEG_QUADS_TABLES) {
assert!(table.codes.len() == table.lens.len());
for (codebook, table) in codebooks.iter_mut().zip(&MPEG_QUADS_TABLES) {
assert!(table.codes.len() == table.lens.len());

let len = table.codes.len() as u16;
let len = table.codes.len() as u16;

// Generate values for the codebook.
let values: Vec<u16> = (0..len).into_iter()
.map(|i| mpeg_gen_value(i, table.wrap))
.collect();
// Generate values for the codebook.
let values: Vec<u16> =
(0..len).into_iter().map(|i| mpeg_gen_value(i, table.wrap)).collect();

// Generate the codebook.
let mut builder = CodebookBuilder::new(BitOrder::Verbatim);
*codebook = builder.make(table.codes, table.lens, &values).unwrap();
}
// Generate the codebook.
let mut builder = CodebookBuilder::new(BitOrder::Verbatim);
*codebook = builder.make(table.codes, table.lens, &values).unwrap();
}

codebooks
};
}
codebooks
});
248 changes: 121 additions & 127 deletions symphonia-bundle-mp3/src/layer3/hybrid_synthesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,143 +10,137 @@

use std::{convert::TryInto, f64};

use lazy_static::lazy_static;
use once_cell::sync::Lazy;

use super::{BlockType, GranuleChannel};
use crate::common::*;

lazy_static! {
/// Hybrid synthesesis IMDCT window coefficients for: Long, Start, Short, and End block, in that
/// order.
///
/// For long blocks:
///
/// ```text
/// W[ 0..36] = sin(PI/36.0 * (i + 0.5))
/// ```
///
/// For start blocks:
///
/// ```text
/// W[ 0..18] = sin(PI/36.0 * (i + 0.5))
/// W[18..24] = 1.0
/// W[24..30] = sin(PI/12.0 * ((i - 18) - 0.5))
/// W[30..36] = 0.0
/// ```
///
/// For short blocks (to be applied to each 12 sample window):
///
/// ```text
/// W[ 0..12] = sin(PI/12.0 * (i + 0.5))
/// W[12..36] = 0.0
/// ```
///
/// For end blocks:
///
/// ```text
/// W[ 0..6 ] = 0.0
/// W[ 6..12] = sin(PI/12.0 * ((i - 6) + 0.5))
/// W[12..18] = 1.0
/// W[18..36] = sin(PI/36.0 * (i + 0.5))
/// ```
static ref IMDCT_WINDOWS: [[f32; 36]; 4] = {
const PI_36: f64 = f64::consts::PI / 36.0;
const PI_12: f64 = f64::consts::PI / 12.0;

let mut windows = [[0f32; 36]; 4];

// Window for Long blocks.
for i in 0..36 {
windows[0][i] = (PI_36 * (i as f64 + 0.5)).sin() as f32;
}

// Window for Start blocks (indicies 30..36 implictly 0.0).
for i in 0..18 {
windows[1][i] = (PI_36 * (i as f64 + 0.5)).sin() as f32;
}
for i in 18..24 {
windows[1][i] = 1.0;
}
for i in 24..30 {
windows[1][i] = (PI_12 * ((i - 18) as f64 + 0.5)).sin() as f32;
}

// Window for Short blocks.
for i in 0..12 {
windows[2][i] = (PI_12 * (i as f64 + 0.5)).sin() as f32;
}

// Window for End blocks (indicies 0..6 implicitly 0.0).
for i in 6..12 {
windows[3][i] = (PI_12 * ((i - 6) as f64 + 0.5)).sin() as f32;
}
for i in 12..18 {
windows[3][i] = 1.0;
}
for i in 18..36 {
windows[3][i] = (PI_36 * (i as f64 + 0.5)).sin() as f32;
}
/// Hybrid synthesesis IMDCT window coefficients for: Long, Start, Short, and End block, in that
/// order.
///
/// For long blocks:
///
/// ```text
/// W[ 0..36] = sin(PI/36.0 * (i + 0.5))
/// ```
///
/// For start blocks:
///
/// ```text
/// W[ 0..18] = sin(PI/36.0 * (i + 0.5))
/// W[18..24] = 1.0
/// W[24..30] = sin(PI/12.0 * ((i - 18) - 0.5))
/// W[30..36] = 0.0
/// ```
///
/// For short blocks (to be applied to each 12 sample window):
///
/// ```text
/// W[ 0..12] = sin(PI/12.0 * (i + 0.5))
/// W[12..36] = 0.0
/// ```
///
/// For end blocks:
///
/// ```text
/// W[ 0..6 ] = 0.0
/// W[ 6..12] = sin(PI/12.0 * ((i - 6) + 0.5))
/// W[12..18] = 1.0
/// W[18..36] = sin(PI/36.0 * (i + 0.5))
/// ```
static IMDCT_WINDOWS: Lazy<[[f32; 36]; 4]> = Lazy::new(|| {
const PI_36: f64 = f64::consts::PI / 36.0;
const PI_12: f64 = f64::consts::PI / 12.0;

let mut windows = [[0f32; 36]; 4];

// Window for Long blocks.
for i in 0..36 {
windows[0][i] = (PI_36 * (i as f64 + 0.5)).sin() as f32;
}

windows
};
}
// Window for Start blocks (indicies 30..36 implictly 0.0).
for i in 0..18 {
windows[1][i] = (PI_36 * (i as f64 + 0.5)).sin() as f32;
}
for i in 18..24 {
windows[1][i] = 1.0;
}
for i in 24..30 {
windows[1][i] = (PI_12 * ((i - 18) as f64 + 0.5)).sin() as f32;
}

lazy_static! {
/// Lookup table of cosine coefficients for half of a 12-point IMDCT.
///
/// This table is derived from the general expression:
///
/// ```text
/// cos12[i][k] = cos(PI/24.0 * (2*i + 1 + N/2) * (2*k + 1))
/// ```
/// where:
/// `N=12`, `i=N/4..3N/4`, and `k=0..N/2`.
static ref IMDCT_HALF_COS_12: [[f32; 6]; 6] = {
const PI_24: f64 = f64::consts::PI / 24.0;
// Window for Short blocks.
for i in 0..12 {
windows[2][i] = (PI_12 * (i as f64 + 0.5)).sin() as f32;
}

let mut cos = [[0f32; 6]; 6];
// Window for End blocks (indicies 0..6 implicitly 0.0).
for i in 6..12 {
windows[3][i] = (PI_12 * ((i - 6) as f64 + 0.5)).sin() as f32;
}
for i in 12..18 {
windows[3][i] = 1.0;
}
for i in 18..36 {
windows[3][i] = (PI_36 * (i as f64 + 0.5)).sin() as f32;
}

for (i, cos_i) in cos.iter_mut().enumerate() {
for (k, cos_ik) in cos_i.iter_mut().enumerate() {
// Only compute the middle half of the cosine lookup table (i offset by 3).
let n = (2 * (i + 3) + (12 / 2) + 1) * (2 * k + 1);
*cos_ik = (PI_24 * n as f64).cos() as f32;
}
windows
});

/// Lookup table of cosine coefficients for half of a 12-point IMDCT.
///
/// This table is derived from the general expression:
///
/// ```text
/// cos12[i][k] = cos(PI/24.0 * (2*i + 1 + N/2) * (2*k + 1))
/// ```
/// where:
/// `N=12`, `i=N/4..3N/4`, and `k=0..N/2`.
static IMDCT_HALF_COS_12: Lazy<[[f32; 6]; 6]> = Lazy::new(|| {
const PI_24: f64 = f64::consts::PI / 24.0;

let mut cos = [[0f32; 6]; 6];

for (i, cos_i) in cos.iter_mut().enumerate() {
for (k, cos_ik) in cos_i.iter_mut().enumerate() {
// Only compute the middle half of the cosine lookup table (i offset by 3).
let n = (2 * (i + 3) + (12 / 2) + 1) * (2 * k + 1);
*cos_ik = (PI_24 * n as f64).cos() as f32;
}
}

cos
};
}

lazy_static! {
/// Pair of lookup tables, CS and CA, for alias reduction.
///
/// As per ISO/IEC 11172-3, CS and CA are calculated as follows:
///
/// ```text
/// cs[i] = 1.0 / sqrt(1.0 + c[i]^2)
/// ca[i] = c[i] / sqrt(1.0 + c[i]^2)
/// ```
///
/// where:
/// ```text
/// c[i] = [ -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 ]
/// ```
static ref ANTIALIAS_CS_CA: ([f32; 8], [f32; 8]) = {
const C: [f64; 8] = [ -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 ];

let mut cs = [0f32; 8];
let mut ca = [0f32; 8];

for i in 0..8 {
let sqrt = f64::sqrt(1.0 + (C[i] * C[i]));
cs[i] = (1.0 / sqrt) as f32;
ca[i] = (C[i] / sqrt) as f32;
}
cos
});

/// Pair of lookup tables, CS and CA, for alias reduction.
///
/// As per ISO/IEC 11172-3, CS and CA are calculated as follows:
///
/// ```text
/// cs[i] = 1.0 / sqrt(1.0 + c[i]^2)
/// ca[i] = c[i] / sqrt(1.0 + c[i]^2)
/// ```
///
/// where:
/// ```text
/// c[i] = [ -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 ]
/// ```
static ANTIALIAS_CS_CA: Lazy<([f32; 8], [f32; 8])> = Lazy::new(|| {
const C: [f64; 8] = [-0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037];

let mut cs = [0f32; 8];
let mut ca = [0f32; 8];

for i in 0..8 {
let sqrt = f64::sqrt(1.0 + (C[i] * C[i]));
cs[i] = (1.0 / sqrt) as f32;
ca[i] = (C[i] / sqrt) as f32;
}

(cs, ca)
};
}
(cs, ca)
});

/// Reorder samples that are part of short blocks into sub-band order.
pub(super) fn reorder(header: &FrameHeader, channel: &GranuleChannel, buf: &mut [f32; 576]) {
Expand Down Expand Up @@ -226,7 +220,7 @@ pub(super) fn antialias(channel: &GranuleChannel, samples: &mut [f32; 576]) {
_ => 32 * 18,
};

// Amortize the lazy_static fetch over the entire anti-aliasing operation.
// Amortize the Lazy fetch over the entire anti-aliasing operation.
let (cs, ca): &([f32; 8], [f32; 8]) = &ANTIALIAS_CS_CA;

// Anti-aliasing is performed using 8 butterfly calculations at the boundaries of ADJACENT
Expand Down
Loading