]>
Commit | Line | Data |
---|---|---|
1 | use nihav_core::codecs::{DecoderResult, DecoderError}; | |
2 | use nihav_core::io::bitreader::*; | |
3 | ||
4 | mod bs; | |
5 | mod dsp; | |
6 | mod synth; | |
7 | ||
8 | pub use bs::{SBRCodebooks, sbr_read_sce, sbr_read_cpe}; | |
9 | pub use dsp::SBRDSP; | |
10 | pub use synth::SBRChannel; | |
11 | ||
12 | pub const NUM_ENVELOPES: usize = 8; | |
13 | pub const NUM_PATCHES: usize = 5; | |
14 | pub const SBR_BANDS: usize = 64; | |
15 | pub const QMF_DELAY: usize = 8; | |
16 | pub const HF_ADJ: usize = 2; | |
17 | pub const MAX_SLOTS: usize = 16; | |
18 | ||
19 | #[derive(Clone, Copy, Debug)] | |
20 | pub struct SBRHeader { | |
21 | pub amp_res: bool, | |
22 | start_freq: usize, | |
23 | stop_freq: usize, | |
24 | xover_band: usize, | |
25 | freq_scale: u8, | |
26 | alter_scale: bool, | |
27 | noise_bands: u8, | |
28 | limiter_bands: u8, | |
29 | limiter_gains: u8, | |
30 | interpol_freq: bool, | |
31 | smoothing_mode: bool, | |
32 | } | |
33 | ||
34 | impl SBRHeader { | |
35 | pub fn new() -> Self { | |
36 | let mut obj: Self = unsafe { std::mem::zeroed() }; | |
37 | obj.reset(); | |
38 | obj | |
39 | } | |
40 | fn reset(&mut self) { | |
41 | self.freq_scale = 2; | |
42 | self.alter_scale = true; | |
43 | self.noise_bands = 2; | |
44 | self.limiter_bands = 2; | |
45 | self.limiter_gains = 2; | |
46 | self.interpol_freq = true; | |
47 | self.smoothing_mode = true; | |
48 | } | |
49 | ||
50 | pub fn read(br: &mut BitReader) -> DecoderResult<Self> { | |
51 | let mut sbrh = Self::new(); | |
52 | sbrh.reset(); | |
53 | sbrh.amp_res = br.read_bool()?; | |
54 | sbrh.start_freq = br.read(4)? as usize; | |
55 | sbrh.stop_freq = br.read(4)? as usize; | |
56 | sbrh.xover_band = br.read(3)? as usize; | |
57 | br.skip(2)?; | |
58 | let header_extra_1 = br.read_bool()?; | |
59 | let header_extra_2 = br.read_bool()?; | |
60 | if header_extra_1 { | |
61 | sbrh.freq_scale = br.read(2)? as u8; | |
62 | sbrh.alter_scale = br.read_bool()?; | |
63 | sbrh.noise_bands = br.read(2)? as u8; | |
64 | } | |
65 | if header_extra_2 { | |
66 | sbrh.limiter_bands = br.read(2)? as u8; | |
67 | sbrh.limiter_gains = br.read(2)? as u8; | |
68 | sbrh.interpol_freq = br.read_bool()?; | |
69 | if !sbrh.interpol_freq { | |
70 | return Err(DecoderError::NotImplemented); | |
71 | } | |
72 | sbrh.smoothing_mode = br.read_bool()?; | |
73 | } | |
74 | Ok(sbrh) | |
75 | } | |
76 | ||
77 | pub fn differs_from(&self, rval: &Self) -> bool { | |
78 | self.start_freq != rval.start_freq || | |
79 | self.stop_freq != rval.stop_freq || | |
80 | self.xover_band != rval.xover_band || | |
81 | self.freq_scale != rval.freq_scale || | |
82 | self.alter_scale != rval.alter_scale || | |
83 | self.noise_bands != rval.noise_bands | |
84 | } | |
85 | } | |
86 | ||
87 | #[derive(Clone)] | |
88 | pub struct SBRState { | |
89 | num_env_bands: [usize; 2], | |
90 | num_master: usize, | |
91 | num_noise_bands: usize, | |
92 | num_lim: usize, | |
93 | k_x: usize, | |
94 | low_to_high_res: [usize; SBR_BANDS], | |
95 | high_to_low_res: [usize; SBR_BANDS], | |
96 | f: [usize; SBR_BANDS], | |
97 | f_low: [usize; SBR_BANDS], | |
98 | f_noise: [usize; SBR_BANDS], | |
99 | f_lim: [usize; SBR_BANDS], | |
100 | patch_num_subbands: [usize; SBR_BANDS], | |
101 | patch_start_subband: [usize; SBR_BANDS], | |
102 | num_patches: usize, | |
103 | } | |
104 | ||
105 | impl SBRState { | |
106 | pub fn new() -> Self { | |
107 | Self { | |
108 | num_env_bands: [0; 2], | |
109 | num_master: 0, | |
110 | num_noise_bands: 0, | |
111 | num_lim: 0, | |
112 | k_x: 0, | |
113 | low_to_high_res: [0; SBR_BANDS], | |
114 | high_to_low_res: [0; SBR_BANDS], | |
115 | f: [0; SBR_BANDS], | |
116 | f_low: [0; SBR_BANDS], | |
117 | f_noise: [0; SBR_BANDS], | |
118 | f_lim: [0; SBR_BANDS], | |
119 | patch_num_subbands: [0; SBR_BANDS], | |
120 | patch_start_subband: [0; SBR_BANDS], | |
121 | num_patches: 0, | |
122 | } | |
123 | } | |
124 | pub fn init(&mut self, hdr: &SBRHeader, srate: u32) -> DecoderResult<()> { | |
125 | let offset_tab = match srate { | |
126 | 0..=16000 => &SBR_OFFSETS[0], | |
127 | 16001..=22050 => &SBR_OFFSETS[1], | |
128 | 22051..=24000 => &SBR_OFFSETS[2], | |
129 | 24001..=32000 => &SBR_OFFSETS[3], | |
130 | 32001..=64000 => &SBR_OFFSETS[4], | |
131 | _ => &SBR_OFFSETS[5], | |
132 | }; | |
133 | let smult = match srate { | |
134 | 0..=31999 => 3000, | |
135 | 32000..=63999 => 4000, | |
136 | _ => 5000, | |
137 | }; | |
138 | let start_min = (128 * smult + srate / 2) / srate; | |
139 | let stop_min = (128 * smult * 2 + srate / 2) / srate; | |
140 | ||
141 | let k0 = ((start_min as i32) + i32::from(offset_tab[hdr.start_freq])).max(0) as usize; | |
142 | let k2 = (match hdr.stop_freq { | |
143 | 14 => 2 * k0, | |
144 | 15 => 3 * k0, | |
145 | _ => { | |
146 | let mut stop_dk = [0; 14]; | |
147 | generate_vdk(&mut stop_dk, stop_min as usize, SBR_BANDS, 13); | |
148 | let dk_sum: usize = stop_dk[..hdr.stop_freq].iter().sum(); | |
149 | (stop_min as usize) + dk_sum | |
150 | }, | |
151 | }).min(SBR_BANDS); | |
152 | ||
153 | let max_bands = match srate { | |
154 | 0..=32000 => 48, | |
155 | 32001..=47999 => 35, | |
156 | _ => 32, | |
157 | }; | |
158 | validate!(k2 - k0 <= max_bands); | |
159 | ||
160 | self.num_master = calculate_master_frequencies(&mut self.f, k0, k2, hdr); | |
161 | let num_high = self.num_master - hdr.xover_band; | |
162 | let num_low = (num_high + 1) / 2; // INT(num_high / 2) + (num_high - 2 * INT(num_high / 2)) | |
163 | ||
164 | self.num_env_bands = [num_low, num_high]; | |
165 | ||
166 | let f_high = &self.f[hdr.xover_band..]; | |
167 | let m = f_high[num_high] - f_high[0]; | |
168 | let k_x = f_high[0]; | |
169 | self.k_x = k_x; | |
170 | self.f_low = [0; SBR_BANDS]; | |
171 | if (num_high & 1) == 0 { | |
172 | for k in 0..=num_low { | |
173 | self.f_low[k] = f_high[k * 2]; | |
174 | } | |
175 | } else { | |
176 | self.f_low[0] = f_high[0]; | |
177 | for k in 1..=num_low { | |
178 | self.f_low[k] = f_high[k * 2 - 1]; | |
179 | } | |
180 | } | |
181 | ||
182 | let high_src = &f_high[..=num_high]; | |
183 | let low_src = &self.f_low[..=num_low]; | |
184 | for (dst, low) in self.high_to_low_res.iter_mut().zip(low_src.iter()) { | |
185 | if let Ok(idx) = high_src.binary_search(low) { | |
186 | *dst = idx; | |
187 | } else { | |
188 | return Err(DecoderError::Bug); | |
189 | } | |
190 | } | |
191 | for (dst, high) in self.low_to_high_res.iter_mut().zip(high_src.iter()) { | |
192 | *dst = match low_src.binary_search(high) { | |
193 | Ok(idx) => idx, | |
194 | Err(idx) => idx - 1, | |
195 | }; | |
196 | } | |
197 | ||
198 | let num_q = (((hdr.noise_bands as f32) * ((k2 as f32) / (k_x as f32)).log2()).round() as usize).max(1); | |
199 | self.num_noise_bands = num_q; | |
200 | self.f_noise = [0; SBR_BANDS]; | |
201 | let mut prev = 0; | |
202 | self.f_noise[0] = self.f_low[0]; | |
203 | for k in 1..=num_q { | |
204 | let idx = prev + ((num_low - prev) / (num_q + 1 - k)); | |
205 | self.f_noise[k] = self.f_low[idx]; | |
206 | prev = idx; | |
207 | } | |
208 | ||
209 | let mut num_patches = 0; | |
210 | self.patch_num_subbands = [0; SBR_BANDS]; | |
211 | self.patch_start_subband = [0; SBR_BANDS]; | |
212 | let mut msb = k0; | |
213 | let mut usb = k_x; | |
214 | let goal_sb = ((2048000 + srate / 2) / srate) as usize; | |
215 | let last_band = k_x + m; | |
216 | let mut k = if goal_sb < last_band { | |
217 | let mut kk = 0; | |
218 | for i in 0..self.num_master { | |
219 | if self.f[i] >= goal_sb { | |
220 | break; | |
221 | } | |
222 | kk = i + 1; | |
223 | } | |
224 | kk | |
225 | } else { | |
226 | self.num_master | |
227 | }; | |
228 | loop { | |
229 | let mut sb; | |
230 | let mut odd; | |
231 | let mut j = k; | |
232 | loop { | |
233 | sb = self.f[j]; | |
234 | odd = (sb - 2 + k0) & 1; | |
235 | if sb <= k0 + msb - 1 - odd { | |
236 | break; | |
237 | } | |
238 | j -= 1; | |
239 | } | |
240 | ||
241 | self.patch_num_subbands[num_patches] = sb.saturating_sub(usb); | |
242 | self.patch_start_subband[num_patches] = k0 - odd - self.patch_num_subbands[num_patches]; | |
243 | ||
244 | if self.patch_num_subbands[num_patches] > 0 { | |
245 | usb = sb; | |
246 | msb = sb; | |
247 | num_patches += 1; | |
248 | } else { | |
249 | msb = k_x; | |
250 | } | |
251 | ||
252 | if self.f[k] < sb + 3 { | |
253 | k = self.num_master; | |
254 | } | |
255 | ||
256 | if sb == last_band { | |
257 | break; | |
258 | } | |
259 | } | |
260 | if (num_patches > 1) && (self.patch_num_subbands[num_patches - 1] < 3) { | |
261 | num_patches -= 1; | |
262 | } | |
263 | validate!(num_patches <= NUM_PATCHES); | |
264 | self.num_patches = num_patches; | |
265 | ||
266 | self.f_lim = [0; SBR_BANDS]; | |
267 | let num_l = if hdr.limiter_bands == 0 { | |
268 | self.f_lim[0] = self.f_low[0]; | |
269 | self.f_lim[1] = self.f_low[num_low]; | |
270 | 1 | |
271 | } else { | |
272 | let lim_bands = match hdr.limiter_bands { | |
273 | 1 => 1.2f32, | |
274 | 2 => 2.0, | |
275 | _ => 3.0, | |
276 | }; | |
277 | let mut patch_borders = [0; NUM_PATCHES + 1]; | |
278 | patch_borders[0] = k_x; | |
279 | for k in 0..num_patches { | |
280 | patch_borders[k + 1] = patch_borders[k] + self.patch_num_subbands[k]; | |
281 | } | |
282 | self.f_lim = self.f_low; | |
283 | let f_lim_ptr = &mut self.f_lim[..num_low + num_patches]; | |
284 | for &pborder in patch_borders[1..num_patches].iter() { | |
285 | let mut i = 0; | |
286 | for &el in f_lim_ptr.iter() { | |
287 | if el > pborder { | |
288 | break; | |
289 | } | |
290 | i += 1; | |
291 | } | |
292 | for j in (i..num_low + num_patches - 1).rev() { | |
293 | f_lim_ptr[j + 1] = f_lim_ptr[j]; | |
294 | } | |
295 | f_lim_ptr[i] = pborder; | |
296 | } | |
297 | let mut nr_lim = num_low + num_patches - 1; | |
298 | let mut k = 1; | |
299 | let pbord = &patch_borders[..=num_patches]; | |
300 | while k <= nr_lim { | |
301 | let n_octaves = ((self.f_lim[k] as f32) / (self.f_lim[k - 1] as f32)).log2(); | |
302 | if (n_octaves * lim_bands) < 0.49 { | |
303 | if self.f_lim[k] == self.f_lim[k - 1] || !pbord.contains(&self.f_lim[k]) { | |
304 | for l in k..nr_lim { | |
305 | self.f_lim[l] = self.f_lim[l + 1]; | |
306 | } | |
307 | nr_lim -= 1; | |
308 | } else if !pbord.contains(&self.f_lim[k - 1]) { | |
309 | for l in (k - 1)..nr_lim { | |
310 | self.f_lim[l] = self.f_lim[l + 1]; | |
311 | } | |
312 | nr_lim -= 1; | |
313 | } else { | |
314 | k += 1; | |
315 | } | |
316 | } else { | |
317 | k += 1; | |
318 | } | |
319 | } | |
320 | ||
321 | nr_lim | |
322 | }; | |
323 | self.num_lim = num_l; | |
324 | ||
325 | Ok(()) | |
326 | } | |
327 | } | |
328 | ||
329 | fn generate_vdk(v_dk: &mut [usize], k0: usize, k1: usize, num_bands: usize) { | |
330 | let mut last = k0; | |
331 | let k0 = k0 as f64; | |
332 | let factor = (k1 as f64) / k0; | |
333 | for k in 0..num_bands { | |
334 | let next = (k0 * factor.powf((k + 1) as f64 / (num_bands as f64))).round() as usize; | |
335 | let newval = next - last; | |
336 | last = next; | |
337 | let mut idx = k; | |
338 | for (j, &el) in v_dk[..k].iter().enumerate() { | |
339 | if newval < el { | |
340 | idx = j; | |
341 | break; | |
342 | } | |
343 | } | |
344 | for j in (idx..k).rev() { | |
345 | v_dk[j + 1] = v_dk[j]; | |
346 | } | |
347 | v_dk[idx] = newval; | |
348 | } | |
349 | } | |
350 | ||
351 | fn calculate_master_frequencies(f: &mut [usize; SBR_BANDS], k0: usize, k2: usize, hdr: &SBRHeader) -> usize { | |
352 | if hdr.freq_scale == 0 { | |
353 | let (dk, num_bands) = if !hdr.alter_scale { | |
354 | (1, 2 * ((k2 - k0) / 2)) | |
355 | } else { | |
356 | (2, 2 * ((k2 - k0 + 2) / (2 * 2))) | |
357 | }; | |
358 | let k2_achieved = k0 + num_bands * dk; | |
359 | let mut k2_diff = (k2 as isize) - (k2_achieved as isize); | |
360 | let mut v_dk = [dk; SBR_BANDS]; | |
361 | if k2_diff < 0 { | |
362 | let mut k = 0; | |
363 | while k2_diff != 0 { | |
364 | v_dk[k] -= 1; | |
365 | k += 1; | |
366 | k2_diff += 1; | |
367 | } | |
368 | } else if k2_diff > 0 { | |
369 | let mut k = num_bands - 1; | |
370 | while k2_diff != 0 { | |
371 | v_dk[k] += 1; | |
372 | k -= 1; | |
373 | k2_diff -= 1; | |
374 | } | |
375 | } | |
376 | f[0] = k0; | |
377 | for i in 0..num_bands { | |
378 | f[i + 1] = f[i] + v_dk[i]; | |
379 | } | |
380 | ||
381 | num_bands | |
382 | } else { | |
383 | let bands = 14 - hdr.freq_scale * 2; | |
384 | let warp = if !hdr.alter_scale { 1.0f32 } else { 1.3f32 }; | |
385 | let two_regions = (k2 as f32) / (k0 as f32) > 2.2449; | |
386 | let k1 = if two_regions { 2 * k0 } else { k2 }; | |
387 | let num_bands0 = 2 * (((bands as f32) * ((k1 as f32) / (k0 as f32)).log2() / 2.0).round() as usize); | |
388 | let mut v_dk0 = [0; SBR_BANDS]; | |
389 | generate_vdk(&mut v_dk0, k0, k1, num_bands0); | |
390 | let mut v_k0 = [0; SBR_BANDS]; | |
391 | v_k0[0] = k0; | |
392 | for i in 0..num_bands0 { | |
393 | v_k0[i + 1] = v_k0[i] + v_dk0[i]; | |
394 | } | |
395 | ||
396 | if two_regions { | |
397 | let num_bands1 = 2 * (((bands as f32) * ((k2 as f32) / (k1 as f32)).log2() / (2.0 * warp)).round() as usize); | |
398 | let mut v_dk1 = [0; SBR_BANDS]; | |
399 | generate_vdk(&mut v_dk1, k1, k2, num_bands1); | |
400 | let max_vdk0 = v_dk0[num_bands0 - 1]; | |
401 | if v_dk1[0] < max_vdk0 { | |
402 | let change = (max_vdk0 - v_dk1[0]).min((v_dk1[num_bands1 - 1] - v_dk1[0]) / 2); | |
403 | v_dk1[0] += change; | |
404 | v_dk1[num_bands1 - 1] -= change; | |
405 | } | |
406 | let mut v_k1 = [0; SBR_BANDS]; | |
407 | v_k1[0] = k1; | |
408 | for i in 0..num_bands1 { | |
409 | v_k1[i + 1] = v_k1[i] + v_dk1[i]; | |
410 | } | |
411 | f[..=num_bands0].copy_from_slice(&v_k0[..=num_bands0]); | |
412 | f[num_bands0 + 1..][..=num_bands1].copy_from_slice(&v_k1[1..][..=num_bands1]); | |
413 | num_bands0 + num_bands1 | |
414 | } else { | |
415 | f[..=num_bands0].copy_from_slice(&v_k0[..=num_bands0]); | |
416 | num_bands0 | |
417 | } | |
418 | } | |
419 | } | |
420 | ||
421 | const SBR_OFFSETS: [[i8; 16]; 6] = [ | |
422 | [ -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 ], // 16kHz | |
423 | [ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13 ], // 22kHz | |
424 | [ -5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16 ], // 24kHz | |
425 | [ -6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16 ], // 32kHz | |
426 | [ -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20 ], // 44kHz | |
427 | [ -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24 ] // 64kHz | |
428 | ]; |