pub const BITRATE_V1_L3: [u32; 16] = [
0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0,
];
pub const BITRATE_V2_L3: [u32; 16] = [
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0,
];
pub const SAMPLE_RATE: [u32; 4] = [44100, 48000, 32000, 0];
pub const SCALEFAC_COMPRESS_V1: [(u8, u8); 16] = [
(0, 0),
(0, 1),
(0, 2),
(0, 3),
(3, 0),
(1, 1),
(1, 2),
(1, 3),
(2, 1),
(2, 2),
(2, 3),
(3, 1),
(3, 2),
(3, 3),
(4, 2),
(4, 3),
];
pub const SFB_OFFSET_LONG_V1: [[u16; 23]; 3] = [
[
0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342,
418, 576,
],
[
0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330,
384, 576,
],
[
0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448,
550, 576,
],
];
pub const SFB_OFFSET_SHORT_V1: [[u16; 14]; 3] = [
[0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192],
[0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192],
[0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192],
];
pub const SFB_OFFSET_LONG_V2: [[u16; 23]; 3] = [
[
0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
522, 576,
],
[
0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464,
540, 576,
],
[
0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
522, 576,
],
];
pub const SFB_OFFSET_SHORT_V2: [[u16; 14]; 3] = [
[0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192],
[0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192],
[0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192],
];
pub const SFB_OFFSET_LONG_V25_8000: [u16; 23] = [
0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 572,
574, 576,
];
pub const SFB_OFFSET_SHORT_V25_8000: [u16; 14] =
[0, 8, 16, 24, 36, 52, 72, 96, 124, 160, 162, 164, 166, 192];
pub fn sfb_long_offsets(sample_rate: u32) -> &'static [u16; 23] {
match sample_rate {
48000 => &SFB_OFFSET_LONG_V1[1],
32000 => &SFB_OFFSET_LONG_V1[2],
22050 | 11025 | 12000 => &SFB_OFFSET_LONG_V2[0],
24000 => &SFB_OFFSET_LONG_V2[1],
16000 => &SFB_OFFSET_LONG_V2[2],
8000 => &SFB_OFFSET_LONG_V25_8000, _ => &SFB_OFFSET_LONG_V1[0], }
}
pub fn sfb_short_offsets(sample_rate: u32) -> &'static [u16; 14] {
match sample_rate {
48000 => &SFB_OFFSET_SHORT_V1[1],
32000 => &SFB_OFFSET_SHORT_V1[2],
22050 => &SFB_OFFSET_SHORT_V2[0],
24000 => &SFB_OFFSET_SHORT_V2[1],
16000 | 11025 | 12000 => &SFB_OFFSET_SHORT_V2[2],
8000 => &SFB_OFFSET_SHORT_V25_8000,
_ => &SFB_OFFSET_SHORT_V1[0],
}
}
pub const PRETAB: [u8; 22] = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0,
];
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sfb_offsets_monotonic_and_complete() {
for row in &SFB_OFFSET_LONG_V1 {
assert_eq!(row[0], 0);
assert_eq!(
*row.last().unwrap(),
576,
"long bands must cover all 576 lines"
);
assert!(
row.windows(2).all(|w| w[0] < w[1]),
"long sfb strictly increasing"
);
}
for row in &SFB_OFFSET_SHORT_V1 {
assert_eq!(row[0], 0);
assert_eq!(*row.last().unwrap(), 192, "short window spans 576/3 lines");
assert!(
row.windows(2).all(|w| w[0] < w[1]),
"short sfb strictly increasing"
);
}
}
}
pub const POW43_LEN: usize = 8207;
pub const HUFFMAN_TABLE_COUNT: usize = 34;
pub const NR_OF_SFB_BLOCK: [[[u8; 4]; 3]; 6] = [
[[6, 5, 5, 5], [9, 9, 9, 9], [6, 9, 9, 9]],
[[6, 5, 7, 3], [9, 9, 12, 6], [6, 9, 12, 6]],
[[11, 10, 0, 0], [18, 18, 0, 0], [15, 18, 0, 0]],
[[7, 7, 7, 0], [12, 12, 12, 0], [6, 15, 12, 0]],
[[6, 6, 6, 3], [12, 9, 9, 6], [6, 12, 9, 6]],
[[8, 8, 5, 0], [15, 12, 9, 0], [6, 18, 9, 0]],
];
pub fn lsf_scale_params(scalefac_compress: u16, blocktype: usize) -> ([u8; 4], [u8; 4]) {
let sfc = scalefac_compress as u32;
let (slen, blocknumber) = if sfc < 400 {
(
[(sfc >> 4) / 5, (sfc >> 4) % 5, (sfc % 16) >> 2, sfc % 4],
0,
)
} else if sfc < 500 {
let s = sfc - 400;
([(s >> 2) / 5, (s >> 2) % 5, s % 4, 0], 1)
} else {
let s = sfc - 500;
([s / 3, s % 3, 0, 0], 2)
};
let nr = NR_OF_SFB_BLOCK[blocknumber][blocktype];
(
[slen[0] as u8, slen[1] as u8, slen[2] as u8, slen[3] as u8],
nr,
)
}