/proc/self/cwd/libfaad/sbr_hfadj.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding |
3 | | ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com |
4 | | ** |
5 | | ** This program is free software; you can redistribute it and/or modify |
6 | | ** it under the terms of the GNU General Public License as published by |
7 | | ** the Free Software Foundation; either version 2 of the License, or |
8 | | ** (at your option) any later version. |
9 | | ** |
10 | | ** This program is distributed in the hope that it will be useful, |
11 | | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | ** GNU General Public License for more details. |
14 | | ** |
15 | | ** You should have received a copy of the GNU General Public License |
16 | | ** along with this program; if not, write to the Free Software |
17 | | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 | | ** |
19 | | ** Any non-GPL usage of this software or parts of this software is strictly |
20 | | ** forbidden. |
21 | | ** |
22 | | ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 |
23 | | ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" |
24 | | ** |
25 | | ** Commercial non-GPL licensing of this software is possible. |
26 | | ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. |
27 | | ** |
28 | | ** $Id: sbr_hfadj.c,v 1.23 2008/09/19 22:50:20 menno Exp $ |
29 | | **/ |
30 | | |
31 | | /* High Frequency adjustment */ |
32 | | #include <float.h> |
33 | | |
34 | | #include "common.h" |
35 | | #include "structs.h" |
36 | | |
37 | | #ifdef SBR_DEC |
38 | | |
39 | | #include "sbr_syntax.h" |
40 | | #include "sbr_hfadj.h" |
41 | | |
42 | | #include "sbr_noise.h" |
43 | | |
44 | | |
45 | | /* static function declarations */ |
46 | | static uint8_t estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, |
47 | | qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch); |
48 | | static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch); |
49 | | #ifdef SBR_LOW_POWER |
50 | | static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch); |
51 | | static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch); |
52 | | #endif |
53 | | static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch); |
54 | | |
55 | | |
56 | | uint8_t hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64] |
57 | | #ifdef SBR_LOW_POWER |
58 | | ,real_t *deg /* aliasing degree */ |
59 | | #endif |
60 | | ,uint8_t ch) |
61 | 24.3k | { |
62 | 24.3k | ALIGN sbr_hfadj_info adj = {{{0}}}; |
63 | 24.3k | uint8_t ret = 0; |
64 | | |
65 | 24.3k | if (sbr->bs_frame_class[ch] == FIXFIX) |
66 | 7.04k | { |
67 | 7.04k | sbr->l_A[ch] = -1; |
68 | 17.2k | } else if (sbr->bs_frame_class[ch] == VARFIX) { |
69 | 7.73k | if (sbr->bs_pointer[ch] > 1) |
70 | 2.29k | sbr->l_A[ch] = sbr->bs_pointer[ch] - 1; |
71 | 5.44k | else |
72 | 5.44k | sbr->l_A[ch] = -1; |
73 | 9.54k | } else { |
74 | 9.54k | if (sbr->bs_pointer[ch] == 0) |
75 | 3.28k | sbr->l_A[ch] = -1; |
76 | 6.26k | else |
77 | 6.26k | sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch]; |
78 | 9.54k | } |
79 | | |
80 | 24.3k | ret = estimate_current_envelope(sbr, &adj, Xsbr, ch); |
81 | 24.3k | if (ret > 0) |
82 | 520 | return 1; |
83 | | |
84 | 23.8k | calculate_gain(sbr, &adj, ch); |
85 | | |
86 | | #ifdef SBR_LOW_POWER |
87 | | calc_gain_groups(sbr, &adj, deg, ch); |
88 | | aliasing_reduction(sbr, &adj, deg, ch); |
89 | | #endif |
90 | | |
91 | 23.8k | hf_assembly(sbr, &adj, Xsbr, ch); |
92 | | |
93 | 23.8k | return 0; |
94 | 24.3k | } |
95 | | |
96 | | static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t current_band) |
97 | 196k | { |
98 | 196k | if (sbr->f[ch][l] == HI_RES) |
99 | 80.8k | { |
100 | | /* in case of using f_table_high we just have 1 to 1 mapping |
101 | | * from bs_add_harmonic[l][k] |
102 | | */ |
103 | 80.8k | if ((l >= sbr->l_A[ch]) || |
104 | 80.8k | (sbr->bs_add_harmonic_prev[ch][current_band] && sbr->bs_add_harmonic_flag_prev[ch])) |
105 | 53.5k | { |
106 | 53.5k | return sbr->bs_add_harmonic[ch][current_band]; |
107 | 53.5k | } |
108 | 115k | } else { |
109 | 115k | uint8_t b, lb, ub; |
110 | | |
111 | | /* in case of f_table_low we check if any of the HI_RES bands |
112 | | * within this LO_RES band has bs_add_harmonic[l][k] turned on |
113 | | * (note that borders in the LO_RES table are also present in |
114 | | * the HI_RES table) |
115 | | */ |
116 | | |
117 | | /* find first HI_RES band in current LO_RES band */ |
118 | 115k | lb = 2*current_band - ((sbr->N_high & 1) ? 1 : 0); |
119 | | /* find first HI_RES band in next LO_RES band */ |
120 | 115k | ub = 2*(current_band+1) - ((sbr->N_high & 1) ? 1 : 0); |
121 | | |
122 | | /* check all HI_RES bands in current LO_RES band for sinusoid */ |
123 | 299k | for (b = lb; b < ub; b++) |
124 | 195k | { |
125 | 195k | if ((l >= sbr->l_A[ch]) || |
126 | 195k | (sbr->bs_add_harmonic_prev[ch][b] && sbr->bs_add_harmonic_flag_prev[ch])) |
127 | 140k | { |
128 | 140k | if (sbr->bs_add_harmonic[ch][b] == 1) |
129 | 11.8k | return 1; |
130 | 140k | } |
131 | 195k | } |
132 | 115k | } |
133 | | |
134 | 131k | return 0; |
135 | 196k | } |
136 | | |
137 | | static uint8_t estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, |
138 | | qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) |
139 | 24.3k | { |
140 | 24.3k | uint8_t m, l, j, k, k_l, k_h, p; |
141 | 24.3k | real_t nrg, div; |
142 | 24.3k | (void)adj; /* TODO: remove parameter? */ |
143 | | #ifdef FIXED_POINT |
144 | 10.1k | const real_t half = REAL_CONST(0.5); |
145 | | real_t limit; |
146 | | real_t mul; |
147 | | #else |
148 | | const real_t half = 0; /* Compiler is smart enough to eliminate +0 op. */ |
149 | | const real_t limit = FLT_MAX; |
150 | | #endif |
151 | | |
152 | 24.3k | if (sbr->bs_interpol_freq == 1) |
153 | 17.3k | { |
154 | 46.4k | for (l = 0; l < sbr->L_E[ch]; l++) |
155 | 29.2k | { |
156 | 29.2k | uint8_t i, l_i, u_i; |
157 | | |
158 | 29.2k | l_i = sbr->t_E[ch][l]; |
159 | 29.2k | u_i = sbr->t_E[ch][l+1]; |
160 | | |
161 | 29.2k | div = (real_t)(u_i - l_i); |
162 | | |
163 | 29.2k | if (div <= 0) |
164 | 1.00k | div = 1; |
165 | | #ifdef FIXED_POINT |
166 | 11.2k | limit = div << (30 - (COEF_BITS - REAL_BITS)); |
167 | 11.2k | mul = (1 << (COEF_BITS - REAL_BITS)) / div; |
168 | | #endif |
169 | | |
170 | 378k | for (m = 0; m < sbr->M; m++) |
171 | 349k | { |
172 | 349k | nrg = 0; |
173 | | |
174 | 6.73M | for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) |
175 | 6.38M | { |
176 | 6.38M | real_t re = QMF_RE(Xsbr[i][m + sbr->kx]) + half; |
177 | 6.38M | real_t im = QMF_IM(Xsbr[i][m + sbr->kx]) + half; |
178 | 6.38M | (void)im; |
179 | | /* Actually, that should be MUL_R. On floating-point build |
180 | | that is the same. On fixed point-build we use it to |
181 | | pre-scale result (to aviod overflow). That, of course |
182 | | causes some precision loss. */ |
183 | 6.38M | nrg += MUL_C(re, re) |
184 | 6.38M | #ifndef SBR_LOW_POWER |
185 | 6.38M | + MUL_C(im, im) |
186 | 6.38M | #endif |
187 | 6.38M | ; |
188 | 6.38M | } |
189 | | |
190 | 349k | if (nrg < -limit || nrg > limit) |
191 | 171 | return 1; |
192 | | #ifdef FIXED_POINT |
193 | 156k | sbr->E_curr[ch][m][l] = nrg * mul; |
194 | | #else |
195 | 192k | sbr->E_curr[ch][m][l] = nrg / div; |
196 | 192k | #endif |
197 | | #ifdef SBR_LOW_POWER |
198 | | #ifdef FIXED_POINT |
199 | | sbr->E_curr[ch][m][l] <<= 1; |
200 | | #else |
201 | | sbr->E_curr[ch][m][l] *= 2; |
202 | | #endif |
203 | | #endif |
204 | 192k | } |
205 | 29.2k | } |
206 | 17.3k | } else { |
207 | 18.5k | for (l = 0; l < sbr->L_E[ch]; l++) |
208 | 11.8k | { |
209 | 89.4k | for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++) |
210 | 77.9k | { |
211 | 77.9k | k_l = sbr->f_table_res[sbr->f[ch][l]][p]; |
212 | 77.9k | k_h = sbr->f_table_res[sbr->f[ch][l]][p+1]; |
213 | | |
214 | 286k | for (k = k_l; k < k_h; k++) |
215 | 208k | { |
216 | 208k | uint8_t i, l_i, u_i; |
217 | 208k | nrg = 0; |
218 | | |
219 | 208k | l_i = sbr->t_E[ch][l]; |
220 | 208k | u_i = sbr->t_E[ch][l+1]; |
221 | | |
222 | 208k | div = (real_t)((u_i - l_i)*(k_h - k_l)); |
223 | | |
224 | 208k | if (div <= 0) |
225 | 8.83k | div = 1; |
226 | | #ifdef FIXED_POINT |
227 | 100k | limit = div << (30 - (COEF_BITS - REAL_BITS)); |
228 | 100k | mul = (1 << (COEF_BITS - REAL_BITS)) / div; |
229 | | #endif |
230 | | |
231 | 4.11M | for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) |
232 | 3.91M | { |
233 | 18.8M | for (j = k_l; j < k_h; j++) |
234 | 14.9M | { |
235 | 14.9M | real_t re = QMF_RE(Xsbr[i][j]) + half; |
236 | 14.9M | real_t im = QMF_IM(Xsbr[i][j]) + half; |
237 | 14.9M | (void)im; |
238 | | /* Actually, that should be MUL_R. On floating-point build |
239 | | that is the same. On fixed point-build we use it to |
240 | | pre-scale result (to aviod overflow). That, of course |
241 | | causes some precision loss. */ |
242 | 14.9M | nrg += MUL_C(re, re) |
243 | 14.9M | #ifndef SBR_LOW_POWER |
244 | 14.9M | + MUL_C(im, im) |
245 | 14.9M | #endif |
246 | 14.9M | ; |
247 | 14.9M | } |
248 | 3.91M | } |
249 | | |
250 | 208k | if (nrg < -limit || nrg > limit) |
251 | 349 | return 1; |
252 | | #ifdef FIXED_POINT |
253 | 100k | sbr->E_curr[ch][k - sbr->kx][l] = nrg * mul; |
254 | | #else |
255 | 108k | sbr->E_curr[ch][k - sbr->kx][l] = nrg / div; |
256 | 108k | #endif |
257 | | #ifdef SBR_LOW_POWER |
258 | | #ifdef FIXED_POINT |
259 | | sbr->E_curr[ch][k - sbr->kx][l] <<= 1; |
260 | | #else |
261 | | sbr->E_curr[ch][k - sbr->kx][l] *= 2; |
262 | | #endif |
263 | | #endif |
264 | 108k | } |
265 | 77.9k | } |
266 | 11.8k | } |
267 | 6.98k | } |
268 | | |
269 | 23.8k | return 0; |
270 | 24.3k | } sbr_hfadj.c:estimate_current_envelope Line | Count | Source | 139 | 10.1k | { | 140 | 10.1k | uint8_t m, l, j, k, k_l, k_h, p; | 141 | 10.1k | real_t nrg, div; | 142 | 10.1k | (void)adj; /* TODO: remove parameter? */ | 143 | 10.1k | #ifdef FIXED_POINT | 144 | 10.1k | const real_t half = REAL_CONST(0.5); | 145 | 10.1k | real_t limit; | 146 | 10.1k | real_t mul; | 147 | | #else | 148 | | const real_t half = 0; /* Compiler is smart enough to eliminate +0 op. */ | 149 | | const real_t limit = FLT_MAX; | 150 | | #endif | 151 | | | 152 | 10.1k | if (sbr->bs_interpol_freq == 1) | 153 | 6.52k | { | 154 | 17.6k | for (l = 0; l < sbr->L_E[ch]; l++) | 155 | 11.2k | { | 156 | 11.2k | uint8_t i, l_i, u_i; | 157 | | | 158 | 11.2k | l_i = sbr->t_E[ch][l]; | 159 | 11.2k | u_i = sbr->t_E[ch][l+1]; | 160 | | | 161 | 11.2k | div = (real_t)(u_i - l_i); | 162 | | | 163 | 11.2k | if (div <= 0) | 164 | 413 | div = 1; | 165 | 11.2k | #ifdef FIXED_POINT | 166 | 11.2k | limit = div << (30 - (COEF_BITS - REAL_BITS)); | 167 | 11.2k | mul = (1 << (COEF_BITS - REAL_BITS)) / div; | 168 | 11.2k | #endif | 169 | | | 170 | 167k | for (m = 0; m < sbr->M; m++) | 171 | 156k | { | 172 | 156k | nrg = 0; | 173 | | | 174 | 2.85M | for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) | 175 | 2.70M | { | 176 | 2.70M | real_t re = QMF_RE(Xsbr[i][m + sbr->kx]) + half; | 177 | 2.70M | real_t im = QMF_IM(Xsbr[i][m + sbr->kx]) + half; | 178 | 2.70M | (void)im; | 179 | | /* Actually, that should be MUL_R. On floating-point build | 180 | | that is the same. On fixed point-build we use it to | 181 | | pre-scale result (to aviod overflow). That, of course | 182 | | causes some precision loss. */ | 183 | 2.70M | nrg += MUL_C(re, re) | 184 | 2.70M | #ifndef SBR_LOW_POWER | 185 | 2.70M | + MUL_C(im, im) | 186 | 2.70M | #endif | 187 | 2.70M | ; | 188 | 2.70M | } | 189 | | | 190 | 156k | if (nrg < -limit || nrg > limit) | 191 | 164 | return 1; | 192 | 156k | #ifdef FIXED_POINT | 193 | 156k | sbr->E_curr[ch][m][l] = nrg * mul; | 194 | | #else | 195 | | sbr->E_curr[ch][m][l] = nrg / div; | 196 | | #endif | 197 | | #ifdef SBR_LOW_POWER | 198 | | #ifdef FIXED_POINT | 199 | | sbr->E_curr[ch][m][l] <<= 1; | 200 | | #else | 201 | | sbr->E_curr[ch][m][l] *= 2; | 202 | | #endif | 203 | | #endif | 204 | 156k | } | 205 | 11.2k | } | 206 | 6.52k | } else { | 207 | 9.23k | for (l = 0; l < sbr->L_E[ch]; l++) | 208 | 5.95k | { | 209 | 44.2k | for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++) | 210 | 38.5k | { | 211 | 38.5k | k_l = sbr->f_table_res[sbr->f[ch][l]][p]; | 212 | 38.5k | k_h = sbr->f_table_res[sbr->f[ch][l]][p+1]; | 213 | | | 214 | 139k | for (k = k_l; k < k_h; k++) | 215 | 100k | { | 216 | 100k | uint8_t i, l_i, u_i; | 217 | 100k | nrg = 0; | 218 | | | 219 | 100k | l_i = sbr->t_E[ch][l]; | 220 | 100k | u_i = sbr->t_E[ch][l+1]; | 221 | | | 222 | 100k | div = (real_t)((u_i - l_i)*(k_h - k_l)); | 223 | | | 224 | 100k | if (div <= 0) | 225 | 2.64k | div = 1; | 226 | 100k | #ifdef FIXED_POINT | 227 | 100k | limit = div << (30 - (COEF_BITS - REAL_BITS)); | 228 | 100k | mul = (1 << (COEF_BITS - REAL_BITS)) / div; | 229 | 100k | #endif | 230 | | | 231 | 2.03M | for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) | 232 | 1.93M | { | 233 | 9.91M | for (j = k_l; j < k_h; j++) | 234 | 7.97M | { | 235 | 7.97M | real_t re = QMF_RE(Xsbr[i][j]) + half; | 236 | 7.97M | real_t im = QMF_IM(Xsbr[i][j]) + half; | 237 | 7.97M | (void)im; | 238 | | /* Actually, that should be MUL_R. On floating-point build | 239 | | that is the same. On fixed point-build we use it to | 240 | | pre-scale result (to aviod overflow). That, of course | 241 | | causes some precision loss. */ | 242 | 7.97M | nrg += MUL_C(re, re) | 243 | 7.97M | #ifndef SBR_LOW_POWER | 244 | 7.97M | + MUL_C(im, im) | 245 | 7.97M | #endif | 246 | 7.97M | ; | 247 | 7.97M | } | 248 | 1.93M | } | 249 | | | 250 | 100k | if (nrg < -limit || nrg > limit) | 251 | 343 | return 1; | 252 | 100k | #ifdef FIXED_POINT | 253 | 100k | sbr->E_curr[ch][k - sbr->kx][l] = nrg * mul; | 254 | | #else | 255 | | sbr->E_curr[ch][k - sbr->kx][l] = nrg / div; | 256 | | #endif | 257 | | #ifdef SBR_LOW_POWER | 258 | | #ifdef FIXED_POINT | 259 | | sbr->E_curr[ch][k - sbr->kx][l] <<= 1; | 260 | | #else | 261 | | sbr->E_curr[ch][k - sbr->kx][l] *= 2; | 262 | | #endif | 263 | | #endif | 264 | 100k | } | 265 | 38.5k | } | 266 | 5.95k | } | 267 | 3.62k | } | 268 | | | 269 | 9.63k | return 0; | 270 | 10.1k | } |
sbr_hfadj.c:estimate_current_envelope Line | Count | Source | 139 | 14.1k | { | 140 | 14.1k | uint8_t m, l, j, k, k_l, k_h, p; | 141 | 14.1k | real_t nrg, div; | 142 | 14.1k | (void)adj; /* TODO: remove parameter? */ | 143 | | #ifdef FIXED_POINT | 144 | | const real_t half = REAL_CONST(0.5); | 145 | | real_t limit; | 146 | | real_t mul; | 147 | | #else | 148 | 14.1k | const real_t half = 0; /* Compiler is smart enough to eliminate +0 op. */ | 149 | 14.1k | const real_t limit = FLT_MAX; | 150 | 14.1k | #endif | 151 | | | 152 | 14.1k | if (sbr->bs_interpol_freq == 1) | 153 | 10.8k | { | 154 | 28.8k | for (l = 0; l < sbr->L_E[ch]; l++) | 155 | 18.0k | { | 156 | 18.0k | uint8_t i, l_i, u_i; | 157 | | | 158 | 18.0k | l_i = sbr->t_E[ch][l]; | 159 | 18.0k | u_i = sbr->t_E[ch][l+1]; | 160 | | | 161 | 18.0k | div = (real_t)(u_i - l_i); | 162 | | | 163 | 18.0k | if (div <= 0) | 164 | 589 | div = 1; | 165 | | #ifdef FIXED_POINT | 166 | | limit = div << (30 - (COEF_BITS - REAL_BITS)); | 167 | | mul = (1 << (COEF_BITS - REAL_BITS)) / div; | 168 | | #endif | 169 | | | 170 | 210k | for (m = 0; m < sbr->M; m++) | 171 | 192k | { | 172 | 192k | nrg = 0; | 173 | | | 174 | 3.87M | for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) | 175 | 3.67M | { | 176 | 3.67M | real_t re = QMF_RE(Xsbr[i][m + sbr->kx]) + half; | 177 | 3.67M | real_t im = QMF_IM(Xsbr[i][m + sbr->kx]) + half; | 178 | 3.67M | (void)im; | 179 | | /* Actually, that should be MUL_R. On floating-point build | 180 | | that is the same. On fixed point-build we use it to | 181 | | pre-scale result (to aviod overflow). That, of course | 182 | | causes some precision loss. */ | 183 | 3.67M | nrg += MUL_C(re, re) | 184 | 3.67M | #ifndef SBR_LOW_POWER | 185 | 3.67M | + MUL_C(im, im) | 186 | 3.67M | #endif | 187 | 3.67M | ; | 188 | 3.67M | } | 189 | | | 190 | 192k | if (nrg < -limit || nrg > limit) | 191 | 7 | return 1; | 192 | | #ifdef FIXED_POINT | 193 | | sbr->E_curr[ch][m][l] = nrg * mul; | 194 | | #else | 195 | 192k | sbr->E_curr[ch][m][l] = nrg / div; | 196 | 192k | #endif | 197 | | #ifdef SBR_LOW_POWER | 198 | | #ifdef FIXED_POINT | 199 | | sbr->E_curr[ch][m][l] <<= 1; | 200 | | #else | 201 | | sbr->E_curr[ch][m][l] *= 2; | 202 | | #endif | 203 | | #endif | 204 | 192k | } | 205 | 18.0k | } | 206 | 10.8k | } else { | 207 | 9.26k | for (l = 0; l < sbr->L_E[ch]; l++) | 208 | 5.91k | { | 209 | 45.2k | for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++) | 210 | 39.3k | { | 211 | 39.3k | k_l = sbr->f_table_res[sbr->f[ch][l]][p]; | 212 | 39.3k | k_h = sbr->f_table_res[sbr->f[ch][l]][p+1]; | 213 | | | 214 | 147k | for (k = k_l; k < k_h; k++) | 215 | 108k | { | 216 | 108k | uint8_t i, l_i, u_i; | 217 | 108k | nrg = 0; | 218 | | | 219 | 108k | l_i = sbr->t_E[ch][l]; | 220 | 108k | u_i = sbr->t_E[ch][l+1]; | 221 | | | 222 | 108k | div = (real_t)((u_i - l_i)*(k_h - k_l)); | 223 | | | 224 | 108k | if (div <= 0) | 225 | 6.18k | div = 1; | 226 | | #ifdef FIXED_POINT | 227 | | limit = div << (30 - (COEF_BITS - REAL_BITS)); | 228 | | mul = (1 << (COEF_BITS - REAL_BITS)) / div; | 229 | | #endif | 230 | | | 231 | 2.08M | for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) | 232 | 1.97M | { | 233 | 8.97M | for (j = k_l; j < k_h; j++) | 234 | 6.99M | { | 235 | 6.99M | real_t re = QMF_RE(Xsbr[i][j]) + half; | 236 | 6.99M | real_t im = QMF_IM(Xsbr[i][j]) + half; | 237 | 6.99M | (void)im; | 238 | | /* Actually, that should be MUL_R. On floating-point build | 239 | | that is the same. On fixed point-build we use it to | 240 | | pre-scale result (to aviod overflow). That, of course | 241 | | causes some precision loss. */ | 242 | 6.99M | nrg += MUL_C(re, re) | 243 | 6.99M | #ifndef SBR_LOW_POWER | 244 | 6.99M | + MUL_C(im, im) | 245 | 6.99M | #endif | 246 | 6.99M | ; | 247 | 6.99M | } | 248 | 1.97M | } | 249 | | | 250 | 108k | if (nrg < -limit || nrg > limit) | 251 | 6 | return 1; | 252 | | #ifdef FIXED_POINT | 253 | | sbr->E_curr[ch][k - sbr->kx][l] = nrg * mul; | 254 | | #else | 255 | 108k | sbr->E_curr[ch][k - sbr->kx][l] = nrg / div; | 256 | 108k | #endif | 257 | | #ifdef SBR_LOW_POWER | 258 | | #ifdef FIXED_POINT | 259 | | sbr->E_curr[ch][k - sbr->kx][l] <<= 1; | 260 | | #else | 261 | | sbr->E_curr[ch][k - sbr->kx][l] *= 2; | 262 | | #endif | 263 | | #endif | 264 | 108k | } | 265 | 39.3k | } | 266 | 5.91k | } | 267 | 3.36k | } | 268 | | | 269 | 14.1k | return 0; | 270 | 14.1k | } |
|
271 | | |
272 | | #ifdef FIXED_POINT |
273 | | #define EPS (1) /* smallest number available in fixed point */ |
274 | | #else |
275 | 184k | #define EPS (1e-12) |
276 | | #endif |
277 | | |
278 | | |
279 | | |
280 | | #ifdef FIXED_POINT |
281 | | |
282 | | /* log2 values of [0..63] */ |
283 | | static const real_t log2_int_tab[] = { |
284 | | LOG2_MIN_INF, REAL_CONST(0.000000000000000), REAL_CONST(1.000000000000000), REAL_CONST(1.584962500721156), |
285 | | REAL_CONST(2.000000000000000), REAL_CONST(2.321928094887362), REAL_CONST(2.584962500721156), REAL_CONST(2.807354922057604), |
286 | | REAL_CONST(3.000000000000000), REAL_CONST(3.169925001442313), REAL_CONST(3.321928094887363), REAL_CONST(3.459431618637297), |
287 | | REAL_CONST(3.584962500721156), REAL_CONST(3.700439718141092), REAL_CONST(3.807354922057604), REAL_CONST(3.906890595608519), |
288 | | REAL_CONST(4.000000000000000), REAL_CONST(4.087462841250339), REAL_CONST(4.169925001442312), REAL_CONST(4.247927513443585), |
289 | | REAL_CONST(4.321928094887362), REAL_CONST(4.392317422778761), REAL_CONST(4.459431618637297), REAL_CONST(4.523561956057013), |
290 | | REAL_CONST(4.584962500721156), REAL_CONST(4.643856189774724), REAL_CONST(4.700439718141093), REAL_CONST(4.754887502163468), |
291 | | REAL_CONST(4.807354922057604), REAL_CONST(4.857980995127572), REAL_CONST(4.906890595608519), REAL_CONST(4.954196310386875), |
292 | | REAL_CONST(5.000000000000000), REAL_CONST(5.044394119358453), REAL_CONST(5.087462841250340), REAL_CONST(5.129283016944966), |
293 | | REAL_CONST(5.169925001442312), REAL_CONST(5.209453365628949), REAL_CONST(5.247927513443585), REAL_CONST(5.285402218862248), |
294 | | REAL_CONST(5.321928094887363), REAL_CONST(5.357552004618084), REAL_CONST(5.392317422778761), REAL_CONST(5.426264754702098), |
295 | | REAL_CONST(5.459431618637297), REAL_CONST(5.491853096329675), REAL_CONST(5.523561956057013), REAL_CONST(5.554588851677637), |
296 | | REAL_CONST(5.584962500721156), REAL_CONST(5.614709844115208), REAL_CONST(5.643856189774724), REAL_CONST(5.672425341971495), |
297 | | REAL_CONST(5.700439718141093), REAL_CONST(5.727920454563200), REAL_CONST(5.754887502163469), REAL_CONST(5.781359713524660), |
298 | | REAL_CONST(5.807354922057605), REAL_CONST(5.832890014164742), REAL_CONST(5.857980995127572), REAL_CONST(5.882643049361842), |
299 | | REAL_CONST(5.906890595608518), REAL_CONST(5.930737337562887), REAL_CONST(5.954196310386876), REAL_CONST(5.977279923499916) |
300 | | }; |
301 | | |
302 | | // pan_log2_tab[X] = log2(2**X + 1) - X |
303 | | static const real_t pan_log2_tab[13] = { |
304 | | REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), |
305 | | REAL_CONST(0.044394119358453), REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), REAL_CONST(0.002815015607054), |
306 | | REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), REAL_CONST(0.000352177480301) |
307 | | }; |
308 | | |
309 | | static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) |
310 | 362k | { |
311 | | /* check for coupled energy/noise data */ |
312 | 362k | if (sbr->bs_coupling == 1) |
313 | 166k | { |
314 | 166k | int16_t e = sbr->E[0][k][l]; |
315 | 166k | int16_t E = sbr->E[1][k][l]; |
316 | 166k | uint8_t amp0 = (sbr->amp_res[0]) ? 0 : 1; |
317 | 166k | uint8_t amp1 = (sbr->amp_res[1]) ? 0 : 1; |
318 | 166k | real_t tmp, pan; |
319 | | |
320 | | /* E[1] should always be even so shifting is OK */ |
321 | 166k | E >>= amp1; |
322 | 166k | if (e < 0 || e >= 64 || E < 0 || E > 24) |
323 | 43.6k | return LOG2_MIN_INF; |
324 | 122k | E -= 12; |
325 | | |
326 | 122k | if (ch != 0) // L/R anti-symmetry |
327 | 60.5k | E = -E; |
328 | | |
329 | 122k | if (E >= 0) |
330 | 61.4k | { |
331 | | /* negative */ |
332 | 61.4k | pan = pan_log2_tab[E]; |
333 | 61.4k | } else { |
334 | | /* positive */ |
335 | 61.0k | pan = pan_log2_tab[-E] + ((-E)<<REAL_BITS); |
336 | 61.0k | } |
337 | | |
338 | | /* tmp / pan in log2 */ |
339 | 122k | tmp = (7 << REAL_BITS) + (e << (REAL_BITS-amp0)); |
340 | 122k | return tmp - pan; |
341 | 195k | } else { |
342 | 195k | int16_t e = sbr->E[ch][k][l]; |
343 | 195k | uint8_t amp = (sbr->amp_res[ch]) ? 0 : 1; |
344 | 195k | if (e < 0 || (e >> amp) >= 64) |
345 | 24.5k | return LOG2_MIN_INF; |
346 | 171k | return 6 * REAL_PRECISION + e * (REAL_PRECISION >> amp); |
347 | 195k | } |
348 | 362k | } |
349 | | |
350 | | static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) |
351 | 247k | { |
352 | | /* check for coupled energy/noise data */ |
353 | 247k | if (sbr->bs_coupling == 1) |
354 | 113k | { |
355 | 113k | int32_t q = sbr->Q[0][k][l]; |
356 | 113k | int32_t Q = sbr->Q[1][k][l]; |
357 | 113k | real_t tmp, pan; |
358 | | |
359 | 113k | if (q < 0 || q > 30 || Q < 0 || Q > 24) |
360 | 22.6k | return LOG2_MIN_INF; |
361 | 90.9k | Q -= 12; |
362 | | |
363 | 90.9k | if (ch != 0) // L/R anti-symmetry |
364 | 45.0k | Q = -Q; |
365 | | |
366 | 90.9k | if (Q >= 0) |
367 | 45.1k | { |
368 | | /* negative */ |
369 | 45.1k | pan = pan_log2_tab[Q]; |
370 | 45.7k | } else { |
371 | | /* positive */ |
372 | 45.7k | pan = pan_log2_tab[-Q] + ((-Q)<<REAL_BITS); |
373 | 45.7k | } |
374 | | |
375 | | /* tmp / pan in log2 */ |
376 | 90.9k | tmp = (7 - q) * REAL_PRECISION; |
377 | 90.9k | return tmp - pan; |
378 | 134k | } else { |
379 | 134k | int32_t q = sbr->Q[ch][k][l]; |
380 | 134k | if (q < 0 || q > 30) |
381 | 20.1k | return LOG2_MIN_INF; |
382 | 114k | return (6 - q) * REAL_PRECISION; |
383 | 134k | } |
384 | 247k | } |
385 | | |
386 | | static const real_t log_Qplus1_pan[31][13] = { |
387 | | { REAL_CONST(0.044383447617292), REAL_CONST(0.169768601655960), REAL_CONST(0.583090126514435), REAL_CONST(1.570089221000671), REAL_CONST(3.092446088790894), REAL_CONST(4.733354568481445), REAL_CONST(6.022367954254150), REAL_CONST(6.692092418670654), REAL_CONST(6.924463272094727), REAL_CONST(6.989034175872803), REAL_CONST(7.005646705627441), REAL_CONST(7.009829998016357), REAL_CONST(7.010877609252930) }, |
388 | | { REAL_CONST(0.022362394258380), REAL_CONST(0.087379962205887), REAL_CONST(0.320804953575134), REAL_CONST(0.988859415054321), REAL_CONST(2.252387046813965), REAL_CONST(3.786596298217773), REAL_CONST(5.044394016265869), REAL_CONST(5.705977916717529), REAL_CONST(5.936291694641113), REAL_CONST(6.000346660614014), REAL_CONST(6.016829967498779), REAL_CONST(6.020981311798096), REAL_CONST(6.022020816802979) }, |
389 | | { REAL_CONST(0.011224525049329), REAL_CONST(0.044351425021887), REAL_CONST(0.169301137328148), REAL_CONST(0.577544987201691), REAL_CONST(1.527246952056885), REAL_CONST(2.887525320053101), REAL_CONST(4.087462902069092), REAL_CONST(4.733354568481445), REAL_CONST(4.959661006927490), REAL_CONST(5.022709369659424), REAL_CONST(5.038940429687500), REAL_CONST(5.043028831481934), REAL_CONST(5.044052600860596) }, |
390 | | { REAL_CONST(0.005623178556561), REAL_CONST(0.022346137091517), REAL_CONST(0.087132595479488), REAL_CONST(0.317482173442841), REAL_CONST(0.956931233406067), REAL_CONST(2.070389270782471), REAL_CONST(3.169924974441528), REAL_CONST(3.786596298217773), REAL_CONST(4.005294322967529), REAL_CONST(4.066420555114746), REAL_CONST(4.082170009613037), REAL_CONST(4.086137294769287), REAL_CONST(4.087131500244141) }, |
391 | | { REAL_CONST(0.002814328996465), REAL_CONST(0.011216334067285), REAL_CONST(0.044224001467228), REAL_CONST(0.167456731200218), REAL_CONST(0.556393325328827), REAL_CONST(1.378511548042297), REAL_CONST(2.321928024291992), REAL_CONST(2.887525320053101), REAL_CONST(3.092446088790894), REAL_CONST(3.150059700012207), REAL_CONST(3.164926528930664), REAL_CONST(3.168673276901245), REAL_CONST(3.169611930847168) }, |
392 | | { REAL_CONST(0.001407850766554), REAL_CONST(0.005619067233056), REAL_CONST(0.022281449288130), REAL_CONST(0.086156636476517), REAL_CONST(0.304854571819305), REAL_CONST(0.847996890544891), REAL_CONST(1.584962487220764), REAL_CONST(2.070389270782471), REAL_CONST(2.252387046813965), REAL_CONST(2.304061651229858), REAL_CONST(2.317430257797241), REAL_CONST(2.320801734924316), REAL_CONST(2.321646213531494) }, |
393 | | { REAL_CONST(0.000704097095877), REAL_CONST(0.002812269143760), REAL_CONST(0.011183738708496), REAL_CONST(0.043721374124289), REAL_CONST(0.160464659333229), REAL_CONST(0.485426813364029), REAL_CONST(1.000000000000000), REAL_CONST(1.378511548042297), REAL_CONST(1.527246952056885), REAL_CONST(1.570089221000671), REAL_CONST(1.581215262413025), REAL_CONST(1.584023833274841), REAL_CONST(1.584727644920349) }, |
394 | | { REAL_CONST(0.000352177477907), REAL_CONST(0.001406819908880), REAL_CONST(0.005602621007711), REAL_CONST(0.022026389837265), REAL_CONST(0.082462236285210), REAL_CONST(0.263034462928772), REAL_CONST(0.584962487220764), REAL_CONST(0.847996890544891), REAL_CONST(0.956931233406067), REAL_CONST(0.988859415054321), REAL_CONST(0.997190535068512), REAL_CONST(0.999296069145203), REAL_CONST(0.999823868274689) }, |
395 | | { REAL_CONST(0.000176099492819), REAL_CONST(0.000703581434209), REAL_CONST(0.002804030198604), REAL_CONST(0.011055230163038), REAL_CONST(0.041820213198662), REAL_CONST(0.137503549456596), REAL_CONST(0.321928083896637), REAL_CONST(0.485426813364029), REAL_CONST(0.556393325328827), REAL_CONST(0.577544987201691), REAL_CONST(0.583090126514435), REAL_CONST(0.584493279457092), REAL_CONST(0.584845066070557) }, |
396 | | { REAL_CONST(0.000088052431238), REAL_CONST(0.000351833587047), REAL_CONST(0.001402696361765), REAL_CONST(0.005538204684854), REAL_CONST(0.021061634644866), REAL_CONST(0.070389263331890), REAL_CONST(0.169925004243851), REAL_CONST(0.263034462928772), REAL_CONST(0.304854571819305), REAL_CONST(0.317482173442841), REAL_CONST(0.320804953575134), REAL_CONST(0.321646571159363), REAL_CONST(0.321857661008835) }, |
397 | | { REAL_CONST(0.000044026888645), REAL_CONST(0.000175927518285), REAL_CONST(0.000701518612914), REAL_CONST(0.002771759871393), REAL_CONST(0.010569252073765), REAL_CONST(0.035623874515295), REAL_CONST(0.087462842464447), REAL_CONST(0.137503549456596), REAL_CONST(0.160464659333229), REAL_CONST(0.167456731200218), REAL_CONST(0.169301137328148), REAL_CONST(0.169768601655960), REAL_CONST(0.169885858893394) }, |
398 | | { REAL_CONST(0.000022013611670), REAL_CONST(0.000088052431238), REAL_CONST(0.000350801943569), REAL_CONST(0.001386545598507), REAL_CONST(0.005294219125062), REAL_CONST(0.017921976745129), REAL_CONST(0.044394120573997), REAL_CONST(0.070389263331890), REAL_CONST(0.082462236285210), REAL_CONST(0.086156636476517), REAL_CONST(0.087132595479488), REAL_CONST(0.087379962205887), REAL_CONST(0.087442122399807) }, |
399 | | { REAL_CONST(0.000011006847672), REAL_CONST(0.000044026888645), REAL_CONST(0.000175411638338), REAL_CONST(0.000693439331371), REAL_CONST(0.002649537986144), REAL_CONST(0.008988817222416), REAL_CONST(0.022367812693119), REAL_CONST(0.035623874515295), REAL_CONST(0.041820213198662), REAL_CONST(0.043721374124289), REAL_CONST(0.044224001467228), REAL_CONST(0.044351425021887), REAL_CONST(0.044383447617292) }, |
400 | | { REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000087708482170), REAL_CONST(0.000346675369656), REAL_CONST(0.001325377263129), REAL_CONST(0.004501323681325), REAL_CONST(0.011227255687118), REAL_CONST(0.017921976745129), REAL_CONST(0.021061634644866), REAL_CONST(0.022026389837265), REAL_CONST(0.022281449288130), REAL_CONST(0.022346137091517), REAL_CONST(0.022362394258380) }, |
401 | | { REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043854910473), REAL_CONST(0.000173348103999), REAL_CONST(0.000662840844598), REAL_CONST(0.002252417383716), REAL_CONST(0.005624548997730), REAL_CONST(0.008988817222416), REAL_CONST(0.010569252073765), REAL_CONST(0.011055230163038), REAL_CONST(0.011183738708496), REAL_CONST(0.011216334067285), REAL_CONST(0.011224525049329) }, |
402 | | { REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000086676649516), REAL_CONST(0.000331544462824), REAL_CONST(0.001126734190620), REAL_CONST(0.002815015614033), REAL_CONST(0.004501323681325), REAL_CONST(0.005294219125062), REAL_CONST(0.005538204684854), REAL_CONST(0.005602621007711), REAL_CONST(0.005619067233056), REAL_CONST(0.005623178556561) }, |
403 | | { REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043338975956), REAL_CONST(0.000165781748365), REAL_CONST(0.000563477107789), REAL_CONST(0.001408194424585), REAL_CONST(0.002252417383716), REAL_CONST(0.002649537986144), REAL_CONST(0.002771759871393), REAL_CONST(0.002804030198604), REAL_CONST(0.002812269143760), REAL_CONST(0.002814328996465) }, |
404 | | { REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000021669651687), REAL_CONST(0.000082893253420), REAL_CONST(0.000281680084299), REAL_CONST(0.000704268983100), REAL_CONST(0.001126734190620), REAL_CONST(0.001325377263129), REAL_CONST(0.001386545598507), REAL_CONST(0.001402696361765), REAL_CONST(0.001406819908880), REAL_CONST(0.001407850766554) }, |
405 | | { REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010834866771), REAL_CONST(0.000041447223339), REAL_CONST(0.000140846910654), REAL_CONST(0.000352177477907), REAL_CONST(0.000563477107789), REAL_CONST(0.000662840844598), REAL_CONST(0.000693439331371), REAL_CONST(0.000701518612914), REAL_CONST(0.000703581434209), REAL_CONST(0.000704097095877) }, |
406 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000020637769921), REAL_CONST(0.000070511166996), REAL_CONST(0.000176099492819), REAL_CONST(0.000281680084299), REAL_CONST(0.000331544462824), REAL_CONST(0.000346675369656), REAL_CONST(0.000350801943569), REAL_CONST(0.000351833587047), REAL_CONST(0.000352177477907) }, |
407 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010318922250), REAL_CONST(0.000035256012779), REAL_CONST(0.000088052431238), REAL_CONST(0.000140846910654), REAL_CONST(0.000165781748365), REAL_CONST(0.000173348103999), REAL_CONST(0.000175411638338), REAL_CONST(0.000175927518285), REAL_CONST(0.000176099492819) }, |
408 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005159470220), REAL_CONST(0.000017542124624), REAL_CONST(0.000044026888645), REAL_CONST(0.000070511166996), REAL_CONST(0.000082893253420), REAL_CONST(0.000086676649516), REAL_CONST(0.000087708482170), REAL_CONST(0.000088052431238), REAL_CONST(0.000088052431238) }, |
409 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002579737384), REAL_CONST(0.000008771088687), REAL_CONST(0.000022013611670), REAL_CONST(0.000035256012779), REAL_CONST(0.000041447223339), REAL_CONST(0.000043338975956), REAL_CONST(0.000043854910473), REAL_CONST(0.000044026888645), REAL_CONST(0.000044026888645) }, |
410 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000004471542070), REAL_CONST(0.000011006847672), REAL_CONST(0.000017542124624), REAL_CONST(0.000020637769921), REAL_CONST(0.000021669651687), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670) }, |
411 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002235772627), REAL_CONST(0.000005503434295), REAL_CONST(0.000008771088687), REAL_CONST(0.000010318922250), REAL_CONST(0.000010834866771), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672) }, |
412 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001031895522), REAL_CONST(0.000002751719876), REAL_CONST(0.000004471542070), REAL_CONST(0.000005159470220), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295) }, |
413 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000515947875), REAL_CONST(0.000001375860506), REAL_CONST(0.000002235772627), REAL_CONST(0.000002579737384), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876) }, |
414 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000000687930424), REAL_CONST(0.000001031895522), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506) }, |
415 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000515947875), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424) }, |
416 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269) }, |
417 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634) } |
418 | | }; |
419 | | |
420 | | static const real_t log_Qplus1[31] = { |
421 | | REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339), |
422 | | REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156), |
423 | | REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), |
424 | | REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453), |
425 | | REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), |
426 | | REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), |
427 | | REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122), |
428 | | REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667), |
429 | | REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551), |
430 | | REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641), |
431 | | REAL_CONST(0.000000000000000) |
432 | | }; |
433 | | |
434 | | static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) |
435 | 247k | { |
436 | | /* check for coupled energy/noise data */ |
437 | 247k | if (sbr->bs_coupling == 1) |
438 | 113k | { |
439 | 113k | if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) && |
440 | 113k | (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24)) |
441 | 90.9k | { |
442 | 90.9k | if (ch == 0) |
443 | 45.9k | { |
444 | 45.9k | return log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1]; |
445 | 45.9k | } else { |
446 | 45.0k | return log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)]; |
447 | 45.0k | } |
448 | 90.9k | } else { |
449 | 22.6k | return 0; |
450 | 22.6k | } |
451 | 134k | } else { |
452 | 134k | if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30) |
453 | 114k | { |
454 | 114k | return log_Qplus1[sbr->Q[ch][k][l]]; |
455 | 114k | } else { |
456 | 20.1k | return 0; |
457 | 20.1k | } |
458 | 134k | } |
459 | 247k | } |
460 | | |
461 | | static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) |
462 | 9.63k | { |
463 | | /* log2 values of limiter gains */ |
464 | | /* Last one less than log2(1e10) due to FIXED POINT float limitations */ |
465 | 9.63k | static real_t limGain[] = { |
466 | 9.63k | REAL_CONST(-1.0), REAL_CONST(0.0), REAL_CONST(1.0), REAL_CONST(21.0) |
467 | 9.63k | }; |
468 | 9.63k | uint8_t m, l, k; |
469 | | |
470 | 9.63k | uint8_t current_t_noise_band = 0; |
471 | 9.63k | uint8_t S_mapped; |
472 | | |
473 | 9.63k | ALIGN real_t Q_M_lim[MAX_M]; |
474 | 9.63k | ALIGN real_t G_lim[MAX_M]; |
475 | 9.63k | ALIGN real_t G_boost; |
476 | 9.63k | ALIGN real_t S_M[MAX_M]; |
477 | | |
478 | 9.63k | real_t exp = REAL_CONST(-10); |
479 | | |
480 | 26.2k | for (l = 0; l < sbr->L_E[ch]; l++) |
481 | 16.5k | { |
482 | 16.5k | uint8_t current_f_noise_band = 0; |
483 | 16.5k | uint8_t current_res_band = 0; |
484 | 16.5k | uint8_t current_res_band2 = 0; |
485 | 16.5k | uint8_t current_hi_res_band = 0; |
486 | | |
487 | 16.5k | real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; |
488 | | |
489 | 16.5k | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); |
490 | | |
491 | 16.5k | if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) |
492 | 2.64k | { |
493 | 2.64k | current_t_noise_band++; |
494 | 2.64k | } |
495 | | |
496 | 54.4k | for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) |
497 | 37.8k | { |
498 | 37.8k | real_t Q_M = 0; |
499 | 37.8k | real_t G_max; |
500 | 37.8k | uint64_t den = 0, acc1 = 0, acc2 = 0; |
501 | 37.8k | uint8_t current_res_band_size = 0; |
502 | 37.8k | uint8_t Q_M_size = 0; |
503 | 37.8k | real_t log_e, log_den, log_acc1, log_acc2; |
504 | | |
505 | 37.8k | uint8_t ml1, ml2; |
506 | | |
507 | | /* bounds of current limiter bands */ |
508 | 37.8k | ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; |
509 | 37.8k | ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; |
510 | | |
511 | 37.8k | if (ml1 > MAX_M) |
512 | 0 | ml1 = MAX_M; |
513 | | |
514 | 37.8k | if (ml2 > MAX_M) |
515 | 0 | ml2 = MAX_M; |
516 | | |
517 | | |
518 | | /* calculate the accumulated E_orig and E_curr over the limiter band */ |
519 | 285k | for (m = ml1; m < ml2; m++) |
520 | 247k | { |
521 | 247k | if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) |
522 | 171k | { |
523 | 171k | current_res_band_size++; |
524 | 171k | } else { |
525 | 76.3k | log_e = find_log2_E(sbr, current_res_band, l, ch); |
526 | 76.3k | acc1 += pow2_int(exp + log2_int_tab[current_res_band_size] + log_e); |
527 | | |
528 | 76.3k | current_res_band++; |
529 | 76.3k | current_res_band_size = 1; |
530 | 76.3k | } |
531 | | |
532 | 247k | acc2 += sbr->E_curr[ch][m][l]; |
533 | 247k | } |
534 | 37.8k | if (current_res_band_size) { |
535 | 37.8k | log_e = find_log2_E(sbr, current_res_band, l, ch); |
536 | 37.8k | acc1 += pow2_int(exp + log2_int_tab[current_res_band_size] + log_e); |
537 | 37.8k | } |
538 | | |
539 | | |
540 | 37.8k | if (acc1 == 0) |
541 | 23.2k | log_acc1 = LOG2_MIN_INF; |
542 | 14.6k | else |
543 | 14.6k | log_acc1 = log2_int(acc1); |
544 | | |
545 | 37.8k | if (acc2 == 0) |
546 | 37.1k | log_acc2 = LOG2_MIN_INF; |
547 | 672 | else |
548 | 672 | log_acc2 = log2_int(acc2); |
549 | | |
550 | | /* calculate the maximum gain */ |
551 | | /* ratio of the energy of the original signal and the energy |
552 | | * of the HF generated signal |
553 | | */ |
554 | 37.8k | G_max = log_acc1 - log_acc2 + limGain[sbr->bs_limiter_gains]; |
555 | 37.8k | G_max = min(G_max, limGain[3]); |
556 | | |
557 | | |
558 | 285k | for (m = ml1; m < ml2; m++) |
559 | 247k | { |
560 | 247k | real_t G; |
561 | 247k | real_t E_curr, E_orig; |
562 | 247k | real_t Q_orig, Q_orig_plus1; |
563 | 247k | uint8_t S_index_mapped; |
564 | | |
565 | | |
566 | | /* check if m is on a noise band border */ |
567 | 247k | if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) |
568 | 15.3k | { |
569 | | /* step to next noise band */ |
570 | 15.3k | current_f_noise_band++; |
571 | 15.3k | } |
572 | | |
573 | | |
574 | | /* check if m is on a resolution band border */ |
575 | 247k | if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) |
576 | 76.2k | { |
577 | | /* accumulate a whole range of equal Q_Ms */ |
578 | 76.2k | if (Q_M_size > 0) |
579 | 32.6k | den += pow2_int(log2_int_tab[Q_M_size] + Q_M); |
580 | 76.2k | Q_M_size = 0; |
581 | | |
582 | | /* step to next resolution band */ |
583 | 76.2k | current_res_band2++; |
584 | | |
585 | | /* if we move to a new resolution band, we should check if we are |
586 | | * going to add a sinusoid in this band |
587 | | */ |
588 | 76.2k | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); |
589 | 76.2k | } |
590 | | |
591 | | |
592 | | /* check if m is on a HI_RES band border */ |
593 | 247k | if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) |
594 | 121k | { |
595 | | /* step to next HI_RES band */ |
596 | 121k | current_hi_res_band++; |
597 | 121k | } |
598 | | |
599 | | |
600 | | /* find S_index_mapped |
601 | | * S_index_mapped can only be 1 for the m in the middle of the |
602 | | * current HI_RES band |
603 | | */ |
604 | 247k | S_index_mapped = 0; |
605 | 247k | if ((l >= sbr->l_A[ch]) || |
606 | 247k | (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) |
607 | 191k | { |
608 | | /* find the middle subband of the HI_RES frequency band */ |
609 | 191k | if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) |
610 | 103k | S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; |
611 | 191k | } |
612 | | |
613 | | |
614 | | /* find bitstream parameters */ |
615 | 247k | if (sbr->E_curr[ch][m][l] == 0) |
616 | 242k | E_curr = LOG2_MIN_INF; |
617 | 4.95k | else |
618 | 4.95k | E_curr = log2_int(sbr->E_curr[ch][m][l]); |
619 | 247k | E_orig = exp + find_log2_E(sbr, current_res_band2, l, ch); |
620 | | |
621 | | |
622 | 247k | Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch); |
623 | 247k | Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch); |
624 | | |
625 | | |
626 | | /* Q_M only depends on E_orig and Q_div2: |
627 | | * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on |
628 | | * a change of current res band (HI or LO) |
629 | | */ |
630 | 247k | Q_M = E_orig + Q_orig - Q_orig_plus1; |
631 | | |
632 | | |
633 | | /* S_M only depends on E_orig, Q_div and S_index_mapped: |
634 | | * S_index_mapped can only be non-zero once per HI_RES band |
635 | | */ |
636 | 247k | if (S_index_mapped == 0) |
637 | 230k | { |
638 | 230k | S_M[m] = LOG2_MIN_INF; /* -inf */ |
639 | 230k | } else { |
640 | 17.3k | S_M[m] = E_orig - Q_orig_plus1; |
641 | 17.3k | S_M[m] = min(S_M[m], limGain[3]); |
642 | | |
643 | | /* accumulate sinusoid part of the total energy */ |
644 | 17.3k | den += pow2_int(S_M[m]); |
645 | 17.3k | } |
646 | | |
647 | | |
648 | | /* calculate gain */ |
649 | | /* ratio of the energy of the original signal and the energy |
650 | | * of the HF generated signal |
651 | | */ |
652 | | /* E_curr here is officially E_curr+1 so the log2() of that can never be < 0 */ |
653 | | /* scaled by exp */ |
654 | 247k | G = E_orig - max(exp, E_curr); |
655 | 247k | if ((S_mapped == 0) && (delta == 1)) |
656 | 188k | { |
657 | | /* G = G * 1/(1+Q) */ |
658 | 188k | G -= Q_orig_plus1; |
659 | 188k | } else if (S_mapped == 1) { |
660 | | /* G = G * Q/(1+Q) */ |
661 | 39.6k | G += Q_orig - Q_orig_plus1; |
662 | 39.6k | } |
663 | | |
664 | | |
665 | | /* limit the additional noise energy level */ |
666 | | /* and apply the limiter */ |
667 | 247k | if (G_max > G) |
668 | 160k | { |
669 | 160k | Q_M_lim[m] = Q_M; |
670 | 160k | G_lim[m] = G; |
671 | | |
672 | 160k | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) |
673 | 140k | { |
674 | 140k | Q_M_size++; |
675 | 140k | } |
676 | 160k | } else { |
677 | | /* G >= G_max */ |
678 | 86.9k | Q_M_lim[m] = Q_M + G_max - G; |
679 | 86.9k | G_lim[m] = G_max; |
680 | | |
681 | | /* accumulate limited Q_M */ |
682 | 86.9k | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) |
683 | 75.4k | { |
684 | 75.4k | den += pow2_int(Q_M_lim[m]); |
685 | 75.4k | } |
686 | 86.9k | } |
687 | | |
688 | | |
689 | | /* accumulate the total energy */ |
690 | | /* E_curr changes for every m so we do need to accumulate every m */ |
691 | 247k | den += pow2_int(E_curr + G_lim[m]); |
692 | 247k | } |
693 | | |
694 | | /* accumulate last range of equal Q_Ms */ |
695 | 37.8k | if (Q_M_size > 0) |
696 | 22.5k | { |
697 | 22.5k | den += pow2_int(log2_int_tab[Q_M_size] + Q_M); |
698 | 22.5k | } |
699 | | |
700 | 37.8k | if (den == 0) |
701 | 28.4k | log_den = LOG2_MIN_INF; |
702 | 9.45k | else |
703 | 9.45k | log_den = log2_int(den /*+ EPS*/); |
704 | | |
705 | | /* calculate the final gain */ |
706 | | /* G_boost: [0..2.51188643] */ |
707 | 37.8k | G_boost = log_acc1 - log_den; |
708 | 37.8k | G_boost = min(G_boost, REAL_CONST(1.328771237) /* log2(1.584893192 ^ 2) */); |
709 | | |
710 | | |
711 | 285k | for (m = ml1; m < ml2; m++) |
712 | 247k | { |
713 | | /* apply compensation to gain, noise floor sf's and sinusoid levels */ |
714 | 247k | #ifndef SBR_LOW_POWER |
715 | 247k | adj->G_lim_boost[l][m] = pow2_fix((G_lim[m] + G_boost) >> 1); |
716 | | #else |
717 | | /* sqrt() will be done after the aliasing reduction to save a |
718 | | * few multiplies |
719 | | */ |
720 | | adj->G_lim_boost[l][m] = pow2_fix(G_lim[m] + G_boost); |
721 | | #endif |
722 | 247k | adj->Q_M_lim_boost[l][m] = pow2_fix((Q_M_lim[m] + G_boost) >> 1); |
723 | | |
724 | 247k | adj->S_M_boost[l][m] = pow2_fix((S_M[m] + G_boost) >> 1); |
725 | 247k | } |
726 | 37.8k | } |
727 | 16.5k | } |
728 | 9.63k | } |
729 | | |
730 | | #else |
731 | | |
732 | | //#define LOG2_TEST |
733 | | |
734 | | #ifdef LOG2_TEST |
735 | | |
736 | | #define LOG2_MIN_INF -100000 |
737 | | |
738 | | __inline float pow2(float val) |
739 | | { |
740 | | return pow(2.0, val); |
741 | | } |
742 | | __inline float log2(float val) |
743 | | { |
744 | | return log(val)/log(2.0); |
745 | | } |
746 | | |
747 | | #define RB 14 |
748 | | |
749 | | float QUANTISE2REAL(float val) |
750 | | { |
751 | | __int32 ival = (__int32)(val * (1<<RB)); |
752 | | return (float)ival / (float)((1<<RB)); |
753 | | } |
754 | | |
755 | | float QUANTISE2INT(float val) |
756 | | { |
757 | | return floor(val); |
758 | | } |
759 | | |
760 | | /* log2 values of [0..63] */ |
761 | | static const real_t log2_int_tab[] = { |
762 | | LOG2_MIN_INF, 0.000000000000000, 1.000000000000000, 1.584962500721156, |
763 | | 2.000000000000000, 2.321928094887362, 2.584962500721156, 2.807354922057604, |
764 | | 3.000000000000000, 3.169925001442313, 3.321928094887363, 3.459431618637297, |
765 | | 3.584962500721156, 3.700439718141092, 3.807354922057604, 3.906890595608519, |
766 | | 4.000000000000000, 4.087462841250339, 4.169925001442312, 4.247927513443585, |
767 | | 4.321928094887362, 4.392317422778761, 4.459431618637297, 4.523561956057013, |
768 | | 4.584962500721156, 4.643856189774724, 4.700439718141093, 4.754887502163468, |
769 | | 4.807354922057604, 4.857980995127572, 4.906890595608519, 4.954196310386875, |
770 | | 5.000000000000000, 5.044394119358453, 5.087462841250340, 5.129283016944966, |
771 | | 5.169925001442312, 5.209453365628949, 5.247927513443585, 5.285402218862248, |
772 | | 5.321928094887363, 5.357552004618084, 5.392317422778761, 5.426264754702098, |
773 | | 5.459431618637297, 5.491853096329675, 5.523561956057013, 5.554588851677637, |
774 | | 5.584962500721156, 5.614709844115208, 5.643856189774724, 5.672425341971495, |
775 | | 5.700439718141093, 5.727920454563200, 5.754887502163469, 5.781359713524660, |
776 | | 5.807354922057605, 5.832890014164742, 5.857980995127572, 5.882643049361842, |
777 | | 5.906890595608518, 5.930737337562887, 5.954196310386876, 5.977279923499916 |
778 | | }; |
779 | | |
780 | | static const real_t pan_log2_tab[] = { |
781 | | 1.000000000000000, 0.584962500721156, 0.321928094887362, 0.169925001442312, 0.087462841250339, |
782 | | 0.044394119358453, 0.022367813028455, 0.011227255423254, 0.005624549193878, 0.002815015607054, |
783 | | 0.001408194392808, 0.000704269011247, 0.000352177480301, 0.000176099486443, 0.000088052430122, |
784 | | 0.000044026886827, 0.000022013611360, 0.000011006847667 |
785 | | }; |
786 | | |
787 | | static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) |
788 | | { |
789 | | /* check for coupled energy/noise data */ |
790 | | if (sbr->bs_coupling == 1) |
791 | | { |
792 | | real_t amp0 = (sbr->amp_res[0]) ? 1.0 : 0.5; |
793 | | real_t amp1 = (sbr->amp_res[1]) ? 1.0 : 0.5; |
794 | | float tmp = QUANTISE2REAL(7.0 + (real_t)sbr->E[0][k][l] * amp0); |
795 | | float pan; |
796 | | |
797 | | int E = (int)(sbr->E[1][k][l] * amp1); |
798 | | |
799 | | if (ch == 0) |
800 | | { |
801 | | if (E > 12) |
802 | | { |
803 | | /* negative */ |
804 | | pan = QUANTISE2REAL(pan_log2_tab[-12 + E]); |
805 | | } else { |
806 | | /* positive */ |
807 | | pan = QUANTISE2REAL(pan_log2_tab[12 - E] + (12 - E)); |
808 | | } |
809 | | } else { |
810 | | if (E < 12) |
811 | | { |
812 | | /* negative */ |
813 | | pan = QUANTISE2REAL(pan_log2_tab[-E + 12]); |
814 | | } else { |
815 | | /* positive */ |
816 | | pan = QUANTISE2REAL(pan_log2_tab[E - 12] + (E - 12)); |
817 | | } |
818 | | } |
819 | | |
820 | | /* tmp / pan in log2 */ |
821 | | return QUANTISE2REAL(tmp - pan); |
822 | | } else { |
823 | | real_t amp = (sbr->amp_res[ch]) ? 1.0 : 0.5; |
824 | | |
825 | | return QUANTISE2REAL(6.0 + (real_t)sbr->E[ch][k][l] * amp); |
826 | | } |
827 | | } |
828 | | |
829 | | static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) |
830 | | { |
831 | | /* check for coupled energy/noise data */ |
832 | | if (sbr->bs_coupling == 1) |
833 | | { |
834 | | float tmp = QUANTISE2REAL(7.0 - (real_t)sbr->Q[0][k][l]); |
835 | | float pan; |
836 | | |
837 | | int Q = (int)(sbr->Q[1][k][l]); |
838 | | |
839 | | if (ch == 0) |
840 | | { |
841 | | if (Q > 12) |
842 | | { |
843 | | /* negative */ |
844 | | pan = QUANTISE2REAL(pan_log2_tab[-12 + Q]); |
845 | | } else { |
846 | | /* positive */ |
847 | | pan = QUANTISE2REAL(pan_log2_tab[12 - Q] + (12 - Q)); |
848 | | } |
849 | | } else { |
850 | | if (Q < 12) |
851 | | { |
852 | | /* negative */ |
853 | | pan = QUANTISE2REAL(pan_log2_tab[-Q + 12]); |
854 | | } else { |
855 | | /* positive */ |
856 | | pan = QUANTISE2REAL(pan_log2_tab[Q - 12] + (Q - 12)); |
857 | | } |
858 | | } |
859 | | |
860 | | /* tmp / pan in log2 */ |
861 | | return QUANTISE2REAL(tmp - pan); |
862 | | } else { |
863 | | return QUANTISE2REAL(6.0 - (real_t)sbr->Q[ch][k][l]); |
864 | | } |
865 | | } |
866 | | |
867 | | static const real_t log_Qplus1_pan[31][13] = { |
868 | | { REAL_CONST(0.044383447617292), REAL_CONST(0.169768601655960), REAL_CONST(0.583090126514435), REAL_CONST(1.570089221000671), REAL_CONST(3.092446088790894), REAL_CONST(4.733354568481445), REAL_CONST(6.022367954254150), REAL_CONST(6.692092418670654), REAL_CONST(6.924463272094727), REAL_CONST(6.989034175872803), REAL_CONST(7.005646705627441), REAL_CONST(7.009829998016357), REAL_CONST(7.010877609252930) }, |
869 | | { REAL_CONST(0.022362394258380), REAL_CONST(0.087379962205887), REAL_CONST(0.320804953575134), REAL_CONST(0.988859415054321), REAL_CONST(2.252387046813965), REAL_CONST(3.786596298217773), REAL_CONST(5.044394016265869), REAL_CONST(5.705977916717529), REAL_CONST(5.936291694641113), REAL_CONST(6.000346660614014), REAL_CONST(6.016829967498779), REAL_CONST(6.020981311798096), REAL_CONST(6.022020816802979) }, |
870 | | { REAL_CONST(0.011224525049329), REAL_CONST(0.044351425021887), REAL_CONST(0.169301137328148), REAL_CONST(0.577544987201691), REAL_CONST(1.527246952056885), REAL_CONST(2.887525320053101), REAL_CONST(4.087462902069092), REAL_CONST(4.733354568481445), REAL_CONST(4.959661006927490), REAL_CONST(5.022709369659424), REAL_CONST(5.038940429687500), REAL_CONST(5.043028831481934), REAL_CONST(5.044052600860596) }, |
871 | | { REAL_CONST(0.005623178556561), REAL_CONST(0.022346137091517), REAL_CONST(0.087132595479488), REAL_CONST(0.317482173442841), REAL_CONST(0.956931233406067), REAL_CONST(2.070389270782471), REAL_CONST(3.169924974441528), REAL_CONST(3.786596298217773), REAL_CONST(4.005294322967529), REAL_CONST(4.066420555114746), REAL_CONST(4.082170009613037), REAL_CONST(4.086137294769287), REAL_CONST(4.087131500244141) }, |
872 | | { REAL_CONST(0.002814328996465), REAL_CONST(0.011216334067285), REAL_CONST(0.044224001467228), REAL_CONST(0.167456731200218), REAL_CONST(0.556393325328827), REAL_CONST(1.378511548042297), REAL_CONST(2.321928024291992), REAL_CONST(2.887525320053101), REAL_CONST(3.092446088790894), REAL_CONST(3.150059700012207), REAL_CONST(3.164926528930664), REAL_CONST(3.168673276901245), REAL_CONST(3.169611930847168) }, |
873 | | { REAL_CONST(0.001407850766554), REAL_CONST(0.005619067233056), REAL_CONST(0.022281449288130), REAL_CONST(0.086156636476517), REAL_CONST(0.304854571819305), REAL_CONST(0.847996890544891), REAL_CONST(1.584962487220764), REAL_CONST(2.070389270782471), REAL_CONST(2.252387046813965), REAL_CONST(2.304061651229858), REAL_CONST(2.317430257797241), REAL_CONST(2.320801734924316), REAL_CONST(2.321646213531494) }, |
874 | | { REAL_CONST(0.000704097095877), REAL_CONST(0.002812269143760), REAL_CONST(0.011183738708496), REAL_CONST(0.043721374124289), REAL_CONST(0.160464659333229), REAL_CONST(0.485426813364029), REAL_CONST(1.000000000000000), REAL_CONST(1.378511548042297), REAL_CONST(1.527246952056885), REAL_CONST(1.570089221000671), REAL_CONST(1.581215262413025), REAL_CONST(1.584023833274841), REAL_CONST(1.584727644920349) }, |
875 | | { REAL_CONST(0.000352177477907), REAL_CONST(0.001406819908880), REAL_CONST(0.005602621007711), REAL_CONST(0.022026389837265), REAL_CONST(0.082462236285210), REAL_CONST(0.263034462928772), REAL_CONST(0.584962487220764), REAL_CONST(0.847996890544891), REAL_CONST(0.956931233406067), REAL_CONST(0.988859415054321), REAL_CONST(0.997190535068512), REAL_CONST(0.999296069145203), REAL_CONST(0.999823868274689) }, |
876 | | { REAL_CONST(0.000176099492819), REAL_CONST(0.000703581434209), REAL_CONST(0.002804030198604), REAL_CONST(0.011055230163038), REAL_CONST(0.041820213198662), REAL_CONST(0.137503549456596), REAL_CONST(0.321928083896637), REAL_CONST(0.485426813364029), REAL_CONST(0.556393325328827), REAL_CONST(0.577544987201691), REAL_CONST(0.583090126514435), REAL_CONST(0.584493279457092), REAL_CONST(0.584845066070557) }, |
877 | | { REAL_CONST(0.000088052431238), REAL_CONST(0.000351833587047), REAL_CONST(0.001402696361765), REAL_CONST(0.005538204684854), REAL_CONST(0.021061634644866), REAL_CONST(0.070389263331890), REAL_CONST(0.169925004243851), REAL_CONST(0.263034462928772), REAL_CONST(0.304854571819305), REAL_CONST(0.317482173442841), REAL_CONST(0.320804953575134), REAL_CONST(0.321646571159363), REAL_CONST(0.321857661008835) }, |
878 | | { REAL_CONST(0.000044026888645), REAL_CONST(0.000175927518285), REAL_CONST(0.000701518612914), REAL_CONST(0.002771759871393), REAL_CONST(0.010569252073765), REAL_CONST(0.035623874515295), REAL_CONST(0.087462842464447), REAL_CONST(0.137503549456596), REAL_CONST(0.160464659333229), REAL_CONST(0.167456731200218), REAL_CONST(0.169301137328148), REAL_CONST(0.169768601655960), REAL_CONST(0.169885858893394) }, |
879 | | { REAL_CONST(0.000022013611670), REAL_CONST(0.000088052431238), REAL_CONST(0.000350801943569), REAL_CONST(0.001386545598507), REAL_CONST(0.005294219125062), REAL_CONST(0.017921976745129), REAL_CONST(0.044394120573997), REAL_CONST(0.070389263331890), REAL_CONST(0.082462236285210), REAL_CONST(0.086156636476517), REAL_CONST(0.087132595479488), REAL_CONST(0.087379962205887), REAL_CONST(0.087442122399807) }, |
880 | | { REAL_CONST(0.000011006847672), REAL_CONST(0.000044026888645), REAL_CONST(0.000175411638338), REAL_CONST(0.000693439331371), REAL_CONST(0.002649537986144), REAL_CONST(0.008988817222416), REAL_CONST(0.022367812693119), REAL_CONST(0.035623874515295), REAL_CONST(0.041820213198662), REAL_CONST(0.043721374124289), REAL_CONST(0.044224001467228), REAL_CONST(0.044351425021887), REAL_CONST(0.044383447617292) }, |
881 | | { REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000087708482170), REAL_CONST(0.000346675369656), REAL_CONST(0.001325377263129), REAL_CONST(0.004501323681325), REAL_CONST(0.011227255687118), REAL_CONST(0.017921976745129), REAL_CONST(0.021061634644866), REAL_CONST(0.022026389837265), REAL_CONST(0.022281449288130), REAL_CONST(0.022346137091517), REAL_CONST(0.022362394258380) }, |
882 | | { REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043854910473), REAL_CONST(0.000173348103999), REAL_CONST(0.000662840844598), REAL_CONST(0.002252417383716), REAL_CONST(0.005624548997730), REAL_CONST(0.008988817222416), REAL_CONST(0.010569252073765), REAL_CONST(0.011055230163038), REAL_CONST(0.011183738708496), REAL_CONST(0.011216334067285), REAL_CONST(0.011224525049329) }, |
883 | | { REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000086676649516), REAL_CONST(0.000331544462824), REAL_CONST(0.001126734190620), REAL_CONST(0.002815015614033), REAL_CONST(0.004501323681325), REAL_CONST(0.005294219125062), REAL_CONST(0.005538204684854), REAL_CONST(0.005602621007711), REAL_CONST(0.005619067233056), REAL_CONST(0.005623178556561) }, |
884 | | { REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043338975956), REAL_CONST(0.000165781748365), REAL_CONST(0.000563477107789), REAL_CONST(0.001408194424585), REAL_CONST(0.002252417383716), REAL_CONST(0.002649537986144), REAL_CONST(0.002771759871393), REAL_CONST(0.002804030198604), REAL_CONST(0.002812269143760), REAL_CONST(0.002814328996465) }, |
885 | | { REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000021669651687), REAL_CONST(0.000082893253420), REAL_CONST(0.000281680084299), REAL_CONST(0.000704268983100), REAL_CONST(0.001126734190620), REAL_CONST(0.001325377263129), REAL_CONST(0.001386545598507), REAL_CONST(0.001402696361765), REAL_CONST(0.001406819908880), REAL_CONST(0.001407850766554) }, |
886 | | { REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010834866771), REAL_CONST(0.000041447223339), REAL_CONST(0.000140846910654), REAL_CONST(0.000352177477907), REAL_CONST(0.000563477107789), REAL_CONST(0.000662840844598), REAL_CONST(0.000693439331371), REAL_CONST(0.000701518612914), REAL_CONST(0.000703581434209), REAL_CONST(0.000704097095877) }, |
887 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000020637769921), REAL_CONST(0.000070511166996), REAL_CONST(0.000176099492819), REAL_CONST(0.000281680084299), REAL_CONST(0.000331544462824), REAL_CONST(0.000346675369656), REAL_CONST(0.000350801943569), REAL_CONST(0.000351833587047), REAL_CONST(0.000352177477907) }, |
888 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010318922250), REAL_CONST(0.000035256012779), REAL_CONST(0.000088052431238), REAL_CONST(0.000140846910654), REAL_CONST(0.000165781748365), REAL_CONST(0.000173348103999), REAL_CONST(0.000175411638338), REAL_CONST(0.000175927518285), REAL_CONST(0.000176099492819) }, |
889 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005159470220), REAL_CONST(0.000017542124624), REAL_CONST(0.000044026888645), REAL_CONST(0.000070511166996), REAL_CONST(0.000082893253420), REAL_CONST(0.000086676649516), REAL_CONST(0.000087708482170), REAL_CONST(0.000088052431238), REAL_CONST(0.000088052431238) }, |
890 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002579737384), REAL_CONST(0.000008771088687), REAL_CONST(0.000022013611670), REAL_CONST(0.000035256012779), REAL_CONST(0.000041447223339), REAL_CONST(0.000043338975956), REAL_CONST(0.000043854910473), REAL_CONST(0.000044026888645), REAL_CONST(0.000044026888645) }, |
891 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000004471542070), REAL_CONST(0.000011006847672), REAL_CONST(0.000017542124624), REAL_CONST(0.000020637769921), REAL_CONST(0.000021669651687), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670) }, |
892 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002235772627), REAL_CONST(0.000005503434295), REAL_CONST(0.000008771088687), REAL_CONST(0.000010318922250), REAL_CONST(0.000010834866771), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672) }, |
893 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001031895522), REAL_CONST(0.000002751719876), REAL_CONST(0.000004471542070), REAL_CONST(0.000005159470220), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295) }, |
894 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000515947875), REAL_CONST(0.000001375860506), REAL_CONST(0.000002235772627), REAL_CONST(0.000002579737384), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876) }, |
895 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000000687930424), REAL_CONST(0.000001031895522), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506) }, |
896 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000515947875), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424) }, |
897 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269) }, |
898 | | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634) } |
899 | | }; |
900 | | |
901 | | static const real_t log_Qplus1[31] = { |
902 | | REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339), |
903 | | REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156), |
904 | | REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), |
905 | | REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453), |
906 | | REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), |
907 | | REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), |
908 | | REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122), |
909 | | REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667), |
910 | | REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551), |
911 | | REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641), |
912 | | REAL_CONST(0.000000000000000) |
913 | | }; |
914 | | |
915 | | static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) |
916 | | { |
917 | | /* check for coupled energy/noise data */ |
918 | | if (sbr->bs_coupling == 1) |
919 | | { |
920 | | if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) && |
921 | | (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24)) |
922 | | { |
923 | | if (ch == 0) |
924 | | { |
925 | | return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1]); |
926 | | } else { |
927 | | return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)]); |
928 | | } |
929 | | } else { |
930 | | return 0; |
931 | | } |
932 | | } else { |
933 | | if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30) |
934 | | { |
935 | | return QUANTISE2REAL(log_Qplus1[sbr->Q[ch][k][l]]); |
936 | | } else { |
937 | | return 0; |
938 | | } |
939 | | } |
940 | | } |
941 | | |
942 | | static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) |
943 | | { |
944 | | /* log2 values of limiter gains */ |
945 | | static real_t limGain[] = { -1.0, 0.0, 1.0, 33.219 }; |
946 | | uint8_t m, l, k; |
947 | | |
948 | | uint8_t current_t_noise_band = 0; |
949 | | uint8_t S_mapped; |
950 | | |
951 | | ALIGN real_t Q_M_lim[MAX_M]; |
952 | | ALIGN real_t G_lim[MAX_M]; |
953 | | ALIGN real_t G_boost; |
954 | | ALIGN real_t S_M[MAX_M]; |
955 | | |
956 | | |
957 | | for (l = 0; l < sbr->L_E[ch]; l++) |
958 | | { |
959 | | uint8_t current_f_noise_band = 0; |
960 | | uint8_t current_res_band = 0; |
961 | | uint8_t current_res_band2 = 0; |
962 | | uint8_t current_hi_res_band = 0; |
963 | | |
964 | | real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; |
965 | | |
966 | | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); |
967 | | |
968 | | if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) |
969 | | { |
970 | | current_t_noise_band++; |
971 | | } |
972 | | |
973 | | for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) |
974 | | { |
975 | | real_t Q_M = 0; |
976 | | real_t G_max; |
977 | | real_t den = 0; |
978 | | real_t acc1 = 0; |
979 | | real_t acc2 = 0; |
980 | | uint8_t current_res_band_size = 0; |
981 | | uint8_t Q_M_size = 0; |
982 | | |
983 | | uint8_t ml1, ml2; |
984 | | |
985 | | /* bounds of current limiter bands */ |
986 | | ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; |
987 | | ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; |
988 | | |
989 | | if (ml1 > MAX_M) |
990 | | ml1 = MAX_M; |
991 | | |
992 | | if (ml2 > MAX_M) |
993 | | ml2 = MAX_M; |
994 | | |
995 | | |
996 | | /* calculate the accumulated E_orig and E_curr over the limiter band */ |
997 | | for (m = ml1; m < ml2; m++) |
998 | | { |
999 | | if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) |
1000 | | { |
1001 | | current_res_band_size++; |
1002 | | } else { |
1003 | | acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch))); |
1004 | | |
1005 | | current_res_band++; |
1006 | | current_res_band_size = 1; |
1007 | | } |
1008 | | |
1009 | | acc2 += QUANTISE2INT(sbr->E_curr[ch][m][l]/1024.0); |
1010 | | } |
1011 | | acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch))); |
1012 | | |
1013 | | acc1 = QUANTISE2REAL( log2(EPS + acc1) ); |
1014 | | |
1015 | | |
1016 | | /* calculate the maximum gain */ |
1017 | | /* ratio of the energy of the original signal and the energy |
1018 | | * of the HF generated signal |
1019 | | */ |
1020 | | G_max = acc1 - QUANTISE2REAL(log2(EPS + acc2)) + QUANTISE2REAL(limGain[sbr->bs_limiter_gains]); |
1021 | | G_max = min(G_max, QUANTISE2REAL(limGain[3])); |
1022 | | |
1023 | | |
1024 | | for (m = ml1; m < ml2; m++) |
1025 | | { |
1026 | | real_t G; |
1027 | | real_t E_curr, E_orig; |
1028 | | real_t Q_orig, Q_orig_plus1; |
1029 | | uint8_t S_index_mapped; |
1030 | | |
1031 | | |
1032 | | /* check if m is on a noise band border */ |
1033 | | if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) |
1034 | | { |
1035 | | /* step to next noise band */ |
1036 | | current_f_noise_band++; |
1037 | | } |
1038 | | |
1039 | | |
1040 | | /* check if m is on a resolution band border */ |
1041 | | if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) |
1042 | | { |
1043 | | /* accumulate a whole range of equal Q_Ms */ |
1044 | | if (Q_M_size > 0) |
1045 | | den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M)); |
1046 | | Q_M_size = 0; |
1047 | | |
1048 | | /* step to next resolution band */ |
1049 | | current_res_band2++; |
1050 | | |
1051 | | /* if we move to a new resolution band, we should check if we are |
1052 | | * going to add a sinusoid in this band |
1053 | | */ |
1054 | | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); |
1055 | | } |
1056 | | |
1057 | | |
1058 | | /* check if m is on a HI_RES band border */ |
1059 | | if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) |
1060 | | { |
1061 | | /* step to next HI_RES band */ |
1062 | | current_hi_res_band++; |
1063 | | } |
1064 | | |
1065 | | |
1066 | | /* find S_index_mapped |
1067 | | * S_index_mapped can only be 1 for the m in the middle of the |
1068 | | * current HI_RES band |
1069 | | */ |
1070 | | S_index_mapped = 0; |
1071 | | if ((l >= sbr->l_A[ch]) || |
1072 | | (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) |
1073 | | { |
1074 | | /* find the middle subband of the HI_RES frequency band */ |
1075 | | if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) |
1076 | | S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; |
1077 | | } |
1078 | | |
1079 | | |
1080 | | /* find bitstream parameters */ |
1081 | | if (sbr->E_curr[ch][m][l] == 0) |
1082 | | E_curr = LOG2_MIN_INF; |
1083 | | else |
1084 | | E_curr = -10 + log2(sbr->E_curr[ch][m][l]); |
1085 | | E_orig = -10 + find_log2_E(sbr, current_res_band2, l, ch); |
1086 | | |
1087 | | Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch); |
1088 | | Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch); |
1089 | | |
1090 | | |
1091 | | /* Q_M only depends on E_orig and Q_div2: |
1092 | | * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on |
1093 | | * a change of current res band (HI or LO) |
1094 | | */ |
1095 | | Q_M = E_orig + Q_orig - Q_orig_plus1; |
1096 | | |
1097 | | |
1098 | | /* S_M only depends on E_orig, Q_div and S_index_mapped: |
1099 | | * S_index_mapped can only be non-zero once per HI_RES band |
1100 | | */ |
1101 | | if (S_index_mapped == 0) |
1102 | | { |
1103 | | S_M[m] = LOG2_MIN_INF; /* -inf */ |
1104 | | } else { |
1105 | | S_M[m] = E_orig - Q_orig_plus1; |
1106 | | |
1107 | | /* accumulate sinusoid part of the total energy */ |
1108 | | den += pow2(S_M[m]); |
1109 | | } |
1110 | | |
1111 | | |
1112 | | /* calculate gain */ |
1113 | | /* ratio of the energy of the original signal and the energy |
1114 | | * of the HF generated signal |
1115 | | */ |
1116 | | /* E_curr here is officially E_curr+1 so the log2() of that can never be < 0 */ |
1117 | | /* scaled by -10 */ |
1118 | | G = E_orig - max(-10, E_curr); |
1119 | | if ((S_mapped == 0) && (delta == 1)) |
1120 | | { |
1121 | | /* G = G * 1/(1+Q) */ |
1122 | | G -= Q_orig_plus1; |
1123 | | } else if (S_mapped == 1) { |
1124 | | /* G = G * Q/(1+Q) */ |
1125 | | G += Q_orig - Q_orig_plus1; |
1126 | | } |
1127 | | |
1128 | | |
1129 | | /* limit the additional noise energy level */ |
1130 | | /* and apply the limiter */ |
1131 | | if (G_max > G) |
1132 | | { |
1133 | | Q_M_lim[m] = QUANTISE2REAL(Q_M); |
1134 | | G_lim[m] = QUANTISE2REAL(G); |
1135 | | |
1136 | | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) |
1137 | | { |
1138 | | Q_M_size++; |
1139 | | } |
1140 | | } else { |
1141 | | /* G > G_max */ |
1142 | | Q_M_lim[m] = QUANTISE2REAL(Q_M) + G_max - QUANTISE2REAL(G); |
1143 | | G_lim[m] = G_max; |
1144 | | |
1145 | | /* accumulate limited Q_M */ |
1146 | | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) |
1147 | | { |
1148 | | den += QUANTISE2INT(pow2(Q_M_lim[m])); |
1149 | | } |
1150 | | } |
1151 | | |
1152 | | |
1153 | | /* accumulate the total energy */ |
1154 | | /* E_curr changes for every m so we do need to accumulate every m */ |
1155 | | den += QUANTISE2INT(pow2(E_curr + G_lim[m])); |
1156 | | } |
1157 | | |
1158 | | /* accumulate last range of equal Q_Ms */ |
1159 | | if (Q_M_size > 0) |
1160 | | { |
1161 | | den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M)); |
1162 | | } |
1163 | | |
1164 | | |
1165 | | /* calculate the final gain */ |
1166 | | /* G_boost: [0..2.51188643] */ |
1167 | | G_boost = acc1 - QUANTISE2REAL(log2(den + EPS)); |
1168 | | G_boost = min(G_boost, QUANTISE2REAL(1.328771237) /* log2(1.584893192 ^ 2) */); |
1169 | | |
1170 | | |
1171 | | for (m = ml1; m < ml2; m++) |
1172 | | { |
1173 | | /* apply compensation to gain, noise floor sf's and sinusoid levels */ |
1174 | | #ifndef SBR_LOW_POWER |
1175 | | adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2((G_lim[m] + G_boost) / 2.0)); |
1176 | | #else |
1177 | | /* sqrt() will be done after the aliasing reduction to save a |
1178 | | * few multiplies |
1179 | | */ |
1180 | | adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2(G_lim[m] + G_boost)); |
1181 | | #endif |
1182 | | adj->Q_M_lim_boost[l][m] = QUANTISE2REAL(pow2((Q_M_lim[m] + 10 + G_boost) / 2.0)); |
1183 | | |
1184 | | if (S_M[m] != LOG2_MIN_INF) |
1185 | | { |
1186 | | adj->S_M_boost[l][m] = QUANTISE2REAL(pow2((S_M[m] + 10 + G_boost) / 2.0)); |
1187 | | } else { |
1188 | | adj->S_M_boost[l][m] = 0; |
1189 | | } |
1190 | | } |
1191 | | } |
1192 | | } |
1193 | | } |
1194 | | |
1195 | | #else |
1196 | | |
1197 | | static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) |
1198 | 14.1k | { |
1199 | 14.1k | static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 }; |
1200 | 14.1k | uint8_t m, l, k; |
1201 | | |
1202 | 14.1k | uint8_t current_t_noise_band = 0; |
1203 | 14.1k | uint8_t S_mapped; |
1204 | | |
1205 | 14.1k | ALIGN real_t Q_M_lim[MAX_M]; |
1206 | 14.1k | ALIGN real_t G_lim[MAX_M]; |
1207 | 14.1k | ALIGN real_t G_boost; |
1208 | 14.1k | ALIGN real_t S_M[MAX_M]; |
1209 | | |
1210 | 38.0k | for (l = 0; l < sbr->L_E[ch]; l++) |
1211 | 23.9k | { |
1212 | 23.9k | uint8_t current_f_noise_band = 0; |
1213 | 23.9k | uint8_t current_res_band = 0; |
1214 | 23.9k | uint8_t current_res_band2 = 0; |
1215 | 23.9k | uint8_t current_hi_res_band = 0; |
1216 | | |
1217 | 23.9k | real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; |
1218 | | |
1219 | 23.9k | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); |
1220 | | |
1221 | 23.9k | if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) |
1222 | 4.48k | { |
1223 | 4.48k | current_t_noise_band++; |
1224 | 4.48k | } |
1225 | | |
1226 | 69.9k | for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) |
1227 | 46.0k | { |
1228 | 46.0k | real_t G_max; |
1229 | 46.0k | real_t den = 0; |
1230 | 46.0k | real_t acc1 = 0; |
1231 | 46.0k | real_t acc2 = 0; |
1232 | | |
1233 | 46.0k | uint8_t ml1, ml2; |
1234 | | |
1235 | 46.0k | ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; |
1236 | 46.0k | ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; |
1237 | | |
1238 | 46.0k | if (ml1 > MAX_M) |
1239 | 0 | ml1 = MAX_M; |
1240 | | |
1241 | 46.0k | if (ml2 > MAX_M) |
1242 | 0 | ml2 = MAX_M; |
1243 | | |
1244 | | |
1245 | | /* calculate the accumulated E_orig and E_curr over the limiter band */ |
1246 | 334k | for (m = ml1; m < ml2; m++) |
1247 | 288k | { |
1248 | 288k | if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) |
1249 | 79.6k | { |
1250 | 79.6k | current_res_band++; |
1251 | 79.6k | } |
1252 | 288k | acc1 += sbr->E_orig[ch][current_res_band][l]; |
1253 | 288k | acc2 += sbr->E_curr[ch][m][l]; |
1254 | 288k | } |
1255 | | |
1256 | | |
1257 | | /* calculate the maximum gain */ |
1258 | | /* ratio of the energy of the original signal and the energy |
1259 | | * of the HF generated signal |
1260 | | */ |
1261 | 46.0k | G_max = ((EPS + acc1) / (EPS + acc2)) * limGain[sbr->bs_limiter_gains]; |
1262 | 46.0k | G_max = min(G_max, 1e10); |
1263 | | |
1264 | | |
1265 | 334k | for (m = ml1; m < ml2; m++) |
1266 | 288k | { |
1267 | 288k | real_t Q_M, G; |
1268 | 288k | real_t Q_div, Q_div2; |
1269 | 288k | uint8_t S_index_mapped; |
1270 | | |
1271 | | |
1272 | | /* check if m is on a noise band border */ |
1273 | 288k | if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) |
1274 | 17.1k | { |
1275 | | /* step to next noise band */ |
1276 | 17.1k | current_f_noise_band++; |
1277 | 17.1k | } |
1278 | | |
1279 | | |
1280 | | /* check if m is on a resolution band border */ |
1281 | 288k | if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) |
1282 | 79.6k | { |
1283 | | /* step to next resolution band */ |
1284 | 79.6k | current_res_band2++; |
1285 | | |
1286 | | /* if we move to a new resolution band, we should check if we are |
1287 | | * going to add a sinusoid in this band |
1288 | | */ |
1289 | 79.6k | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); |
1290 | 79.6k | } |
1291 | | |
1292 | | |
1293 | | /* check if m is on a HI_RES band border */ |
1294 | 288k | if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) |
1295 | 135k | { |
1296 | | /* step to next HI_RES band */ |
1297 | 135k | current_hi_res_band++; |
1298 | 135k | } |
1299 | | |
1300 | | |
1301 | | /* find S_index_mapped |
1302 | | * S_index_mapped can only be 1 for the m in the middle of the |
1303 | | * current HI_RES band |
1304 | | */ |
1305 | 288k | S_index_mapped = 0; |
1306 | 288k | if ((l >= sbr->l_A[ch]) || |
1307 | 288k | (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) |
1308 | 202k | { |
1309 | | /* find the middle subband of the HI_RES frequency band */ |
1310 | 202k | if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) |
1311 | 107k | S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; |
1312 | 202k | } |
1313 | | |
1314 | | |
1315 | | /* Q_div: [0..1] (1/(1+Q_mapped)) */ |
1316 | 288k | Q_div = sbr->Q_div[ch][current_f_noise_band][current_t_noise_band]; |
1317 | | |
1318 | | |
1319 | | /* Q_div2: [0..1] (Q_mapped/(1+Q_mapped)) */ |
1320 | 288k | Q_div2 = sbr->Q_div2[ch][current_f_noise_band][current_t_noise_band]; |
1321 | | |
1322 | | |
1323 | | /* Q_M only depends on E_orig and Q_div2: |
1324 | | * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on |
1325 | | * a change of current noise band |
1326 | | */ |
1327 | 288k | Q_M = sbr->E_orig[ch][current_res_band2][l] * Q_div2; |
1328 | | |
1329 | | |
1330 | | /* S_M only depends on E_orig, Q_div and S_index_mapped: |
1331 | | * S_index_mapped can only be non-zero once per HI_RES band |
1332 | | */ |
1333 | 288k | if (S_index_mapped == 0) |
1334 | 276k | { |
1335 | 276k | S_M[m] = 0; |
1336 | 276k | } else { |
1337 | 12.0k | S_M[m] = sbr->E_orig[ch][current_res_band2][l] * Q_div; |
1338 | | |
1339 | | /* accumulate sinusoid part of the total energy */ |
1340 | 12.0k | den += S_M[m]; |
1341 | 12.0k | } |
1342 | | |
1343 | | |
1344 | | /* calculate gain */ |
1345 | | /* ratio of the energy of the original signal and the energy |
1346 | | * of the HF generated signal |
1347 | | */ |
1348 | 288k | G = sbr->E_orig[ch][current_res_band2][l] / (1.0 + sbr->E_curr[ch][m][l]); |
1349 | 288k | if ((S_mapped == 0) && (delta == 1)) |
1350 | 240k | G *= Q_div; |
1351 | 47.9k | else if (S_mapped == 1) |
1352 | 27.4k | G *= Q_div2; |
1353 | | |
1354 | | |
1355 | | /* limit the additional noise energy level */ |
1356 | | /* and apply the limiter */ |
1357 | 288k | if (G <= G_max) |
1358 | 252k | { |
1359 | 252k | Q_M_lim[m] = Q_M; |
1360 | 252k | G_lim[m] = G; |
1361 | 252k | } else { |
1362 | 35.7k | Q_M_lim[m] = Q_M * G_max / G; |
1363 | 35.7k | G_lim[m] = G_max; |
1364 | 35.7k | } |
1365 | | |
1366 | | |
1367 | | /* accumulate the total energy */ |
1368 | 288k | den += sbr->E_curr[ch][m][l] * G_lim[m]; |
1369 | 288k | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) |
1370 | 259k | den += Q_M_lim[m]; |
1371 | 288k | } |
1372 | | |
1373 | | /* G_boost: [0..2.51188643] */ |
1374 | 46.0k | G_boost = (acc1 + EPS) / (den + EPS); |
1375 | 46.0k | G_boost = min(G_boost, 2.51188643 /* 1.584893192 ^ 2 */); |
1376 | | |
1377 | 334k | for (m = ml1; m < ml2; m++) |
1378 | 288k | { |
1379 | | /* apply compensation to gain, noise floor sf's and sinusoid levels */ |
1380 | 288k | #ifndef SBR_LOW_POWER |
1381 | 288k | adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost); |
1382 | | #else |
1383 | | /* sqrt() will be done after the aliasing reduction to save a |
1384 | | * few multiplies |
1385 | | */ |
1386 | | adj->G_lim_boost[l][m] = G_lim[m] * G_boost; |
1387 | | #endif |
1388 | 288k | adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost); |
1389 | | |
1390 | 288k | if (S_M[m] != 0) |
1391 | 7.67k | { |
1392 | 7.67k | adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost); |
1393 | 280k | } else { |
1394 | 280k | adj->S_M_boost[l][m] = 0; |
1395 | 280k | } |
1396 | 288k | } |
1397 | 46.0k | } |
1398 | 23.9k | } |
1399 | 14.1k | } |
1400 | | #endif // log2_test |
1401 | | |
1402 | | #endif |
1403 | | |
1404 | | #ifdef SBR_LOW_POWER |
1405 | | static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) |
1406 | | { |
1407 | | uint8_t l, k, i; |
1408 | | uint8_t grouping; |
1409 | | uint8_t S_mapped; |
1410 | | |
1411 | | for (l = 0; l < sbr->L_E[ch]; l++) |
1412 | | { |
1413 | | uint8_t current_res_band = 0; |
1414 | | i = 0; |
1415 | | grouping = 0; |
1416 | | |
1417 | | S_mapped = get_S_mapped(sbr, ch, l, current_res_band); |
1418 | | |
1419 | | for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++) |
1420 | | { |
1421 | | if (k == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) |
1422 | | { |
1423 | | /* step to next resolution band */ |
1424 | | current_res_band++; |
1425 | | |
1426 | | S_mapped = get_S_mapped(sbr, ch, l, current_res_band); |
1427 | | } |
1428 | | |
1429 | | if (deg[k + 1] && S_mapped == 0) |
1430 | | { |
1431 | | if (grouping == 0) |
1432 | | { |
1433 | | sbr->f_group[l][i] = k; |
1434 | | grouping = 1; |
1435 | | i++; |
1436 | | } |
1437 | | } else { |
1438 | | if (grouping) |
1439 | | { |
1440 | | if (S_mapped) |
1441 | | { |
1442 | | sbr->f_group[l][i] = k; |
1443 | | } else { |
1444 | | sbr->f_group[l][i] = k + 1; |
1445 | | } |
1446 | | grouping = 0; |
1447 | | i++; |
1448 | | } |
1449 | | } |
1450 | | } |
1451 | | |
1452 | | if (grouping) |
1453 | | { |
1454 | | sbr->f_group[l][i] = sbr->kx + sbr->M; |
1455 | | i++; |
1456 | | } |
1457 | | |
1458 | | sbr->N_G[l] = (uint8_t)(i >> 1); |
1459 | | } |
1460 | | } |
1461 | | |
1462 | | static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) |
1463 | | { |
1464 | | uint8_t l, k, m; |
1465 | | real_t E_total, E_total_est, G_target, acc; |
1466 | | |
1467 | | for (l = 0; l < sbr->L_E[ch]; l++) |
1468 | | { |
1469 | | for (k = 0; k < sbr->N_G[l]; k++) |
1470 | | { |
1471 | | E_total_est = E_total = 0; |
1472 | | |
1473 | | for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++) |
1474 | | { |
1475 | | /* E_curr: integer */ |
1476 | | /* G_lim_boost: fixed point */ |
1477 | | /* E_total_est: integer */ |
1478 | | /* E_total: integer */ |
1479 | | E_total_est += sbr->E_curr[ch][m-sbr->kx][l]; |
1480 | | #ifdef FIXED_POINT |
1481 | | E_total += MUL_Q2(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]); |
1482 | | #else |
1483 | | E_total += sbr->E_curr[ch][m-sbr->kx][l] * adj->G_lim_boost[l][m-sbr->kx]; |
1484 | | #endif |
1485 | | } |
1486 | | |
1487 | | /* G_target: fixed point */ |
1488 | | if ((E_total_est + EPS) == 0) |
1489 | | { |
1490 | | G_target = 0; |
1491 | | } else { |
1492 | | #ifdef FIXED_POINT |
1493 | | G_target = (((int64_t)(E_total))<<Q2_BITS)/(E_total_est + EPS); |
1494 | | #else |
1495 | | G_target = E_total / (E_total_est + EPS); |
1496 | | #endif |
1497 | | } |
1498 | | acc = 0; |
1499 | | |
1500 | | for (m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) |
1501 | | { |
1502 | | real_t alpha; |
1503 | | |
1504 | | /* alpha: (COEF) fixed point */ |
1505 | | if (m < sbr->kx + sbr->M - 1) |
1506 | | { |
1507 | | alpha = max(deg[m], deg[m + 1]); |
1508 | | } else { |
1509 | | alpha = deg[m]; |
1510 | | } |
1511 | | |
1512 | | adj->G_lim_boost[l][m-sbr->kx] = MUL_C(alpha, G_target) + |
1513 | | MUL_C((COEF_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]); |
1514 | | |
1515 | | /* acc: integer */ |
1516 | | #ifdef FIXED_POINT |
1517 | | acc += MUL_Q2(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]); |
1518 | | #else |
1519 | | acc += adj->G_lim_boost[l][m-sbr->kx] * sbr->E_curr[ch][m-sbr->kx][l]; |
1520 | | #endif |
1521 | | } |
1522 | | |
1523 | | /* acc: fixed point */ |
1524 | | if (acc + EPS == 0) |
1525 | | { |
1526 | | acc = 0; |
1527 | | } else { |
1528 | | #ifdef FIXED_POINT |
1529 | | acc = (((int64_t)(E_total))<<Q2_BITS)/(acc + EPS); |
1530 | | #else |
1531 | | acc = E_total / (acc + EPS); |
1532 | | #endif |
1533 | | } |
1534 | | for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) |
1535 | | { |
1536 | | #ifdef FIXED_POINT |
1537 | | adj->G_lim_boost[l][m-sbr->kx] = MUL_Q2(acc, adj->G_lim_boost[l][m-sbr->kx]); |
1538 | | #else |
1539 | | adj->G_lim_boost[l][m-sbr->kx] = acc * adj->G_lim_boost[l][m-sbr->kx]; |
1540 | | #endif |
1541 | | } |
1542 | | } |
1543 | | } |
1544 | | |
1545 | | for (l = 0; l < sbr->L_E[ch]; l++) |
1546 | | { |
1547 | | for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) |
1548 | | { |
1549 | | for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; |
1550 | | m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) |
1551 | | { |
1552 | | #ifdef FIXED_POINT |
1553 | | adj->G_lim_boost[l][m] = SBR_SQRT_Q2(adj->G_lim_boost[l][m]); |
1554 | | #else |
1555 | | adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]); |
1556 | | #endif |
1557 | | } |
1558 | | } |
1559 | | } |
1560 | | } |
1561 | | #endif |
1562 | | |
1563 | | static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, |
1564 | | qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) |
1565 | 23.8k | { |
1566 | 23.8k | static real_t h_smooth[] = { |
1567 | 23.8k | FRAC_CONST(0.03183050093751), FRAC_CONST(0.11516383427084), |
1568 | 23.8k | FRAC_CONST(0.21816949906249), FRAC_CONST(0.30150283239582), |
1569 | 23.8k | FRAC_CONST(0.33333333333333) |
1570 | 23.8k | }; |
1571 | 23.8k | static int8_t phi_re[] = { 1, 0, -1, 0 }; |
1572 | 23.8k | static int8_t phi_im[] = { 0, 1, 0, -1 }; |
1573 | | |
1574 | 23.8k | uint8_t m, l, i, n; |
1575 | 23.8k | uint16_t fIndexNoise = 0; |
1576 | 23.8k | uint8_t fIndexSine = 0; |
1577 | 23.8k | uint8_t assembly_reset = 0; |
1578 | | |
1579 | 23.8k | real_t G_filt, Q_filt; |
1580 | | |
1581 | 23.8k | uint8_t h_SL; |
1582 | | |
1583 | | |
1584 | 23.8k | if (sbr->Reset == 1) |
1585 | 22.9k | { |
1586 | 22.9k | assembly_reset = 1; |
1587 | 22.9k | fIndexNoise = 0; |
1588 | 22.9k | } else { |
1589 | 833 | fIndexNoise = sbr->index_noise_prev[ch]; |
1590 | 833 | } |
1591 | 23.8k | fIndexSine = sbr->psi_is_prev[ch]; |
1592 | | |
1593 | | |
1594 | 64.3k | for (l = 0; l < sbr->L_E[ch]; l++) |
1595 | 40.5k | { |
1596 | 40.5k | uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0; |
1597 | | |
1598 | | #ifdef SBR_LOW_POWER |
1599 | | h_SL = 0; |
1600 | | #else |
1601 | 40.5k | h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4; |
1602 | 40.5k | h_SL = (no_noise ? 0 : h_SL); |
1603 | 40.5k | #endif |
1604 | | |
1605 | 40.5k | if (assembly_reset) |
1606 | 22.9k | { |
1607 | 114k | for (n = 0; n < 4; n++) |
1608 | 91.6k | { |
1609 | 91.6k | memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); |
1610 | 91.6k | memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); |
1611 | 91.6k | } |
1612 | | /* reset ringbuffer index */ |
1613 | 22.9k | sbr->GQ_ringbuf_index[ch] = 4; |
1614 | 22.9k | assembly_reset = 0; |
1615 | 22.9k | } |
1616 | | |
1617 | 783k | for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++) |
1618 | 743k | { |
1619 | | #ifdef SBR_LOW_POWER |
1620 | | uint8_t i_min1, i_plus1; |
1621 | | uint8_t sinusoids = 0; |
1622 | | #endif |
1623 | | |
1624 | | /* load new values into ringbuffer */ |
1625 | 743k | memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); |
1626 | 743k | memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); |
1627 | | |
1628 | 10.9M | for (m = 0; m < sbr->M; m++) |
1629 | 10.2M | { |
1630 | 10.2M | qmf_t psi; |
1631 | | |
1632 | 10.2M | G_filt = 0; |
1633 | 10.2M | Q_filt = 0; |
1634 | | |
1635 | 10.2M | #ifndef SBR_LOW_POWER |
1636 | 10.2M | if (h_SL != 0) |
1637 | 3.34M | { |
1638 | 3.34M | uint8_t ri = sbr->GQ_ringbuf_index[ch]; |
1639 | 20.0M | for (n = 0; n <= 4; n++) |
1640 | 16.7M | { |
1641 | 16.7M | real_t curr_h_smooth = h_smooth[n]; |
1642 | 16.7M | ri++; |
1643 | 16.7M | if (ri >= 5) |
1644 | 3.34M | ri -= 5; |
1645 | 16.7M | G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], curr_h_smooth); |
1646 | 16.7M | Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], curr_h_smooth); |
1647 | 16.7M | } |
1648 | 6.86M | } else { |
1649 | 6.86M | #endif |
1650 | 6.86M | G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; |
1651 | 6.86M | Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; |
1652 | 6.86M | #ifndef SBR_LOW_POWER |
1653 | 6.86M | } |
1654 | 10.2M | #endif |
1655 | 10.2M | if (adj->S_M_boost[l][m] != 0 || no_noise) |
1656 | 1.01M | Q_filt = 0; |
1657 | | |
1658 | | /* add noise to the output */ |
1659 | 10.2M | fIndexNoise = (fIndexNoise + 1) & 511; |
1660 | | |
1661 | | /* the smoothed gain values are applied to Xsbr */ |
1662 | | /* V is defined, not calculated */ |
1663 | | //QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) |
1664 | | // + MUL_F(Q_filt, RE(V[fIndexNoise])); |
1665 | 10.2M | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) |
1666 | 10.2M | + MUL_F(Q_filt, RE(V[fIndexNoise])); |
1667 | 10.2M | if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42) |
1668 | 10.5k | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320; |
1669 | 10.2M | #ifndef SBR_LOW_POWER |
1670 | | //QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) |
1671 | | // + MUL_F(Q_filt, IM(V[fIndexNoise])); |
1672 | 10.2M | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) |
1673 | 10.2M | + MUL_F(Q_filt, IM(V[fIndexNoise])); |
1674 | 10.2M | #endif |
1675 | | |
1676 | 10.2M | { |
1677 | 10.2M | int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1); |
1678 | 10.2M | QMF_RE(psi) = adj->S_M_boost[l][m] * phi_re[fIndexSine]; |
1679 | 10.2M | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi); |
1680 | | |
1681 | 10.2M | #ifndef SBR_LOW_POWER |
1682 | 10.2M | QMF_IM(psi) = rev * adj->S_M_boost[l][m] * phi_im[fIndexSine]; |
1683 | 10.2M | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi); |
1684 | | #else |
1685 | | |
1686 | | i_min1 = (fIndexSine - 1) & 3; |
1687 | | i_plus1 = (fIndexSine + 1) & 3; |
1688 | | |
1689 | | if ((m == 0) && (phi_re[i_plus1] != 0)) |
1690 | | { |
1691 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) += |
1692 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][0], FRAC_CONST(0.00815))); |
1693 | | if (sbr->M != 0) |
1694 | | { |
1695 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= |
1696 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][1], FRAC_CONST(0.00815))); |
1697 | | } |
1698 | | } |
1699 | | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) |
1700 | | { |
1701 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= |
1702 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); |
1703 | | } |
1704 | | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0)) |
1705 | | { |
1706 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= |
1707 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][m + 1], FRAC_CONST(0.00815))); |
1708 | | } |
1709 | | if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) |
1710 | | { |
1711 | | if (m > 0) |
1712 | | { |
1713 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= |
1714 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); |
1715 | | } |
1716 | | if (m + sbr->kx < 64) |
1717 | | { |
1718 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) += |
1719 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m], FRAC_CONST(0.00815))); |
1720 | | } |
1721 | | } |
1722 | | |
1723 | | if (adj->S_M_boost[l][m] != 0) |
1724 | | sinusoids++; |
1725 | | #endif |
1726 | 10.2M | } |
1727 | 10.2M | } |
1728 | | |
1729 | 743k | fIndexSine = (fIndexSine + 1) & 3; |
1730 | | |
1731 | | /* update the ringbuffer index used for filtering G and Q with h_smooth */ |
1732 | 743k | sbr->GQ_ringbuf_index[ch]++; |
1733 | 743k | if (sbr->GQ_ringbuf_index[ch] >= 5) |
1734 | 159k | sbr->GQ_ringbuf_index[ch] = 0; |
1735 | 743k | } |
1736 | 40.5k | } |
1737 | | |
1738 | 23.8k | sbr->index_noise_prev[ch] = fIndexNoise; |
1739 | 23.8k | sbr->psi_is_prev[ch] = fIndexSine; |
1740 | 23.8k | } Line | Count | Source | 1565 | 9.63k | { | 1566 | 9.63k | static real_t h_smooth[] = { | 1567 | 9.63k | FRAC_CONST(0.03183050093751), FRAC_CONST(0.11516383427084), | 1568 | 9.63k | FRAC_CONST(0.21816949906249), FRAC_CONST(0.30150283239582), | 1569 | 9.63k | FRAC_CONST(0.33333333333333) | 1570 | 9.63k | }; | 1571 | 9.63k | static int8_t phi_re[] = { 1, 0, -1, 0 }; | 1572 | 9.63k | static int8_t phi_im[] = { 0, 1, 0, -1 }; | 1573 | | | 1574 | 9.63k | uint8_t m, l, i, n; | 1575 | 9.63k | uint16_t fIndexNoise = 0; | 1576 | 9.63k | uint8_t fIndexSine = 0; | 1577 | 9.63k | uint8_t assembly_reset = 0; | 1578 | | | 1579 | 9.63k | real_t G_filt, Q_filt; | 1580 | | | 1581 | 9.63k | uint8_t h_SL; | 1582 | | | 1583 | | | 1584 | 9.63k | if (sbr->Reset == 1) | 1585 | 9.32k | { | 1586 | 9.32k | assembly_reset = 1; | 1587 | 9.32k | fIndexNoise = 0; | 1588 | 9.32k | } else { | 1589 | 308 | fIndexNoise = sbr->index_noise_prev[ch]; | 1590 | 308 | } | 1591 | 9.63k | fIndexSine = sbr->psi_is_prev[ch]; | 1592 | | | 1593 | | | 1594 | 26.2k | for (l = 0; l < sbr->L_E[ch]; l++) | 1595 | 16.5k | { | 1596 | 16.5k | uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0; | 1597 | | | 1598 | | #ifdef SBR_LOW_POWER | 1599 | | h_SL = 0; | 1600 | | #else | 1601 | 16.5k | h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4; | 1602 | 16.5k | h_SL = (no_noise ? 0 : h_SL); | 1603 | 16.5k | #endif | 1604 | | | 1605 | 16.5k | if (assembly_reset) | 1606 | 9.30k | { | 1607 | 46.5k | for (n = 0; n < 4; n++) | 1608 | 37.2k | { | 1609 | 37.2k | memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | 1610 | 37.2k | memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | 1611 | 37.2k | } | 1612 | | /* reset ringbuffer index */ | 1613 | 9.30k | sbr->GQ_ringbuf_index[ch] = 4; | 1614 | 9.30k | assembly_reset = 0; | 1615 | 9.30k | } | 1616 | | | 1617 | 326k | for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++) | 1618 | 309k | { | 1619 | | #ifdef SBR_LOW_POWER | 1620 | | uint8_t i_min1, i_plus1; | 1621 | | uint8_t sinusoids = 0; | 1622 | | #endif | 1623 | | | 1624 | | /* load new values into ringbuffer */ | 1625 | 309k | memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | 1626 | 309k | memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | 1627 | | | 1628 | 4.86M | for (m = 0; m < sbr->M; m++) | 1629 | 4.55M | { | 1630 | 4.55M | qmf_t psi; | 1631 | | | 1632 | 4.55M | G_filt = 0; | 1633 | 4.55M | Q_filt = 0; | 1634 | | | 1635 | 4.55M | #ifndef SBR_LOW_POWER | 1636 | 4.55M | if (h_SL != 0) | 1637 | 1.70M | { | 1638 | 1.70M | uint8_t ri = sbr->GQ_ringbuf_index[ch]; | 1639 | 10.2M | for (n = 0; n <= 4; n++) | 1640 | 8.50M | { | 1641 | 8.50M | real_t curr_h_smooth = h_smooth[n]; | 1642 | 8.50M | ri++; | 1643 | 8.50M | if (ri >= 5) | 1644 | 1.70M | ri -= 5; | 1645 | 8.50M | G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], curr_h_smooth); | 1646 | 8.50M | Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], curr_h_smooth); | 1647 | 8.50M | } | 1648 | 2.85M | } else { | 1649 | 2.85M | #endif | 1650 | 2.85M | G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; | 1651 | 2.85M | Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; | 1652 | 2.85M | #ifndef SBR_LOW_POWER | 1653 | 2.85M | } | 1654 | 4.55M | #endif | 1655 | 4.55M | if (adj->S_M_boost[l][m] != 0 || no_noise) | 1656 | 549k | Q_filt = 0; | 1657 | | | 1658 | | /* add noise to the output */ | 1659 | 4.55M | fIndexNoise = (fIndexNoise + 1) & 511; | 1660 | | | 1661 | | /* the smoothed gain values are applied to Xsbr */ | 1662 | | /* V is defined, not calculated */ | 1663 | | //QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | 1664 | | // + MUL_F(Q_filt, RE(V[fIndexNoise])); | 1665 | 4.55M | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | 1666 | 4.55M | + MUL_F(Q_filt, RE(V[fIndexNoise])); | 1667 | 4.55M | if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42) | 1668 | 4.39k | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320; | 1669 | 4.55M | #ifndef SBR_LOW_POWER | 1670 | | //QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | 1671 | | // + MUL_F(Q_filt, IM(V[fIndexNoise])); | 1672 | 4.55M | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | 1673 | 4.55M | + MUL_F(Q_filt, IM(V[fIndexNoise])); | 1674 | 4.55M | #endif | 1675 | | | 1676 | 4.55M | { | 1677 | 4.55M | int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1); | 1678 | 4.55M | QMF_RE(psi) = adj->S_M_boost[l][m] * phi_re[fIndexSine]; | 1679 | 4.55M | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi); | 1680 | | | 1681 | 4.55M | #ifndef SBR_LOW_POWER | 1682 | 4.55M | QMF_IM(psi) = rev * adj->S_M_boost[l][m] * phi_im[fIndexSine]; | 1683 | 4.55M | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi); | 1684 | | #else | 1685 | | | 1686 | | i_min1 = (fIndexSine - 1) & 3; | 1687 | | i_plus1 = (fIndexSine + 1) & 3; | 1688 | | | 1689 | | if ((m == 0) && (phi_re[i_plus1] != 0)) | 1690 | | { | 1691 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) += | 1692 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][0], FRAC_CONST(0.00815))); | 1693 | | if (sbr->M != 0) | 1694 | | { | 1695 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | 1696 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][1], FRAC_CONST(0.00815))); | 1697 | | } | 1698 | | } | 1699 | | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) | 1700 | | { | 1701 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | 1702 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); | 1703 | | } | 1704 | | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0)) | 1705 | | { | 1706 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | 1707 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][m + 1], FRAC_CONST(0.00815))); | 1708 | | } | 1709 | | if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) | 1710 | | { | 1711 | | if (m > 0) | 1712 | | { | 1713 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | 1714 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); | 1715 | | } | 1716 | | if (m + sbr->kx < 64) | 1717 | | { | 1718 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) += | 1719 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m], FRAC_CONST(0.00815))); | 1720 | | } | 1721 | | } | 1722 | | | 1723 | | if (adj->S_M_boost[l][m] != 0) | 1724 | | sinusoids++; | 1725 | | #endif | 1726 | 4.55M | } | 1727 | 4.55M | } | 1728 | | | 1729 | 309k | fIndexSine = (fIndexSine + 1) & 3; | 1730 | | | 1731 | | /* update the ringbuffer index used for filtering G and Q with h_smooth */ | 1732 | 309k | sbr->GQ_ringbuf_index[ch]++; | 1733 | 309k | if (sbr->GQ_ringbuf_index[ch] >= 5) | 1734 | 66.3k | sbr->GQ_ringbuf_index[ch] = 0; | 1735 | 309k | } | 1736 | 16.5k | } | 1737 | | | 1738 | 9.63k | sbr->index_noise_prev[ch] = fIndexNoise; | 1739 | 9.63k | sbr->psi_is_prev[ch] = fIndexSine; | 1740 | 9.63k | } |
Line | Count | Source | 1565 | 14.1k | { | 1566 | 14.1k | static real_t h_smooth[] = { | 1567 | 14.1k | FRAC_CONST(0.03183050093751), FRAC_CONST(0.11516383427084), | 1568 | 14.1k | FRAC_CONST(0.21816949906249), FRAC_CONST(0.30150283239582), | 1569 | 14.1k | FRAC_CONST(0.33333333333333) | 1570 | 14.1k | }; | 1571 | 14.1k | static int8_t phi_re[] = { 1, 0, -1, 0 }; | 1572 | 14.1k | static int8_t phi_im[] = { 0, 1, 0, -1 }; | 1573 | | | 1574 | 14.1k | uint8_t m, l, i, n; | 1575 | 14.1k | uint16_t fIndexNoise = 0; | 1576 | 14.1k | uint8_t fIndexSine = 0; | 1577 | 14.1k | uint8_t assembly_reset = 0; | 1578 | | | 1579 | 14.1k | real_t G_filt, Q_filt; | 1580 | | | 1581 | 14.1k | uint8_t h_SL; | 1582 | | | 1583 | | | 1584 | 14.1k | if (sbr->Reset == 1) | 1585 | 13.6k | { | 1586 | 13.6k | assembly_reset = 1; | 1587 | 13.6k | fIndexNoise = 0; | 1588 | 13.6k | } else { | 1589 | 525 | fIndexNoise = sbr->index_noise_prev[ch]; | 1590 | 525 | } | 1591 | 14.1k | fIndexSine = sbr->psi_is_prev[ch]; | 1592 | | | 1593 | | | 1594 | 38.0k | for (l = 0; l < sbr->L_E[ch]; l++) | 1595 | 23.9k | { | 1596 | 23.9k | uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0; | 1597 | | | 1598 | | #ifdef SBR_LOW_POWER | 1599 | | h_SL = 0; | 1600 | | #else | 1601 | 23.9k | h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4; | 1602 | 23.9k | h_SL = (no_noise ? 0 : h_SL); | 1603 | 23.9k | #endif | 1604 | | | 1605 | 23.9k | if (assembly_reset) | 1606 | 13.6k | { | 1607 | 68.0k | for (n = 0; n < 4; n++) | 1608 | 54.4k | { | 1609 | 54.4k | memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | 1610 | 54.4k | memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | 1611 | 54.4k | } | 1612 | | /* reset ringbuffer index */ | 1613 | 13.6k | sbr->GQ_ringbuf_index[ch] = 4; | 1614 | 13.6k | assembly_reset = 0; | 1615 | 13.6k | } | 1616 | | | 1617 | 457k | for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++) | 1618 | 433k | { | 1619 | | #ifdef SBR_LOW_POWER | 1620 | | uint8_t i_min1, i_plus1; | 1621 | | uint8_t sinusoids = 0; | 1622 | | #endif | 1623 | | | 1624 | | /* load new values into ringbuffer */ | 1625 | 433k | memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | 1626 | 433k | memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | 1627 | | | 1628 | 6.08M | for (m = 0; m < sbr->M; m++) | 1629 | 5.65M | { | 1630 | 5.65M | qmf_t psi; | 1631 | | | 1632 | 5.65M | G_filt = 0; | 1633 | 5.65M | Q_filt = 0; | 1634 | | | 1635 | 5.65M | #ifndef SBR_LOW_POWER | 1636 | 5.65M | if (h_SL != 0) | 1637 | 1.64M | { | 1638 | 1.64M | uint8_t ri = sbr->GQ_ringbuf_index[ch]; | 1639 | 9.86M | for (n = 0; n <= 4; n++) | 1640 | 8.22M | { | 1641 | 8.22M | real_t curr_h_smooth = h_smooth[n]; | 1642 | 8.22M | ri++; | 1643 | 8.22M | if (ri >= 5) | 1644 | 1.64M | ri -= 5; | 1645 | 8.22M | G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], curr_h_smooth); | 1646 | 8.22M | Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], curr_h_smooth); | 1647 | 8.22M | } | 1648 | 4.00M | } else { | 1649 | 4.00M | #endif | 1650 | 4.00M | G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; | 1651 | 4.00M | Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; | 1652 | 4.00M | #ifndef SBR_LOW_POWER | 1653 | 4.00M | } | 1654 | 5.65M | #endif | 1655 | 5.65M | if (adj->S_M_boost[l][m] != 0 || no_noise) | 1656 | 469k | Q_filt = 0; | 1657 | | | 1658 | | /* add noise to the output */ | 1659 | 5.65M | fIndexNoise = (fIndexNoise + 1) & 511; | 1660 | | | 1661 | | /* the smoothed gain values are applied to Xsbr */ | 1662 | | /* V is defined, not calculated */ | 1663 | | //QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | 1664 | | // + MUL_F(Q_filt, RE(V[fIndexNoise])); | 1665 | 5.65M | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | 1666 | 5.65M | + MUL_F(Q_filt, RE(V[fIndexNoise])); | 1667 | 5.65M | if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42) | 1668 | 6.12k | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320; | 1669 | 5.65M | #ifndef SBR_LOW_POWER | 1670 | | //QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | 1671 | | // + MUL_F(Q_filt, IM(V[fIndexNoise])); | 1672 | 5.65M | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | 1673 | 5.65M | + MUL_F(Q_filt, IM(V[fIndexNoise])); | 1674 | 5.65M | #endif | 1675 | | | 1676 | 5.65M | { | 1677 | 5.65M | int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1); | 1678 | 5.65M | QMF_RE(psi) = adj->S_M_boost[l][m] * phi_re[fIndexSine]; | 1679 | 5.65M | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi); | 1680 | | | 1681 | 5.65M | #ifndef SBR_LOW_POWER | 1682 | 5.65M | QMF_IM(psi) = rev * adj->S_M_boost[l][m] * phi_im[fIndexSine]; | 1683 | 5.65M | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi); | 1684 | | #else | 1685 | | | 1686 | | i_min1 = (fIndexSine - 1) & 3; | 1687 | | i_plus1 = (fIndexSine + 1) & 3; | 1688 | | | 1689 | | if ((m == 0) && (phi_re[i_plus1] != 0)) | 1690 | | { | 1691 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) += | 1692 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][0], FRAC_CONST(0.00815))); | 1693 | | if (sbr->M != 0) | 1694 | | { | 1695 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | 1696 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][1], FRAC_CONST(0.00815))); | 1697 | | } | 1698 | | } | 1699 | | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) | 1700 | | { | 1701 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | 1702 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); | 1703 | | } | 1704 | | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0)) | 1705 | | { | 1706 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | 1707 | | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][m + 1], FRAC_CONST(0.00815))); | 1708 | | } | 1709 | | if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) | 1710 | | { | 1711 | | if (m > 0) | 1712 | | { | 1713 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | 1714 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); | 1715 | | } | 1716 | | if (m + sbr->kx < 64) | 1717 | | { | 1718 | | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) += | 1719 | | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m], FRAC_CONST(0.00815))); | 1720 | | } | 1721 | | } | 1722 | | | 1723 | | if (adj->S_M_boost[l][m] != 0) | 1724 | | sinusoids++; | 1725 | | #endif | 1726 | 5.65M | } | 1727 | 5.65M | } | 1728 | | | 1729 | 433k | fIndexSine = (fIndexSine + 1) & 3; | 1730 | | | 1731 | | /* update the ringbuffer index used for filtering G and Q with h_smooth */ | 1732 | 433k | sbr->GQ_ringbuf_index[ch]++; | 1733 | 433k | if (sbr->GQ_ringbuf_index[ch] >= 5) | 1734 | 93.2k | sbr->GQ_ringbuf_index[ch] = 0; | 1735 | 433k | } | 1736 | 23.9k | } | 1737 | | | 1738 | 14.1k | sbr->index_noise_prev[ch] = fIndexNoise; | 1739 | 14.1k | sbr->psi_is_prev[ch] = fIndexSine; | 1740 | 14.1k | } |
|
1741 | | |
1742 | | #endif |