lc3_codec/decoder/
global_gain.rs

1use crate::common::complex::Scaler;
2#[allow(unused_imports)]
3use num_traits::real::Real;
4
5// checked against spec
6
7/// Adjusts the loudness for all spectral lines in the frame
8///
9/// # Arguments
10///
11/// * `frame_num_bits` - Number of bits in the frame
12/// * `fs_ind` - Sampling frequency index (e.g. 4 for 48khz)
13/// * `global_gain_index` - Computed global gain index (e.g 204)
14/// * `spec_lines` - All the spectral lines in a frame to be mutated
15pub fn apply_global_gain(frame_num_bits: usize, fs_ind: usize, global_gain_index: usize, spec_lines: &mut [Scaler]) {
16    let fs = fs_ind as i32 + 1;
17    let nbits = frame_num_bits as i32;
18    let gg_off = -((nbits / (10 * fs)).min(115)) - 105 - (5 * fs);
19    let exponent: Scaler = (global_gain_index as Scaler + gg_off as Scaler) / 28.0;
20    let gg = (10.0).powf(exponent);
21
22    for f in spec_lines.iter_mut() {
23        *f *= gg;
24    }
25}
26
27#[cfg(test)]
28mod tests {
29    extern crate std;
30    use super::*;
31
32    #[test]
33    fn global_gain_decode() {
34        let mut spec_lines = [1.0, 10.0, 100.0];
35
36        apply_global_gain(1200, 4, 204, &mut spec_lines);
37
38        assert_eq!(spec_lines, [61.0540199, 610.540199, 6105.40199])
39    }
40}