1use crate::common::{complex::Scaler, config::FrameDuration};
2
3const I_BW_START_TABLE: [[usize; 4]; 4] = [[53, 0, 0, 0], [47, 59, 0, 0], [44, 54, 60, 0], [41, 51, 57, 61]];
6const I_BW_STOP_TABLE: [[usize; 4]; 4] = [[63, 0, 0, 0], [56, 63, 0, 0], [52, 59, 63, 0], [49, 55, 60, 63]];
7const I_BW_START_TABLE_7P5MS: [[usize; 4]; 4] = [[51, 0, 0, 0], [45, 58, 0, 0], [42, 53, 60, 0], [40, 51, 57, 61]];
8const I_BW_STOP_TABLE_7P5MS: [[usize; 4]; 4] = [[63, 0, 0, 0], [55, 63, 0, 0], [51, 58, 63, 0], [48, 55, 60, 63]];
9const NBITS_BW_TABLE: [usize; 5] = [0, 1, 2, 2, 3];
10
11const QUIETNESS_THRESH: [usize; 4] = [20, 10, 10, 10];
13
14const CUTOFF_THRESH: [usize; 4] = [15, 23, 20, 20];
16
17const L_10MS: [usize; 4] = [4, 4, 3, 1];
18const L_7P5MS: [usize; 4] = [4, 4, 3, 2];
19
20pub struct BandwidthDetector {
21 sample_freq_ind: usize, i_bw_start: &'static [usize],
23 i_bw_stop: &'static [usize],
24 l: &'static [usize],
25}
26
27pub struct BandwidthDetectorResult {
28 pub bandwidth_ind: usize,
29 pub nbits_bandwidth: usize,
30}
31
32impl BandwidthDetector {
33 pub fn new(frame_duration: FrameDuration, sample_freq_ind: usize) -> Self {
34 let (i_bw_start, i_bw_stop, l) = match frame_duration {
35 FrameDuration::TenMs => (
36 I_BW_START_TABLE[sample_freq_ind - 1].as_slice(),
37 I_BW_STOP_TABLE[sample_freq_ind - 1].as_slice(),
38 L_10MS.as_slice(),
39 ),
40 FrameDuration::SevenPointFiveMs => (
41 I_BW_START_TABLE_7P5MS[sample_freq_ind - 1].as_slice(),
42 I_BW_STOP_TABLE_7P5MS[sample_freq_ind - 1].as_slice(),
43 L_7P5MS.as_slice(),
44 ),
45 };
46
47 Self {
48 sample_freq_ind,
49 i_bw_start,
50 i_bw_stop,
51 l,
52 }
53 }
54
55 pub fn get_num_bits_bandwidth(&self) -> usize {
56 NBITS_BW_TABLE[self.sample_freq_ind]
57 }
58
59 pub fn run(&self, e_b: &[Scaler]) -> BandwidthDetectorResult {
65 let nbits_bandwidth = NBITS_BW_TABLE[self.sample_freq_ind];
66 if self.sample_freq_ind == 0 {
67 return BandwidthDetectorResult {
68 bandwidth_ind: 0,
69 nbits_bandwidth,
70 };
71 }
72
73 let mut bandwidth_ind = 0;
75
76 for k in (0..self.sample_freq_ind).rev() {
79 let start = self.i_bw_start[k];
80 let stop = self.i_bw_stop[k];
81 let width = (stop + 1 - start) as Scaler;
82 let mut quietness = 0.0;
83
84 for energy in e_b[start..=stop].iter() {
86 quietness += *energy / width;
87 }
88
89 if quietness >= QUIETNESS_THRESH[k] as Scaler {
91 bandwidth_ind = k + 1;
92 break;
93 }
94 }
95
96 if self.sample_freq_ind == bandwidth_ind {
98 BandwidthDetectorResult {
99 bandwidth_ind,
100 nbits_bandwidth,
101 }
102 } else {
103 let mut cutoff_max = 0.0;
105 let l_bw = self.l[bandwidth_ind];
106 let from = self.i_bw_start[bandwidth_ind] + 1 - l_bw;
107 let to = self.i_bw_start[bandwidth_ind];
108 for n in from..to {
109 let cutoff = e_b[n - l_bw] / e_b[n];
112 cutoff_max = cutoff.max(cutoff_max);
113 }
114
115 if cutoff_max > CUTOFF_THRESH[bandwidth_ind] as Scaler {
116 BandwidthDetectorResult {
117 bandwidth_ind,
118 nbits_bandwidth,
119 }
120 } else {
121 BandwidthDetectorResult {
122 bandwidth_ind: self.sample_freq_ind,
123 nbits_bandwidth,
124 }
125 }
126 }
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 extern crate std;
133 use super::*;
134 use crate::common::config::{FrameDuration, Lc3Config, SamplingFrequency};
135
136 #[test]
137 fn bandwidth_detector_run() {
138 let config = Lc3Config::new(SamplingFrequency::Hz48000, FrameDuration::TenMs);
139 let detector = BandwidthDetector::new(config.n_ms, config.fs_ind);
140 #[rustfmt::skip]
141 let e_b = [
142 18782358.0, 38743940.0, 616163.4, 395644.22, 20441758.0, 31336932.0, 130985740.0, 116001040.0, 297851520.0,
143 52884070.0, 13922108.0, 1211718.9, 643103.44, 2697760.3, 1674064.1, 8157596.5, 11880675.0, 615179.8,
144 1548138.0, 15001.449, 72356.61, 424075.13, 339332.63, 9093.422, 118530.22, 106300.99, 93872.414, 103234.38,
145 129645.81, 12188.947, 48738.766, 124244.47, 12835.649, 47138.63, 10050.675, 24161.475, 15844.599, 16136.73,
146 37085.188, 5236.445, 14986.677, 10497.837, 8121.843, 2109.306, 3711.1233, 3116.423, 3749.5027, 4903.189,
147 3149.5522, 1745.0712, 1382.3269, 1555.3384, 994.6934, 1484.393, 888.5528, 926.9374, 639.82434, 801.4557,
148 743.6313, 487.39868, 681.486, 519.567, 481.0444, 454.6319,
149 ];
150
151 let result = detector.run(&e_b);
152
153 assert_eq!(result.bandwidth_ind, 4);
154 assert_eq!(result.nbits_bandwidth, 3);
155 }
156}