X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-mpeg%2Fsrc%2Fcodecs%2Faac%2Fsbr%2Fbs.rs;fp=nihav-mpeg%2Fsrc%2Fcodecs%2Faac%2Fsbr%2Fbs.rs;h=292a32af9243522a614a6f73a1283bd994f47b69;hp=0000000000000000000000000000000000000000;hb=0e18270ddb438c765a4597404f9053a15ce84704;hpb=9c3cd867ce7645f6f828675bd5d383033d6263f7 diff --git a/nihav-mpeg/src/codecs/aac/sbr/bs.rs b/nihav-mpeg/src/codecs/aac/sbr/bs.rs new file mode 100644 index 0000000..292a32a --- /dev/null +++ b/nihav-mpeg/src/codecs/aac/sbr/bs.rs @@ -0,0 +1,584 @@ +use nihav_core::codecs::{DecoderResult, DecoderError}; +use nihav_core::io::bitreader::*; +use nihav_core::io::codebook::*; + +use super::{MAX_SLOTS, NUM_ENVELOPES, SBR_BANDS, SBRState, SBRChannel}; +use super::synth::QuantMode; + +#[derive(Clone,Copy,Debug,PartialEq)] +pub enum FrameClass { + FixFix, + FixVar, + VarFix, + VarVar, +} + +impl FrameClass { + fn read(br: &mut BitReader) -> DecoderResult { + Ok(match br.read(2)? { + 0 => Self::FixFix, + 1 => Self::FixVar, + 2 => Self::VarFix, + _ => Self::VarVar, + }) + } +} + +pub fn sbr_read_sce(br: &mut BitReader, orig_amp_res: bool, state: &SBRState, cbs: &SBRCodebooks, ch: &mut SBRChannel) -> DecoderResult<()> { + ch.qmode = QuantMode::Single; + if br.read_bool()? { + br.skip(4)?; + } + read_grid(br, ch)?; + read_dtdf(br, ch)?; + read_invf(br, ch, state)?; + ch.set_amp_res(orig_amp_res); + read_envelope(br, ch, false, cbs, state)?; + read_noise(br, ch, false, cbs, state)?; + read_sinusoidal_coding(br, ch, state)?; + read_extensions(br)?; + + Ok(()) +} +pub fn sbr_read_cpe(br: &mut BitReader, orig_amp_res: bool, state: &SBRState, cbs: &SBRCodebooks, ch: &mut [SBRChannel; 2]) -> DecoderResult<()> { + if br.read_bool()? { + br.skip(4)?; + br.skip(4)?; + } + let coupling = br.read_bool()?; + if coupling { + ch[0].qmode = QuantMode::Left; + ch[1].qmode = QuantMode::Right; + read_grid(br, &mut ch[0])?; + ch[1].fclass = ch[0].fclass; + ch[1].num_env = ch[0].num_env; + ch[1].env_border = ch[0].env_border; + ch[1].freq_res = ch[0].freq_res; + ch[1].pointer = ch[0].pointer; + ch[1].num_noise = ch[0].num_noise; + ch[1].noise_env_border = ch[0].noise_env_border; + + read_dtdf(br, &mut ch[0])?; + read_dtdf(br, &mut ch[1])?; + read_invf(br, &mut ch[0], state)?; + ch[1].invf_mode = ch[0].invf_mode; + + ch[0].set_amp_res(orig_amp_res); + read_envelope(br, &mut ch[0], false, cbs, state)?; + read_noise(br, &mut ch[0], false, cbs, state)?; + ch[1].set_amp_res(orig_amp_res); + read_envelope(br, &mut ch[1], true, cbs, state)?; + read_noise(br, &mut ch[1], true, cbs, state)?; + + ch[0].data_env2 = ch[1].data_env; + ch[0].data_noise2 = ch[1].data_noise; + ch[1].data_env2 = ch[0].data_env; + ch[1].data_noise2 = ch[0].data_noise; + } else { + ch[0].qmode = QuantMode::Single; + ch[1].qmode = QuantMode::Single; + read_grid(br, &mut ch[0])?; + read_grid(br, &mut ch[1])?; + read_dtdf(br, &mut ch[0])?; + read_dtdf(br, &mut ch[1])?; + read_invf(br, &mut ch[0], state)?; + read_invf(br, &mut ch[1], state)?; + + ch[0].set_amp_res(orig_amp_res); + read_envelope(br, &mut ch[0], false, cbs, state)?; + ch[1].set_amp_res(orig_amp_res); + read_envelope(br, &mut ch[1], false, cbs, state)?; + read_noise(br, &mut ch[0], false, cbs, state)?; + read_noise(br, &mut ch[1], false, cbs, state)?; + } + read_sinusoidal_coding(br, &mut ch[0], state)?; + read_sinusoidal_coding(br, &mut ch[1], state)?; + read_extensions(br)?; + + Ok(()) +} + +fn read_grid(br: &mut BitReader, chan: &mut SBRChannel) -> DecoderResult<()> { + chan.fclass = FrameClass::read(br)?; + match chan.fclass { + FrameClass::FixFix => { + chan.num_env = 1 << br.read(2)?; + let freq_res = br.read_bool()?; + for el in chan.freq_res[..chan.num_env].iter_mut() { + *el = freq_res; + } + if chan.num_env > 1 { + let delta = (MAX_SLOTS + chan.num_env / 2) / chan.num_env; + chan.env_border[0] = delta; + for i in 0..chan.num_env - 1 { + chan.env_border[i + 1] = chan.env_border[i] + delta; + } + } + chan.env_border[chan.num_env - 1] = MAX_SLOTS; + }, + FrameClass::FixVar => { + let var_bord_1 = br.read(2)? as u8; + chan.num_env = br.read(2)? as usize + 1; + let mut rel_bord_1 = [0u8; NUM_ENVELOPES]; + for el in rel_bord_1[..chan.num_env - 1].iter_mut() { + *el = 2 * (br.read(2)? as u8) + 2; + } + let ptr_bits = 8 - (chan.num_env as u8).leading_zeros(); + chan.pointer = br.read(ptr_bits as u8)? as u8; + for el in chan.freq_res[..chan.num_env].iter_mut().rev() { + *el = br.read_bool()?; + } + + chan.env_border[chan.num_env - 1] = MAX_SLOTS + usize::from(var_bord_1); + for (i, &delta) in (1..chan.num_env).rev().zip(rel_bord_1.iter()) { + chan.env_border[i - 1] = chan.env_border[i] - usize::from(delta); + } + }, + FrameClass::VarFix => { + let var_bord_0 = br.read(2)? as u8; + chan.num_env = br.read(2)? as usize + 1; + let mut rel_bord_0 = [0u8; NUM_ENVELOPES]; + for el in rel_bord_0[..chan.num_env - 1].iter_mut() { + *el = 2 * (br.read(2)? as u8) + 2; + } + let ptr_bits = 8 - (chan.num_env as u8).leading_zeros(); + chan.pointer = br.read(ptr_bits as u8)? as u8; + for el in chan.freq_res[..chan.num_env].iter_mut() { + *el = br.read_bool()?; + } + + chan.env_border[0] = usize::from(var_bord_0 + rel_bord_0[0]); + for i in 1..chan.num_env { + chan.env_border[i] = chan.env_border[i - 1] + usize::from(rel_bord_0[i]); + } + chan.env_border[chan.num_env - 1] = MAX_SLOTS; + }, + FrameClass::VarVar => { + let var_bord_0 = br.read(2)? as u8; + let var_bord_1 = br.read(2)? as u8; + let num_rel_0 = br.read(2)? as usize; + let num_rel_1 = br.read(2)? as usize; + chan.num_env = (num_rel_0 as usize) + (num_rel_1 as usize) + 1; + let mut rel_bord_0 = [0u8; NUM_ENVELOPES]; + let mut rel_bord_1 = [0u8; NUM_ENVELOPES]; + for el in rel_bord_0[..num_rel_0].iter_mut() { + *el = 2 * (br.read(2)? as u8) + 2; + } + for el in rel_bord_1[..num_rel_1].iter_mut() { + *el = 2 * (br.read(2)? as u8) + 2; + } + let ptr_bits = 8 - (chan.num_env as u8).leading_zeros(); + chan.pointer = br.read(ptr_bits as u8)? as u8; + for el in chan.freq_res[..chan.num_env].iter_mut() { + *el = br.read_bool()?; + } + + chan.env_border[0] = usize::from(var_bord_0 + rel_bord_0[0]); + for i in 1..=num_rel_0 { + chan.env_border[i] = chan.env_border[i - 1] + usize::from(rel_bord_0[i]); + } + chan.env_border[chan.num_env - 1] = MAX_SLOTS + usize::from(var_bord_1); + for i in 0..num_rel_1 { + chan.env_border[chan.num_env - 2 - i] = chan.env_border[chan.num_env - 1 - i] - usize::from(rel_bord_1[i]); + } + }, + }; + for i in 0..chan.num_env - 1 { + validate!(chan.env_border[i] < chan.env_border[i + 1]); + } + + if chan.num_env > 1 { + chan.num_noise = 2; + let mid = match (chan.fclass, chan.pointer) { + (FrameClass::FixFix, _) => chan.num_env / 2 - 1, + (FrameClass::VarFix, 0) => 0, + (FrameClass::VarFix, 1) => chan.num_env - 2, + (FrameClass::VarFix, _) => chan.pointer as usize - 2, + (_, 0) | (_, 1) => chan.num_env - 2, + (_, _) => chan.num_env - (chan.pointer as usize), + }; + chan.noise_env_border[0] = chan.env_border[mid]; + chan.noise_env_border[1] = chan.env_border[chan.num_env - 1]; + } else { + chan.num_noise = 1; + chan.noise_env_border[0] = chan.env_border[0]; + } + + + Ok(()) +} +fn read_dtdf(br: &mut BitReader, chan: &mut SBRChannel) -> DecoderResult<()> { + for el in chan.df_env[..chan.num_env].iter_mut() { + *el = br.read_bool()?; + } + for el in chan.df_noise[..chan.num_noise].iter_mut() { + *el = br.read_bool()?; + } + Ok(()) +} +fn read_invf(br: &mut BitReader, chan: &mut SBRChannel, state: &SBRState) -> DecoderResult<()> { + for el in chan.invf_mode[..state.num_noise_bands].iter_mut() { + *el = br.read(2)? as u8; + } + Ok(()) +} +fn read_envelope(br: &mut BitReader, chan: &mut SBRChannel, coupled: bool, cbs: &SBRCodebooks, state: &SBRState) -> DecoderResult<()> { + let (f_cb, t_cb) = if coupled { + if chan.amp_res { + (&cbs.env_bal_3_0db_f_cb, &cbs.env_bal_3_0db_t_cb) + } else { + (&cbs.env_bal_1_5db_f_cb, &cbs.env_bal_1_5db_t_cb) + } + } else { + if chan.amp_res { + (&cbs.env_3_0db_f_cb, &cbs.env_3_0db_t_cb) + } else { + (&cbs.env_1_5db_f_cb, &cbs.env_1_5db_t_cb) + } + }; + let scale = if coupled { 2 } else { 1 }; + for (envelope, (&df_env, &freq_res)) in chan.data_env[..chan.num_env].iter_mut().zip(chan.df_env.iter().zip(chan.freq_res.iter())) { + let num_env_bands = state.num_env_bands[freq_res as usize]; + if !df_env { + if coupled { + envelope[0] = br.read(5 + (!chan.amp_res as u8))? as i8; + } else { + envelope[0] = br.read(6 + (!chan.amp_res as u8))? as i8; + } + envelope[0] *= scale; + let mut last = envelope[0]; + for band_env in envelope[1..num_env_bands].iter_mut() { + let delta = br.read_cb(f_cb)?; + *band_env = last + delta * scale; + last = *band_env + } + } else { + for (i, band_env) in envelope[..num_env_bands].iter_mut().enumerate() { + let delta = br.read_cb(t_cb)?; + let last = match (freq_res, chan.last_freq_res) { + (true, false) => chan.last_envelope[state.high_to_low_res[i]], + (false, true) => chan.last_envelope[state.low_to_high_res[i]], + _ => chan.last_envelope[i], + }; + *band_env = last + delta * scale; + } + } + chan.last_envelope = *envelope; + chan.last_freq_res = freq_res; + } + Ok(()) +} +fn read_noise(br: &mut BitReader, chan: &mut SBRChannel, coupled: bool, cbs: &SBRCodebooks, state: &SBRState) -> DecoderResult<()> { + let (f_cb, t_cb) = if coupled { + (&cbs.env_bal_3_0db_f_cb, &cbs.noise_bal_3_0db_t_cb) + } else { + (&cbs.env_3_0db_f_cb, &cbs.noise_3_0db_t_cb) + }; + let scale = if coupled { 2 } else { 1 }; + for (noise, &df_noise) in chan.data_noise[..chan.num_noise].iter_mut().zip(chan.df_noise.iter()) { + if !df_noise { + noise[0] = (br.read(5)? as i8) * scale; + let mut last = noise[0]; + for band_noise in noise[1..state.num_noise_bands].iter_mut() { + let delta = br.read_cb(f_cb)?; + *band_noise = last + scale * delta; + last = *band_noise; + } + } else { + for (band_noise, &last) in noise[..state.num_noise_bands].iter_mut().zip(chan.last_noise_env.iter()) { + let delta = br.read_cb(t_cb)?; + *band_noise = last + delta * scale; + } + } + chan.last_noise_env = *noise; + } + Ok(()) +} +fn read_sinusoidal_coding(br: &mut BitReader, chan: &mut SBRChannel, state: &SBRState) -> DecoderResult<()> { + if !br.read_bool()? { + chan.add_harmonic = [false; SBR_BANDS]; + return Ok(()); + } + for el in chan.add_harmonic[..state.num_env_bands[1]].iter_mut() { + *el = br.read_bool()?; + } + Ok(()) +} +fn read_extensions(br: &mut BitReader) -> DecoderResult<()> { + if br.read_bool()? { + let mut size = br.read(4)? as usize; + if size == 15 { + size += br.read(8)? as usize; + } + validate!(br.left() >= ((size * 8) as isize)); + let end = br.tell() + size * 8; + while br.tell() + 7 < end { + let _extension_id = br.read(2)?; + // todo parse PS? + } + } + Ok(()) +} + +pub struct SBRCodebooks { + env_bal_1_5db_f_cb: Codebook, + env_bal_1_5db_t_cb: Codebook, + env_bal_3_0db_f_cb: Codebook, + env_bal_3_0db_t_cb: Codebook, + env_1_5db_f_cb: Codebook, + env_1_5db_t_cb: Codebook, + env_3_0db_f_cb: Codebook, + env_3_0db_t_cb: Codebook, + noise_bal_3_0db_t_cb: Codebook, + noise_3_0db_t_cb: Codebook, +} + +fn map_idx12(idx: usize) -> i8 { idx as i8 - 12 } +fn map_idx24(idx: usize) -> i8 { idx as i8 - 24 } +fn map_idx31(idx: usize) -> i8 { idx as i8 - 31 } +fn map_idx60(idx: usize) -> i8 { idx as i8 - 60 } + +impl SBRCodebooks { + pub fn new() -> Self { + let mut cbr = TableCodebookDescReader::new(ENV_BAL_1_5DB_F_BITS, ENV_BAL_1_5DB_F_LENS, map_idx24); + let env_bal_1_5db_f_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + let mut cbr = TableCodebookDescReader::new(ENV_BAL_1_5DB_T_BITS, ENV_BAL_1_5DB_T_LENS, map_idx24); + let env_bal_1_5db_t_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + + let mut cbr = TableCodebookDescReader::new(ENV_1_5DB_F_BITS, ENV_1_5DB_F_LENS, map_idx60); + let env_1_5db_f_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + let mut cbr = TableCodebookDescReader::new(ENV_1_5DB_T_BITS, ENV_1_5DB_T_LENS, map_idx60); + let env_1_5db_t_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + + let mut cbr = TableCodebookDescReader::new(ENV_BAL_3_0DB_F_BITS, ENV_BAL_3_0DB_F_LENS, map_idx12); + let env_bal_3_0db_f_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + let mut cbr = TableCodebookDescReader::new(ENV_BAL_3_0DB_T_BITS, ENV_BAL_3_0DB_T_LENS, map_idx12); + let env_bal_3_0db_t_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + + let mut cbr = TableCodebookDescReader::new(ENV_3_0DB_F_BITS, ENV_3_0DB_F_LENS, map_idx31); + let env_3_0db_f_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + let mut cbr = TableCodebookDescReader::new(ENV_3_0DB_T_BITS, ENV_3_0DB_T_LENS, map_idx31); + let env_3_0db_t_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + + let mut cbr = TableCodebookDescReader::new(NOISE_BAL_3_0DB_T_BITS, NOISE_BAL_3_0DB_T_LENS, map_idx12); + let noise_bal_3_0db_t_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + let mut cbr = TableCodebookDescReader::new(NOISE_3_0DB_T_BITS, NOISE_3_0DB_T_LENS, map_idx31); + let noise_3_0db_t_cb = Codebook::new(&mut cbr, CodebookMode::MSB).unwrap(); + + Self { + env_bal_1_5db_f_cb, env_bal_1_5db_t_cb, + env_1_5db_f_cb, env_1_5db_t_cb, + env_bal_3_0db_f_cb, env_bal_3_0db_t_cb, + env_3_0db_f_cb, env_3_0db_t_cb, + noise_3_0db_t_cb, noise_bal_3_0db_t_cb + } + } +} + +const ENV_1_5DB_F_BITS: &[u32; 121] = &[ + 0x7ffe7, 0x7ffe8, 0xfffd2, 0xfffd3, 0xfffd4, 0xfffd5, 0xfffd6, 0xfffd7, + 0xfffd8, 0x7ffda, 0xfffd9, 0xfffda, 0xfffdb, 0xfffdc, 0x7ffdb, 0xfffdd, + 0x7ffdc, 0x7ffdd, 0xfffde, 0x3ffe4, 0xfffdf, 0xfffe0, 0xfffe1, 0x7ffde, + 0xfffe2, 0xfffe3, 0xfffe4, 0x7ffdf, 0xfffe5, 0x7ffe0, 0x3ffe8, 0x7ffe1, + 0x3ffe0, 0x3ffe9, 0x1ffef, 0x3ffe5, 0x1ffec, 0x1ffed, 0x1ffee, 0x0fff4, + 0x0fff3, 0x0fff0, 0x07ff7, 0x07ff6, 0x03ffa, 0x01ffa, 0x01ff9, 0x00ffa, + 0x00ff8, 0x007f9, 0x003fb, 0x001fc, 0x001fa, 0x000fb, 0x0007c, 0x0003c, + 0x0001c, 0x0000c, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000d, 0x0001d, + 0x0003d, 0x000fa, 0x000fc, 0x001fb, 0x003fa, 0x007f8, 0x007fa, 0x007fb, + 0x00ff9, 0x00ffb, 0x01ff8, 0x01ffb, 0x03ff8, 0x03ff9, 0x0fff1, 0x0fff2, + 0x1ffea, 0x1ffeb, 0x3ffe1, 0x3ffe2, 0x3ffea, 0x3ffe3, 0x3ffe6, 0x3ffe7, + 0x3ffeb, 0xfffe6, 0x7ffe2, 0xfffe7, 0xfffe8, 0xfffe9, 0xfffea, 0xfffeb, + 0xfffec, 0x7ffe3, 0xfffed, 0xfffee, 0xfffef, 0xffff0, 0x7ffe4, 0xffff1, + 0x3ffec, 0xffff2, 0xffff3, 0x7ffe5, 0x7ffe6, 0xffff4, 0xffff5, 0xffff6, + 0xffff7, 0xffff8, 0xffff9, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, + 0xfffff +]; +const ENV_1_5DB_F_LENS: &[u8; 121] = &[ + 19, 19, 20, 20, 20, 20, 20, 20, + 20, 19, 20, 20, 20, 20, 19, 20, + 19, 19, 20, 18, 20, 20, 20, 19, + 20, 20, 20, 19, 20, 19, 18, 19, + 18, 18, 17, 18, 17, 17, 17, 16, + 16, 16, 15, 15, 14, 13, 13, 12, + 12, 11, 10, 9, 9, 8, 7, 6, + 5, 4, 3, 2, 2, 3, 4, 5, + 6, 8, 8, 9, 10, 11, 11, 11, + 12, 12, 13, 13, 14, 14, 16, 16, + 17, 17, 18, 18, 18, 18, 18, 18, + 18, 20, 19, 20, 20, 20, 20, 20, + 20, 19, 20, 20, 20, 20, 19, 20, + 18, 20, 20, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20 +]; +const ENV_1_5DB_T_BITS: &[u32; 121] = &[ + 0x3ffd6, 0x3ffd7, 0x3ffd8, 0x3ffd9, 0x3ffda, 0x3ffdb, 0x7ffb8, 0x7ffb9, + 0x7ffba, 0x7ffbb, 0x7ffbc, 0x7ffbd, 0x7ffbe, 0x7ffbf, 0x7ffc0, 0x7ffc1, + 0x7ffc2, 0x7ffc3, 0x7ffc4, 0x7ffc5, 0x7ffc6, 0x7ffc7, 0x7ffc8, 0x7ffc9, + 0x7ffca, 0x7ffcb, 0x7ffcc, 0x7ffcd, 0x7ffce, 0x7ffcf, 0x7ffd0, 0x7ffd1, + 0x7ffd2, 0x7ffd3, 0x1ffe6, 0x3ffd4, 0x0fff0, 0x1ffe9, 0x3ffd5, 0x1ffe7, + 0x0fff1, 0x0ffec, 0x0ffed, 0x0ffee, 0x07ff4, 0x03ff9, 0x03ff7, 0x01ffa, + 0x01ff9, 0x00ffb, 0x007fc, 0x003fc, 0x001fd, 0x000fd, 0x0007d, 0x0003d, + 0x0001d, 0x0000d, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000c, 0x0001c, + 0x0003c, 0x0007c, 0x000fc, 0x001fc, 0x003fd, 0x00ffa, 0x01ff8, 0x03ff6, + 0x03ff8, 0x07ff5, 0x0ffef, 0x1ffe8, 0x0fff2, 0x7ffd4, 0x7ffd5, 0x7ffd6, + 0x7ffd7, 0x7ffd8, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, 0x7ffde, + 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffe6, + 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffec, 0x7ffed, 0x7ffee, + 0x7ffef, 0x7fff0, 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, + 0x7fff7, 0x7fff8, 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, + 0x7ffff +]; +const ENV_1_5DB_T_LENS: &[u8; 121] = &[ + 18, 18, 18, 18, 18, 18, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 17, 18, 16, 17, 18, 17, + 16, 16, 16, 16, 15, 14, 14, 13, + 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 2, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 12, 13, 14, + 14, 15, 16, 17, 16, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19 +]; + +const ENV_BAL_1_5DB_F_BITS: &[u32; 49] = &[ + 0x3ffe2, 0x3ffe3, 0x3ffe4, 0x3ffe5, 0x3ffe6, 0x3ffe7, 0x3ffe8, 0x3ffe9, + 0x3ffea, 0x3ffeb, 0x3ffec, 0x3ffed, 0x3ffee, 0x3ffef, 0x3fff0, 0x0fff7, + 0x1fff0, 0x03ffc, 0x007fe, 0x007fc, 0x000fe, 0x0007e, 0x0000e, 0x00002, + 0x00000, 0x00006, 0x0001e, 0x0003e, 0x001fe, 0x007fd, 0x00ffe, 0x07ffa, + 0x0fff6, 0x3fff1, 0x3fff2, 0x3fff3, 0x3fff4, 0x3fff5, 0x3fff6, 0x3fff7, + 0x3fff8, 0x3fff9, 0x3fffa, 0x3fffb, 0x3fffc, 0x3fffd, 0x3fffe, 0x7fffe, + 0x7ffff +]; +const ENV_BAL_1_5DB_F_LENS: &[u8; 49] = &[ + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 16, + 17, 14, 11, 11, 8, 7, 4, 2, + 1, 3, 5, 6, 9, 11, 12, 15, + 16, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, + 19 +]; +const ENV_BAL_1_5DB_T_BITS: &[u32; 49] = &[ + 0x0ffe4, 0x0ffe5, 0x0ffe6, 0x0ffe7, 0x0ffe8, 0x0ffe9, 0x0ffea, 0x0ffeb, + 0x0ffec, 0x0ffed, 0x0ffee, 0x0ffef, 0x0fff0, 0x0fff1, 0x0fff2, 0x0fff3, + 0x0fff4, 0x0ffe2, 0x00ffc, 0x007fc, 0x001fe, 0x0007e, 0x0001e, 0x00006, + 0x00000, 0x00002, 0x0000e, 0x0003e, 0x000fe, 0x007fd, 0x00ffd, 0x07ff0, + 0x0ffe3, 0x0fff5, 0x0fff6, 0x0fff7, 0x0fff8, 0x0fff9, 0x0fffa, 0x1fff6, + 0x1fff7, 0x1fff8, 0x1fff9, 0x1fffa, 0x1fffb, 0x1fffc, 0x1fffd, 0x1fffe, + 0x1ffff +]; +const ENV_BAL_1_5DB_T_LENS: &[u8; 49] = &[ + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 12, 11, 9, 7, 5, 3, + 1, 2, 4, 6, 8, 11, 12, 15, + 16, 16, 16, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17 +]; + +const ENV_3_0DB_F_BITS: &[u32; 63] = &[ + 0xffff0, 0xffff1, 0xffff2, 0xffff3, 0xffff4, 0xffff5, 0xffff6, 0x3fff3, + 0x7fff5, 0x7ffee, 0x7ffef, 0x7fff6, 0x3fff4, 0x3fff2, 0xffff7, 0x7fff0, + 0x1fff5, 0x3fff0, 0x1fff4, 0x0fff7, 0x0fff6, 0x07ff8, 0x03ffb, 0x00ffd, + 0x007fd, 0x003fd, 0x001fd, 0x000fd, 0x0003e, 0x0000e, 0x00002, 0x00000, + 0x00006, 0x0001e, 0x000fc, 0x001fc, 0x003fc, 0x007fc, 0x00ffc, 0x01ffc, + 0x03ffa, 0x07ff9, 0x07ffa, 0x0fff8, 0x0fff9, 0x1fff6, 0x1fff7, 0x3fff5, + 0x3fff6, 0x3fff1, 0xffff8, 0x7fff1, 0x7fff2, 0x7fff3, 0xffff9, 0x7fff7, + 0x7fff4, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, 0xfffff +]; +const ENV_3_0DB_F_LENS: &[u8; 63] = &[ + 20, 20, 20, 20, 20, 20, 20, 18, + 19, 19, 19, 19, 18, 18, 20, 19, + 17, 18, 17, 16, 16, 15, 14, 12, + 11, 10, 9, 8, 6, 4, 2, 1, + 3, 5, 8, 9, 10, 11, 12, 13, + 14, 15, 15, 16, 16, 17, 17, 18, + 18, 18, 20, 19, 19, 19, 20, 19, + 19, 20, 20, 20, 20, 20, 20 +]; +const ENV_3_0DB_T_BITS: &[u32; 63] = &[ + 0x3ffed, 0x3ffee, 0x7ffde, 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, + 0x7ffe4, 0x7ffe5, 0x7ffe6, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, + 0x7ffec, 0x1fff4, 0x0fff7, 0x0fff9, 0x0fff8, 0x03ffb, 0x03ffa, 0x03ff8, + 0x01ffa, 0x00ffc, 0x007fc, 0x000fe, 0x0003e, 0x0000e, 0x00002, 0x00000, + 0x00006, 0x0001e, 0x0007e, 0x001fe, 0x007fd, 0x01ffb, 0x03ff9, 0x03ffc, + 0x07ffa, 0x0fff6, 0x1fff5, 0x3ffec, 0x7ffed, 0x7ffee, 0x7ffef, 0x7fff0, + 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, 0x7fff7, 0x7fff8, + 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, 0x7ffff +]; +const ENV_3_0DB_T_LENS: &[u8; 63] = &[ + 18, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 17, 16, 16, 16, 14, 14, 14, + 13, 12, 11, 8, 6, 4, 2, 1, + 3, 5, 7, 9, 11, 13, 14, 14, + 15, 16, 17, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19 +]; + +const ENV_BAL_3_0DB_F_BITS: &[u16; 25] = &[ + 0x1ff7, 0x1ff8, 0x1ff9, 0x1ffa, 0x1ffb, 0x3ff8, 0x3ff9, 0x07fc, + 0x00fe, 0x007e, 0x000e, 0x0002, 0x0000, 0x0006, 0x001e, 0x003e, + 0x01fe, 0x0ffa, 0x1ff6, 0x3ffa, 0x3ffb, 0x3ffc, 0x3ffd, 0x3ffe, + 0x3fff +]; +const ENV_BAL_3_0DB_F_LENS: &[u8; 25] = &[ + 13, 13, 13, 13, 13, 14, 14, 11, + 8, 7, 4, 2, 1, 3, 5, 6, + 9, 12, 13, 14, 14, 14, 14, 14, + 14 +]; +const ENV_BAL_3_0DB_T_BITS: &[u16; 25] = &[ + 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x0ff8, + 0x00fe, 0x007e, 0x000e, 0x0006, 0x0000, 0x0002, 0x001e, 0x003e, + 0x01fe, 0x1ff9, 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, + 0x3fff +]; +const ENV_BAL_3_0DB_T_LENS: &[u8; 25] = &[ + 13, 13, 13, 13, 13, 13, 13, 12, + 8, 7, 4, 3, 1, 2, 5, 6, + 9, 13, 13, 13, 13, 13, 13, 14, + 14 +]; + +const NOISE_3_0DB_T_BITS: &[u16; 63] = &[ + 0x1fce, 0x1fcf, 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, + 0x1fd6, 0x1fd7, 0x1fd8, 0x1fd9, 0x1fda, 0x1fdb, 0x1fdc, 0x1fdd, + 0x1fde, 0x1fdf, 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, + 0x1fe6, 0x1fe7, 0x07f2, 0x00fd, 0x003e, 0x000e, 0x0006, 0x0000, + 0x0002, 0x001e, 0x00fc, 0x03f8, 0x1fcc, 0x1fe8, 0x1fe9, 0x1fea, + 0x1feb, 0x1fec, 0x1fcd, 0x1fed, 0x1fee, 0x1fef, 0x1ff0, 0x1ff1, + 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x1ff9, + 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, 0x3fff +]; +const NOISE_3_0DB_T_LENS: &[u8; 63] = &[ + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 11, 8, 6, 4, 3, 1, + 2, 5, 8, 10, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 14, 14 +]; +const NOISE_BAL_3_0DB_T_BITS: &[u8; 25] = &[ + 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0x1c, 0x02, 0x00, 0x06, 0x3a, 0xf6, + 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, + 0xff +]; +const NOISE_BAL_3_0DB_T_LENS: &[u8; 25] = &[ + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 5, 2, 1, 3, 6, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8 +];