blob: b26314a7eb51aa269e22dec45f7a82cee665c239
1 | /* |
2 | * Copyright (c) 2013 |
3 | * MIPS Technologies, Inc., California. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. |
13 | * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its |
14 | * contributors may be used to endorse or promote products derived from |
15 | * this software without specific prior written permission. |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 | * SUCH DAMAGE. |
28 | * |
29 | * AAC Spectral Band Replication decoding functions (fixed-point) |
30 | * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) |
31 | * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com> |
32 | * |
33 | * This file is part of FFmpeg. |
34 | * |
35 | * FFmpeg is free software; you can redistribute it and/or |
36 | * modify it under the terms of the GNU Lesser General Public |
37 | * License as published by the Free Software Foundation; either |
38 | * version 2.1 of the License, or (at your option) any later version. |
39 | * |
40 | * FFmpeg is distributed in the hope that it will be useful, |
41 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
42 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
43 | * Lesser General Public License for more details. |
44 | * |
45 | * You should have received a copy of the GNU Lesser General Public |
46 | * License along with FFmpeg; if not, write to the Free Software |
47 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
48 | */ |
49 | |
50 | /** |
51 | * @file |
52 | * AAC Spectral Band Replication decoding functions (fixed-point) |
53 | * Note: Rounding-to-nearest used unless otherwise stated |
54 | * @author Robert Swain ( rob opendot cl ) |
55 | * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com ) |
56 | */ |
57 | #define USE_FIXED 1 |
58 | |
59 | #include "aac.h" |
60 | #include "sbr.h" |
61 | #include "aacsbr.h" |
62 | #include "aacsbrdata.h" |
63 | #include "aacsbr_fixed_tablegen.h" |
64 | #include "fft.h" |
65 | #include "aacps.h" |
66 | #include "sbrdsp.h" |
67 | #include "libavutil/internal.h" |
68 | #include "libavutil/libm.h" |
69 | #include "libavutil/avassert.h" |
70 | |
71 | #include <stdint.h> |
72 | #include <float.h> |
73 | #include <math.h> |
74 | |
75 | static VLC vlc_sbr[10]; |
76 | static void aacsbr_func_ptr_init(AACSBRContext *c); |
77 | static const int CONST_LN2 = Q31(0.6931471806/256); // ln(2)/256 |
78 | static const int CONST_RECIP_LN2 = Q31(0.7213475204); // 0.5/ln(2) |
79 | static const int CONST_076923 = Q31(0.76923076923076923077f); |
80 | |
81 | static const int fixed_log_table[10] = |
82 | { |
83 | Q31(1.0/2), Q31(1.0/3), Q31(1.0/4), Q31(1.0/5), Q31(1.0/6), |
84 | Q31(1.0/7), Q31(1.0/8), Q31(1.0/9), Q31(1.0/10), Q31(1.0/11) |
85 | }; |
86 | |
87 | static int fixed_log(int x) |
88 | { |
89 | int i, ret, xpow, tmp; |
90 | |
91 | ret = x; |
92 | xpow = x; |
93 | for (i=0; i<10; i+=2){ |
94 | xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31); |
95 | tmp = (int)(((int64_t)xpow * fixed_log_table[i] + 0x40000000) >> 31); |
96 | ret -= tmp; |
97 | |
98 | xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31); |
99 | tmp = (int)(((int64_t)xpow * fixed_log_table[i+1] + 0x40000000) >> 31); |
100 | ret += tmp; |
101 | } |
102 | |
103 | return ret; |
104 | } |
105 | |
106 | static const int fixed_exp_table[7] = |
107 | { |
108 | Q31(1.0/2), Q31(1.0/6), Q31(1.0/24), Q31(1.0/120), |
109 | Q31(1.0/720), Q31(1.0/5040), Q31(1.0/40320) |
110 | }; |
111 | |
112 | static int fixed_exp(int x) |
113 | { |
114 | int i, ret, xpow, tmp; |
115 | |
116 | ret = 0x800000 + x; |
117 | xpow = x; |
118 | for (i=0; i<7; i++){ |
119 | xpow = (int)(((int64_t)xpow * x + 0x400000) >> 23); |
120 | tmp = (int)(((int64_t)xpow * fixed_exp_table[i] + 0x40000000) >> 31); |
121 | ret += tmp; |
122 | } |
123 | |
124 | return ret; |
125 | } |
126 | |
127 | static void make_bands(int16_t* bands, int start, int stop, int num_bands) |
128 | { |
129 | int k, previous, present; |
130 | int base, prod, nz = 0; |
131 | |
132 | base = (stop << 23) / start; |
133 | while (base < 0x40000000){ |
134 | base <<= 1; |
135 | nz++; |
136 | } |
137 | base = fixed_log(base - 0x80000000); |
138 | base = (((base + 0x80) >> 8) + (8-nz)*CONST_LN2) / num_bands; |
139 | base = fixed_exp(base); |
140 | |
141 | previous = start; |
142 | prod = start << 23; |
143 | |
144 | for (k = 0; k < num_bands-1; k++) { |
145 | prod = (int)(((int64_t)prod * base + 0x400000) >> 23); |
146 | present = (prod + 0x400000) >> 23; |
147 | bands[k] = present - previous; |
148 | previous = present; |
149 | } |
150 | bands[num_bands-1] = stop - previous; |
151 | } |
152 | |
153 | /// Dequantization and stereo decoding (14496-3 sp04 p203) |
154 | static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) |
155 | { |
156 | int k, e; |
157 | int ch; |
158 | |
159 | if (id_aac == TYPE_CPE && sbr->bs_coupling) { |
160 | int alpha = sbr->data[0].bs_amp_res ? 2 : 1; |
161 | int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24; |
162 | for (e = 1; e <= sbr->data[0].bs_num_env; e++) { |
163 | for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { |
164 | SoftFloat temp1, temp2, fac; |
165 | |
166 | temp1.exp = sbr->data[0].env_facs_q[e][k] * alpha + 14; |
167 | if (temp1.exp & 1) |
168 | temp1.mant = 759250125; |
169 | else |
170 | temp1.mant = 0x20000000; |
171 | temp1.exp = (temp1.exp >> 1) + 1; |
172 | if (temp1.exp > 66) { // temp1 > 1E20 |
173 | av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); |
174 | temp1 = FLOAT_1; |
175 | } |
176 | |
177 | temp2.exp = (pan_offset - sbr->data[1].env_facs_q[e][k]) * alpha; |
178 | if (temp2.exp & 1) |
179 | temp2.mant = 759250125; |
180 | else |
181 | temp2.mant = 0x20000000; |
182 | temp2.exp = (temp2.exp >> 1) + 1; |
183 | fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2)); |
184 | sbr->data[0].env_facs[e][k] = fac; |
185 | sbr->data[1].env_facs[e][k] = av_mul_sf(fac, temp2); |
186 | } |
187 | } |
188 | for (e = 1; e <= sbr->data[0].bs_num_noise; e++) { |
189 | for (k = 0; k < sbr->n_q; k++) { |
190 | SoftFloat temp1, temp2, fac; |
191 | |
192 | temp1.exp = NOISE_FLOOR_OFFSET - \ |
193 | sbr->data[0].noise_facs_q[e][k] + 2; |
194 | temp1.mant = 0x20000000; |
195 | av_assert0(temp1.exp <= 66); |
196 | temp2.exp = 12 - sbr->data[1].noise_facs_q[e][k] + 1; |
197 | temp2.mant = 0x20000000; |
198 | fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2)); |
199 | sbr->data[0].noise_facs[e][k] = fac; |
200 | sbr->data[1].noise_facs[e][k] = av_mul_sf(fac, temp2); |
201 | } |
202 | } |
203 | } else { // SCE or one non-coupled CPE |
204 | for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { |
205 | int alpha = sbr->data[ch].bs_amp_res ? 2 : 1; |
206 | for (e = 1; e <= sbr->data[ch].bs_num_env; e++) |
207 | for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){ |
208 | SoftFloat temp1; |
209 | |
210 | temp1.exp = alpha * sbr->data[ch].env_facs_q[e][k] + 12; |
211 | if (temp1.exp & 1) |
212 | temp1.mant = 759250125; |
213 | else |
214 | temp1.mant = 0x20000000; |
215 | temp1.exp = (temp1.exp >> 1) + 1; |
216 | if (temp1.exp > 66) { // temp1 > 1E20 |
217 | av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); |
218 | temp1 = FLOAT_1; |
219 | } |
220 | sbr->data[ch].env_facs[e][k] = temp1; |
221 | } |
222 | for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) |
223 | for (k = 0; k < sbr->n_q; k++){ |
224 | sbr->data[ch].noise_facs[e][k].exp = NOISE_FLOOR_OFFSET - \ |
225 | sbr->data[ch].noise_facs_q[e][k] + 1; |
226 | sbr->data[ch].noise_facs[e][k].mant = 0x20000000; |
227 | } |
228 | } |
229 | } |
230 | } |
231 | |
232 | /** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering |
233 | * (14496-3 sp04 p214) |
234 | * Warning: This routine does not seem numerically stable. |
235 | */ |
236 | static void sbr_hf_inverse_filter(SBRDSPContext *dsp, |
237 | int (*alpha0)[2], int (*alpha1)[2], |
238 | const int X_low[32][40][2], int k0) |
239 | { |
240 | int k; |
241 | int shift, round; |
242 | |
243 | for (k = 0; k < k0; k++) { |
244 | SoftFloat phi[3][2][2]; |
245 | SoftFloat a00, a01, a10, a11; |
246 | SoftFloat dk; |
247 | |
248 | dsp->autocorrelate(X_low[k], phi); |
249 | |
250 | dk = av_sub_sf(av_mul_sf(phi[2][1][0], phi[1][0][0]), |
251 | av_mul_sf(av_add_sf(av_mul_sf(phi[1][1][0], phi[1][1][0]), |
252 | av_mul_sf(phi[1][1][1], phi[1][1][1])), FLOAT_0999999)); |
253 | |
254 | if (!dk.mant) { |
255 | a10 = FLOAT_0; |
256 | a11 = FLOAT_0; |
257 | } else { |
258 | SoftFloat temp_real, temp_im; |
259 | temp_real = av_sub_sf(av_sub_sf(av_mul_sf(phi[0][0][0], phi[1][1][0]), |
260 | av_mul_sf(phi[0][0][1], phi[1][1][1])), |
261 | av_mul_sf(phi[0][1][0], phi[1][0][0])); |
262 | temp_im = av_sub_sf(av_add_sf(av_mul_sf(phi[0][0][0], phi[1][1][1]), |
263 | av_mul_sf(phi[0][0][1], phi[1][1][0])), |
264 | av_mul_sf(phi[0][1][1], phi[1][0][0])); |
265 | |
266 | a10 = av_div_sf(temp_real, dk); |
267 | a11 = av_div_sf(temp_im, dk); |
268 | } |
269 | |
270 | if (!phi[1][0][0].mant) { |
271 | a00 = FLOAT_0; |
272 | a01 = FLOAT_0; |
273 | } else { |
274 | SoftFloat temp_real, temp_im; |
275 | temp_real = av_add_sf(phi[0][0][0], |
276 | av_add_sf(av_mul_sf(a10, phi[1][1][0]), |
277 | av_mul_sf(a11, phi[1][1][1]))); |
278 | temp_im = av_add_sf(phi[0][0][1], |
279 | av_sub_sf(av_mul_sf(a11, phi[1][1][0]), |
280 | av_mul_sf(a10, phi[1][1][1]))); |
281 | |
282 | temp_real.mant = -temp_real.mant; |
283 | temp_im.mant = -temp_im.mant; |
284 | a00 = av_div_sf(temp_real, phi[1][0][0]); |
285 | a01 = av_div_sf(temp_im, phi[1][0][0]); |
286 | } |
287 | |
288 | shift = a00.exp; |
289 | if (shift >= 3) |
290 | alpha0[k][0] = 0x7fffffff; |
291 | else { |
292 | a00.mant <<= 1; |
293 | shift = 2-shift; |
294 | if (shift == 0) |
295 | alpha0[k][0] = a00.mant; |
296 | else { |
297 | round = 1 << (shift-1); |
298 | alpha0[k][0] = (a00.mant + round) >> shift; |
299 | } |
300 | } |
301 | |
302 | shift = a01.exp; |
303 | if (shift >= 3) |
304 | alpha0[k][1] = 0x7fffffff; |
305 | else { |
306 | a01.mant <<= 1; |
307 | shift = 2-shift; |
308 | if (shift == 0) |
309 | alpha0[k][1] = a01.mant; |
310 | else { |
311 | round = 1 << (shift-1); |
312 | alpha0[k][1] = (a01.mant + round) >> shift; |
313 | } |
314 | } |
315 | shift = a10.exp; |
316 | if (shift >= 3) |
317 | alpha1[k][0] = 0x7fffffff; |
318 | else { |
319 | a10.mant <<= 1; |
320 | shift = 2-shift; |
321 | if (shift == 0) |
322 | alpha1[k][0] = a10.mant; |
323 | else { |
324 | round = 1 << (shift-1); |
325 | alpha1[k][0] = (a10.mant + round) >> shift; |
326 | } |
327 | } |
328 | |
329 | shift = a11.exp; |
330 | if (shift >= 3) |
331 | alpha1[k][1] = 0x7fffffff; |
332 | else { |
333 | a11.mant <<= 1; |
334 | shift = 2-shift; |
335 | if (shift == 0) |
336 | alpha1[k][1] = a11.mant; |
337 | else { |
338 | round = 1 << (shift-1); |
339 | alpha1[k][1] = (a11.mant + round) >> shift; |
340 | } |
341 | } |
342 | |
343 | shift = (int)(((int64_t)(alpha1[k][0]>>1) * (alpha1[k][0]>>1) + \ |
344 | (int64_t)(alpha1[k][1]>>1) * (alpha1[k][1]>>1) + \ |
345 | 0x40000000) >> 31); |
346 | if (shift >= 0x20000000){ |
347 | alpha1[k][0] = 0; |
348 | alpha1[k][1] = 0; |
349 | alpha0[k][0] = 0; |
350 | alpha0[k][1] = 0; |
351 | } |
352 | |
353 | shift = (int)(((int64_t)(alpha0[k][0]>>1) * (alpha0[k][0]>>1) + \ |
354 | (int64_t)(alpha0[k][1]>>1) * (alpha0[k][1]>>1) + \ |
355 | 0x40000000) >> 31); |
356 | if (shift >= 0x20000000){ |
357 | alpha1[k][0] = 0; |
358 | alpha1[k][1] = 0; |
359 | alpha0[k][0] = 0; |
360 | alpha0[k][1] = 0; |
361 | } |
362 | } |
363 | } |
364 | |
365 | /// Chirp Factors (14496-3 sp04 p214) |
366 | static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data) |
367 | { |
368 | int i; |
369 | int new_bw; |
370 | static const int bw_tab[] = { 0, 1610612736, 1932735283, 2104533975 }; |
371 | int64_t accu; |
372 | |
373 | for (i = 0; i < sbr->n_q; i++) { |
374 | if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1) |
375 | new_bw = 1288490189; |
376 | else |
377 | new_bw = bw_tab[ch_data->bs_invf_mode[0][i]]; |
378 | |
379 | if (new_bw < ch_data->bw_array[i]){ |
380 | accu = (int64_t)new_bw * 1610612736; |
381 | accu += (int64_t)ch_data->bw_array[i] * 0x20000000; |
382 | new_bw = (int)((accu + 0x40000000) >> 31); |
383 | } else { |
384 | accu = (int64_t)new_bw * 1946157056; |
385 | accu += (int64_t)ch_data->bw_array[i] * 201326592; |
386 | new_bw = (int)((accu + 0x40000000) >> 31); |
387 | } |
388 | ch_data->bw_array[i] = new_bw < 0x2000000 ? 0 : new_bw; |
389 | } |
390 | } |
391 | |
392 | /** |
393 | * Calculation of levels of additional HF signal components (14496-3 sp04 p219) |
394 | * and Calculation of gain (14496-3 sp04 p219) |
395 | */ |
396 | static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr, |
397 | SBRData *ch_data, const int e_a[2]) |
398 | { |
399 | int e, k, m; |
400 | // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) |
401 | static const SoftFloat limgain[4] = { { 760155524, 0 }, { 0x20000000, 1 }, |
402 | { 758351638, 1 }, { 625000000, 34 } }; |
403 | |
404 | for (e = 0; e < ch_data->bs_num_env; e++) { |
405 | int delta = !((e == e_a[1]) || (e == e_a[0])); |
406 | for (k = 0; k < sbr->n_lim; k++) { |
407 | SoftFloat gain_boost, gain_max; |
408 | SoftFloat sum[2]; |
409 | sum[0] = sum[1] = FLOAT_0; |
410 | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
411 | const SoftFloat temp = av_div_sf(sbr->e_origmapped[e][m], |
412 | av_add_sf(FLOAT_1, sbr->q_mapped[e][m])); |
413 | sbr->q_m[e][m] = av_sqrt_sf(av_mul_sf(temp, sbr->q_mapped[e][m])); |
414 | sbr->s_m[e][m] = av_sqrt_sf(av_mul_sf(temp, av_int2sf(ch_data->s_indexmapped[e + 1][m], 0))); |
415 | if (!sbr->s_mapped[e][m]) { |
416 | if (delta) { |
417 | sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m], |
418 | av_mul_sf(av_add_sf(FLOAT_1, sbr->e_curr[e][m]), |
419 | av_add_sf(FLOAT_1, sbr->q_mapped[e][m])))); |
420 | } else { |
421 | sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m], |
422 | av_add_sf(FLOAT_1, sbr->e_curr[e][m]))); |
423 | } |
424 | } else { |
425 | sbr->gain[e][m] = av_sqrt_sf( |
426 | av_div_sf( |
427 | av_mul_sf(sbr->e_origmapped[e][m], sbr->q_mapped[e][m]), |
428 | av_mul_sf( |
429 | av_add_sf(FLOAT_1, sbr->e_curr[e][m]), |
430 | av_add_sf(FLOAT_1, sbr->q_mapped[e][m])))); |
431 | } |
432 | } |
433 | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
434 | sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]); |
435 | sum[1] = av_add_sf(sum[1], sbr->e_curr[e][m]); |
436 | } |
437 | gain_max = av_mul_sf(limgain[sbr->bs_limiter_gains], |
438 | av_sqrt_sf( |
439 | av_div_sf( |
440 | av_add_sf(FLOAT_EPSILON, sum[0]), |
441 | av_add_sf(FLOAT_EPSILON, sum[1])))); |
442 | if (av_gt_sf(gain_max, FLOAT_100000)) |
443 | gain_max = FLOAT_100000; |
444 | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
445 | SoftFloat q_m_max = av_div_sf( |
446 | av_mul_sf(sbr->q_m[e][m], gain_max), |
447 | sbr->gain[e][m]); |
448 | if (av_gt_sf(sbr->q_m[e][m], q_m_max)) |
449 | sbr->q_m[e][m] = q_m_max; |
450 | if (av_gt_sf(sbr->gain[e][m], gain_max)) |
451 | sbr->gain[e][m] = gain_max; |
452 | } |
453 | sum[0] = sum[1] = FLOAT_0; |
454 | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
455 | sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]); |
456 | sum[1] = av_add_sf(sum[1], |
457 | av_mul_sf( |
458 | av_mul_sf(sbr->e_curr[e][m], |
459 | sbr->gain[e][m]), |
460 | sbr->gain[e][m])); |
461 | sum[1] = av_add_sf(sum[1], |
462 | av_mul_sf(sbr->s_m[e][m], sbr->s_m[e][m])); |
463 | if (delta && !sbr->s_m[e][m].mant) |
464 | sum[1] = av_add_sf(sum[1], |
465 | av_mul_sf(sbr->q_m[e][m], sbr->q_m[e][m])); |
466 | } |
467 | gain_boost = av_sqrt_sf( |
468 | av_div_sf( |
469 | av_add_sf(FLOAT_EPSILON, sum[0]), |
470 | av_add_sf(FLOAT_EPSILON, sum[1]))); |
471 | if (av_gt_sf(gain_boost, FLOAT_1584893192)) |
472 | gain_boost = FLOAT_1584893192; |
473 | |
474 | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
475 | sbr->gain[e][m] = av_mul_sf(sbr->gain[e][m], gain_boost); |
476 | sbr->q_m[e][m] = av_mul_sf(sbr->q_m[e][m], gain_boost); |
477 | sbr->s_m[e][m] = av_mul_sf(sbr->s_m[e][m], gain_boost); |
478 | } |
479 | } |
480 | } |
481 | } |
482 | |
483 | /// Assembling HF Signals (14496-3 sp04 p220) |
484 | static void sbr_hf_assemble(int Y1[38][64][2], |
485 | const int X_high[64][40][2], |
486 | SpectralBandReplication *sbr, SBRData *ch_data, |
487 | const int e_a[2]) |
488 | { |
489 | int e, i, j, m; |
490 | const int h_SL = 4 * !sbr->bs_smoothing_mode; |
491 | const int kx = sbr->kx[1]; |
492 | const int m_max = sbr->m[1]; |
493 | static const SoftFloat h_smooth[5] = { |
494 | { 715827883, -1 }, |
495 | { 647472402, -1 }, |
496 | { 937030863, -2 }, |
497 | { 989249804, -3 }, |
498 | { 546843842, -4 }, |
499 | }; |
500 | SoftFloat (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp; |
501 | int indexnoise = ch_data->f_indexnoise; |
502 | int indexsine = ch_data->f_indexsine; |
503 | |
504 | if (sbr->reset) { |
505 | for (i = 0; i < h_SL; i++) { |
506 | memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0])); |
507 | memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0])); |
508 | } |
509 | } else if (h_SL) { |
510 | for (i = 0; i < 4; i++) { |
511 | memcpy(g_temp[i + 2 * ch_data->t_env[0]], |
512 | g_temp[i + 2 * ch_data->t_env_num_env_old], |
513 | sizeof(g_temp[0])); |
514 | memcpy(q_temp[i + 2 * ch_data->t_env[0]], |
515 | q_temp[i + 2 * ch_data->t_env_num_env_old], |
516 | sizeof(q_temp[0])); |
517 | } |
518 | } |
519 | |
520 | for (e = 0; e < ch_data->bs_num_env; e++) { |
521 | for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { |
522 | memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0])); |
523 | memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0])); |
524 | } |
525 | } |
526 | |
527 | for (e = 0; e < ch_data->bs_num_env; e++) { |
528 | for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { |
529 | SoftFloat g_filt_tab[48]; |
530 | SoftFloat q_filt_tab[48]; |
531 | SoftFloat *g_filt, *q_filt; |
532 | |
533 | if (h_SL && e != e_a[0] && e != e_a[1]) { |
534 | g_filt = g_filt_tab; |
535 | q_filt = q_filt_tab; |
536 | for (m = 0; m < m_max; m++) { |
537 | const int idx1 = i + h_SL; |
538 | g_filt[m].mant = g_filt[m].exp = 0; |
539 | q_filt[m].mant = q_filt[m].exp = 0; |
540 | for (j = 0; j <= h_SL; j++) { |
541 | g_filt[m] = av_add_sf(g_filt[m], |
542 | av_mul_sf(g_temp[idx1 - j][m], |
543 | h_smooth[j])); |
544 | q_filt[m] = av_add_sf(q_filt[m], |
545 | av_mul_sf(q_temp[idx1 - j][m], |
546 | h_smooth[j])); |
547 | } |
548 | } |
549 | } else { |
550 | g_filt = g_temp[i + h_SL]; |
551 | q_filt = q_temp[i]; |
552 | } |
553 | |
554 | sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max, |
555 | i + ENVELOPE_ADJUSTMENT_OFFSET); |
556 | |
557 | if (e != e_a[0] && e != e_a[1]) { |
558 | sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e], |
559 | q_filt, indexnoise, |
560 | kx, m_max); |
561 | } else { |
562 | int idx = indexsine&1; |
563 | int A = (1-((indexsine+(kx & 1))&2)); |
564 | int B = (A^(-idx)) + idx; |
565 | int *out = &Y1[i][kx][idx]; |
566 | int shift, round; |
567 | |
568 | SoftFloat *in = sbr->s_m[e]; |
569 | for (m = 0; m+1 < m_max; m+=2) { |
570 | shift = 22 - in[m ].exp; |
571 | round = 1 << (shift-1); |
572 | out[2*m ] += (in[m ].mant * A + round) >> shift; |
573 | |
574 | shift = 22 - in[m+1].exp; |
575 | round = 1 << (shift-1); |
576 | out[2*m+2] += (in[m+1].mant * B + round) >> shift; |
577 | } |
578 | if(m_max&1) |
579 | { |
580 | shift = 22 - in[m ].exp; |
581 | round = 1 << (shift-1); |
582 | |
583 | out[2*m ] += (in[m ].mant * A + round) >> shift; |
584 | } |
585 | } |
586 | indexnoise = (indexnoise + m_max) & 0x1ff; |
587 | indexsine = (indexsine + 1) & 3; |
588 | } |
589 | } |
590 | ch_data->f_indexnoise = indexnoise; |
591 | ch_data->f_indexsine = indexsine; |
592 | } |
593 | |
594 | #include "aacsbr_template.c" |
595 |