/src/ffmpeg/libavcodec/aacsbr.c
Line | Count | Source |
1 | | /* |
2 | | * AAC Spectral Band Replication decoding functions |
3 | | * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) |
4 | | * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com> |
5 | | * |
6 | | * This file is part of FFmpeg. |
7 | | * |
8 | | * FFmpeg is free software; you can redistribute it and/or |
9 | | * modify it under the terms of the GNU Lesser General Public |
10 | | * License as published by the Free Software Foundation; either |
11 | | * version 2.1 of the License, or (at your option) any later version. |
12 | | * |
13 | | * FFmpeg is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public |
19 | | * License along with FFmpeg; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | | */ |
22 | | |
23 | | /** |
24 | | * @file |
25 | | * AAC Spectral Band Replication decoding functions |
26 | | * @author Robert Swain ( rob opendot cl ) |
27 | | */ |
28 | 501k | #define USE_FIXED 0 |
29 | | |
30 | | #include "aac.h" |
31 | | #include "sbr.h" |
32 | | #include "aacsbr.h" |
33 | | #include "aacsbrdata.h" |
34 | | #include "aacps.h" |
35 | | #include "sbrdsp.h" |
36 | | #include "libavutil/internal.h" |
37 | | #include "libavutil/intfloat.h" |
38 | | #include "libavutil/libm.h" |
39 | | #include "libavutil/avassert.h" |
40 | | #include "libavutil/mem_internal.h" |
41 | | |
42 | | #include <stdint.h> |
43 | | #include <float.h> |
44 | | #include <math.h> |
45 | | |
46 | | /** |
47 | | * 2^(x) for integer x |
48 | | * @return correctly rounded float |
49 | | */ |
50 | 712k | static av_always_inline float exp2fi(int x) { |
51 | | /* Normal range */ |
52 | 712k | if (-126 <= x && x <= 128) |
53 | 711k | return av_int2float((x+127) << 23); |
54 | | /* Too large */ |
55 | 1.73k | else if (x > 128) |
56 | 1.70k | return INFINITY; |
57 | | /* Subnormal numbers */ |
58 | 37 | else if (x > -150) |
59 | 0 | return av_int2float(1 << (x+149)); |
60 | | /* Negligibly small */ |
61 | 37 | else |
62 | 37 | return 0; |
63 | 712k | } |
64 | | |
65 | | static void aacsbr_func_ptr_init(AACSBRContext *c); |
66 | | |
67 | | static void make_bands(int16_t* bands, int start, int stop, int num_bands) |
68 | 1.23M | { |
69 | 1.23M | int k, previous, present; |
70 | 1.23M | float base, prod; |
71 | | |
72 | 1.23M | base = powf((float)stop / start, 1.0f / num_bands); |
73 | 1.23M | prod = start; |
74 | 1.23M | previous = start; |
75 | | |
76 | 13.4M | for (k = 0; k < num_bands-1; k++) { |
77 | 12.2M | prod *= base; |
78 | 12.2M | present = lrintf(prod); |
79 | 12.2M | bands[k] = present - previous; |
80 | 12.2M | previous = present; |
81 | 12.2M | } |
82 | 1.23M | bands[num_bands-1] = stop - previous; |
83 | 1.23M | } |
84 | | |
85 | | /// Dequantization and stereo decoding (14496-3 sp04 p203) |
86 | | static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) |
87 | 38.0k | { |
88 | 38.0k | int k, e; |
89 | 38.0k | int ch; |
90 | 38.0k | static const double exp2_tab[2] = {1, M_SQRT2}; |
91 | 38.0k | if (id_aac == TYPE_CPE && sbr->bs_coupling) { |
92 | 4.88k | int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24; |
93 | 14.6k | for (e = 1; e <= sbr->data[0].bs_num_env; e++) { |
94 | 62.9k | for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { |
95 | 53.1k | float temp1, temp2, fac; |
96 | 53.1k | if (sbr->data[0].bs_amp_res) { |
97 | 40.2k | temp1 = exp2fi(sbr->data[0].env_facs_q[e][k] + 7); |
98 | 40.2k | temp2 = exp2fi(pan_offset - sbr->data[1].env_facs_q[e][k]); |
99 | 40.2k | } |
100 | 12.9k | else { |
101 | 12.9k | temp1 = exp2fi((sbr->data[0].env_facs_q[e][k]>>1) + 7) * |
102 | 12.9k | exp2_tab[sbr->data[0].env_facs_q[e][k] & 1]; |
103 | 12.9k | temp2 = exp2fi((pan_offset - sbr->data[1].env_facs_q[e][k])>>1) * |
104 | 12.9k | exp2_tab[(pan_offset - sbr->data[1].env_facs_q[e][k]) & 1]; |
105 | 12.9k | } |
106 | 53.1k | if (temp1 > 1E20) { |
107 | 2.97k | av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); |
108 | 2.97k | temp1 = 1; |
109 | 2.97k | } |
110 | 53.1k | fac = temp1 / (1.0f + temp2); |
111 | 53.1k | sbr->data[0].env_facs[e][k] = fac; |
112 | 53.1k | sbr->data[1].env_facs[e][k] = fac * temp2; |
113 | 53.1k | } |
114 | 9.75k | } |
115 | 11.6k | for (e = 1; e <= sbr->data[0].bs_num_noise; e++) { |
116 | 18.7k | for (k = 0; k < sbr->n_q; k++) { |
117 | 12.0k | float temp1 = exp2fi(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs_q[e][k] + 1); |
118 | 12.0k | float temp2 = exp2fi(12 - sbr->data[1].noise_facs_q[e][k]); |
119 | 12.0k | float fac; |
120 | 12.0k | av_assert0(temp1 <= 1E20); |
121 | 12.0k | fac = temp1 / (1.0f + temp2); |
122 | 12.0k | sbr->data[0].noise_facs[e][k] = fac; |
123 | 12.0k | sbr->data[1].noise_facs[e][k] = fac * temp2; |
124 | 12.0k | } |
125 | 6.77k | } |
126 | 33.1k | } else { // SCE or one non-coupled CPE |
127 | 80.9k | for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { |
128 | 131k | for (e = 1; e <= sbr->data[ch].bs_num_env; e++) |
129 | 530k | for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){ |
130 | 446k | if (sbr->data[ch].bs_amp_res) |
131 | 215k | sbr->data[ch].env_facs[e][k] = exp2fi(sbr->data[ch].env_facs_q[e][k] + 6); |
132 | 231k | else |
133 | 231k | sbr->data[ch].env_facs[e][k] = exp2fi((sbr->data[ch].env_facs_q[e][k]>>1) + 6) |
134 | 231k | * exp2_tab[sbr->data[ch].env_facs_q[e][k] & 1]; |
135 | 446k | if (sbr->data[ch].env_facs[e][k] > 1E20) { |
136 | 22.2k | av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); |
137 | 22.2k | sbr->data[ch].env_facs[e][k] = 1; |
138 | 22.2k | } |
139 | 446k | } |
140 | | |
141 | 110k | for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) |
142 | 199k | for (k = 0; k < sbr->n_q; k++) |
143 | 135k | sbr->data[ch].noise_facs[e][k] = |
144 | 135k | exp2fi(NOISE_FLOOR_OFFSET - sbr->data[ch].noise_facs_q[e][k]); |
145 | 47.8k | } |
146 | 33.1k | } |
147 | 38.0k | } |
148 | | |
149 | | /** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering |
150 | | * (14496-3 sp04 p214) |
151 | | * Warning: This routine does not seem numerically stable. |
152 | | */ |
153 | | static void sbr_hf_inverse_filter(SBRDSPContext *dsp, |
154 | | float (*alpha0)[2], float (*alpha1)[2], |
155 | | const float X_low[32][40][2], int k0) |
156 | 57.5k | { |
157 | 57.5k | int k; |
158 | 936k | for (k = 0; k < k0; k++) { |
159 | 879k | LOCAL_ALIGNED_16(float, phi, [3], [2][2]); |
160 | 879k | float dk; |
161 | | |
162 | 879k | dsp->autocorrelate(X_low[k], phi); |
163 | | |
164 | 879k | dk = phi[2][1][0] * phi[1][0][0] - |
165 | 879k | (phi[1][1][0] * phi[1][1][0] + phi[1][1][1] * phi[1][1][1]) / 1.000001f; |
166 | | |
167 | 879k | if (!dk) { |
168 | 509k | alpha1[k][0] = 0; |
169 | 509k | alpha1[k][1] = 0; |
170 | 509k | } else { |
171 | 369k | float temp_real, temp_im; |
172 | 369k | temp_real = phi[0][0][0] * phi[1][1][0] - |
173 | 369k | phi[0][0][1] * phi[1][1][1] - |
174 | 369k | phi[0][1][0] * phi[1][0][0]; |
175 | 369k | temp_im = phi[0][0][0] * phi[1][1][1] + |
176 | 369k | phi[0][0][1] * phi[1][1][0] - |
177 | 369k | phi[0][1][1] * phi[1][0][0]; |
178 | | |
179 | 369k | alpha1[k][0] = temp_real / dk; |
180 | 369k | alpha1[k][1] = temp_im / dk; |
181 | 369k | } |
182 | | |
183 | 879k | if (!phi[1][0][0]) { |
184 | 502k | alpha0[k][0] = 0; |
185 | 502k | alpha0[k][1] = 0; |
186 | 502k | } else { |
187 | 376k | float temp_real, temp_im; |
188 | 376k | temp_real = phi[0][0][0] + alpha1[k][0] * phi[1][1][0] + |
189 | 376k | alpha1[k][1] * phi[1][1][1]; |
190 | 376k | temp_im = phi[0][0][1] + alpha1[k][1] * phi[1][1][0] - |
191 | 376k | alpha1[k][0] * phi[1][1][1]; |
192 | | |
193 | 376k | alpha0[k][0] = -temp_real / phi[1][0][0]; |
194 | 376k | alpha0[k][1] = -temp_im / phi[1][0][0]; |
195 | 376k | } |
196 | | |
197 | 879k | if (alpha1[k][0] * alpha1[k][0] + alpha1[k][1] * alpha1[k][1] >= 16.0f || |
198 | 875k | alpha0[k][0] * alpha0[k][0] + alpha0[k][1] * alpha0[k][1] >= 16.0f) { |
199 | 5.60k | alpha1[k][0] = 0; |
200 | 5.60k | alpha1[k][1] = 0; |
201 | 5.60k | alpha0[k][0] = 0; |
202 | 5.60k | alpha0[k][1] = 0; |
203 | 5.60k | } |
204 | 879k | } |
205 | 57.5k | } |
206 | | |
207 | | /// Chirp Factors (14496-3 sp04 p214) |
208 | | static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data) |
209 | 57.5k | { |
210 | 57.5k | int i; |
211 | 57.5k | float new_bw; |
212 | 57.5k | static const float bw_tab[] = { 0.0f, 0.75f, 0.9f, 0.98f }; |
213 | | |
214 | 181k | for (i = 0; i < sbr->n_q; i++) { |
215 | 123k | if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1) { |
216 | 22.4k | new_bw = 0.6f; |
217 | 22.4k | } else |
218 | 101k | new_bw = bw_tab[ch_data->bs_invf_mode[0][i]]; |
219 | | |
220 | 123k | if (new_bw < ch_data->bw_array[i]) { |
221 | 22.3k | new_bw = 0.75f * new_bw + 0.25f * ch_data->bw_array[i]; |
222 | 22.3k | } else |
223 | 101k | new_bw = 0.90625f * new_bw + 0.09375f * ch_data->bw_array[i]; |
224 | 123k | ch_data->bw_array[i] = new_bw < 0.015625f ? 0.0f : new_bw; |
225 | 123k | } |
226 | 57.5k | } |
227 | | |
228 | | /** |
229 | | * Calculation of levels of additional HF signal components (14496-3 sp04 p219) |
230 | | * and Calculation of gain (14496-3 sp04 p219) |
231 | | */ |
232 | | static void sbr_gain_calc(SpectralBandReplication *sbr, |
233 | | SBRData *ch_data, const int e_a[2]) |
234 | 57.5k | { |
235 | 57.5k | int e, k, m; |
236 | | // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) |
237 | 57.5k | static const float limgain[4] = { 0.70795, 1.0, 1.41254, 10000000000 }; |
238 | | |
239 | 160k | for (e = 0; e < ch_data->bs_num_env; e++) { |
240 | 102k | int delta = !((e == e_a[1]) || (e == e_a[0])); |
241 | 334k | for (k = 0; k < sbr->n_lim; k++) { |
242 | 231k | float gain_boost, gain_max; |
243 | 231k | float sum[2] = { 0.0f, 0.0f }; |
244 | 2.26M | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
245 | 2.03M | const float temp = sbr->e_origmapped[e][m] / (1.0f + sbr->q_mapped[e][m]); |
246 | 2.03M | sbr->q_m[e][m] = sqrtf(temp * sbr->q_mapped[e][m]); |
247 | 2.03M | sbr->s_m[e][m] = sqrtf(temp * ch_data->s_indexmapped[e + 1][m]); |
248 | 2.03M | if (!sbr->s_mapped[e][m]) { |
249 | 1.97M | sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] / |
250 | 1.97M | ((1.0f + sbr->e_curr[e][m]) * |
251 | 1.97M | (1.0f + sbr->q_mapped[e][m] * delta))); |
252 | 1.97M | } else { |
253 | 60.0k | sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] * sbr->q_mapped[e][m] / |
254 | 60.0k | ((1.0f + sbr->e_curr[e][m]) * |
255 | 60.0k | (1.0f + sbr->q_mapped[e][m]))); |
256 | 60.0k | } |
257 | 2.03M | sbr->gain[e][m] += FLT_MIN; |
258 | 2.03M | } |
259 | 2.26M | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
260 | 2.03M | sum[0] += sbr->e_origmapped[e][m]; |
261 | 2.03M | sum[1] += sbr->e_curr[e][m]; |
262 | 2.03M | } |
263 | 231k | gain_max = limgain[sbr->bs_limiter_gains] * sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); |
264 | 231k | gain_max = FFMIN(100000.f, gain_max); |
265 | 2.26M | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
266 | 2.03M | float q_m_max = sbr->q_m[e][m] * gain_max / sbr->gain[e][m]; |
267 | 2.03M | sbr->q_m[e][m] = FFMIN(sbr->q_m[e][m], q_m_max); |
268 | 2.03M | sbr->gain[e][m] = FFMIN(sbr->gain[e][m], gain_max); |
269 | 2.03M | } |
270 | 231k | sum[0] = sum[1] = 0.0f; |
271 | 2.26M | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
272 | 2.03M | sum[0] += sbr->e_origmapped[e][m]; |
273 | 2.03M | sum[1] += sbr->e_curr[e][m] * sbr->gain[e][m] * sbr->gain[e][m] |
274 | 2.03M | + sbr->s_m[e][m] * sbr->s_m[e][m] |
275 | 2.03M | + (delta && !sbr->s_m[e][m]) * sbr->q_m[e][m] * sbr->q_m[e][m]; |
276 | 2.03M | } |
277 | 231k | gain_boost = sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); |
278 | 231k | gain_boost = FFMIN(1.584893192f, gain_boost); |
279 | 2.26M | for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { |
280 | 2.03M | sbr->gain[e][m] *= gain_boost; |
281 | 2.03M | sbr->q_m[e][m] *= gain_boost; |
282 | 2.03M | sbr->s_m[e][m] *= gain_boost; |
283 | 2.03M | } |
284 | 231k | } |
285 | 102k | } |
286 | 57.5k | } |
287 | | |
288 | | /// Assembling HF Signals (14496-3 sp04 p220) |
289 | | static void sbr_hf_assemble(float Y1[38][64][2], |
290 | | const float X_high[64][40][2], |
291 | | SpectralBandReplication *sbr, SBRData *ch_data, |
292 | | const int e_a[2]) |
293 | 57.5k | { |
294 | 57.5k | int e, i, j, m; |
295 | 57.5k | const int h_SL = 4 * !sbr->bs_smoothing_mode; |
296 | 57.5k | const int kx = sbr->kx[1]; |
297 | 57.5k | const int m_max = sbr->m[1]; |
298 | 57.5k | static const float h_smooth[5] = { |
299 | 57.5k | 0.33333333333333, |
300 | 57.5k | 0.30150283239582, |
301 | 57.5k | 0.21816949906249, |
302 | 57.5k | 0.11516383427084, |
303 | 57.5k | 0.03183050093751, |
304 | 57.5k | }; |
305 | 57.5k | float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp; |
306 | 57.5k | int indexnoise = ch_data->f_indexnoise; |
307 | 57.5k | int indexsine = ch_data->f_indexsine; |
308 | | |
309 | 57.5k | if (sbr->reset) { |
310 | 78.2k | for (i = 0; i < h_SL; i++) { |
311 | 43.5k | memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0])); |
312 | 43.5k | memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0])); |
313 | 43.5k | } |
314 | 34.6k | } else if (h_SL) { |
315 | 57.6k | for (i = 0; i < 4; i++) { |
316 | 46.1k | memcpy(g_temp[i + 2 * ch_data->t_env[0]], |
317 | 46.1k | g_temp[i + 2 * ch_data->t_env_num_env_old], |
318 | 46.1k | sizeof(g_temp[0])); |
319 | 46.1k | memcpy(q_temp[i + 2 * ch_data->t_env[0]], |
320 | 46.1k | q_temp[i + 2 * ch_data->t_env_num_env_old], |
321 | 46.1k | sizeof(q_temp[0])); |
322 | 46.1k | } |
323 | 11.5k | } |
324 | | |
325 | 160k | for (e = 0; e < ch_data->bs_num_env; e++) { |
326 | 1.97M | for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { |
327 | 1.86M | memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0])); |
328 | 1.86M | memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0])); |
329 | 1.86M | } |
330 | 102k | } |
331 | | |
332 | 160k | for (e = 0; e < ch_data->bs_num_env; e++) { |
333 | 1.97M | for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { |
334 | 1.86M | LOCAL_ALIGNED_16(float, g_filt_tab, [48]); |
335 | 1.86M | LOCAL_ALIGNED_16(float, q_filt_tab, [48]); |
336 | 1.86M | float *g_filt, *q_filt; |
337 | | |
338 | 1.86M | if (h_SL && e != e_a[0] && e != e_a[1]) { |
339 | 597k | g_filt = g_filt_tab; |
340 | 597k | q_filt = q_filt_tab; |
341 | 16.0M | for (m = 0; m < m_max; m++) { |
342 | 15.4M | const int idx1 = i + h_SL; |
343 | 15.4M | g_filt[m] = 0.0f; |
344 | 15.4M | q_filt[m] = 0.0f; |
345 | 92.6M | for (j = 0; j <= h_SL; j++) { |
346 | 77.1M | g_filt[m] += g_temp[idx1 - j][m] * h_smooth[j]; |
347 | 77.1M | q_filt[m] += q_temp[idx1 - j][m] * h_smooth[j]; |
348 | 77.1M | } |
349 | 15.4M | } |
350 | 1.27M | } else { |
351 | 1.27M | g_filt = g_temp[i + h_SL]; |
352 | 1.27M | q_filt = q_temp[i]; |
353 | 1.27M | } |
354 | | |
355 | 1.86M | sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max, |
356 | 1.86M | i + ENVELOPE_ADJUSTMENT_OFFSET); |
357 | | |
358 | 1.86M | if (e != e_a[0] && e != e_a[1]) { |
359 | 1.61M | sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e], |
360 | 1.61M | q_filt, indexnoise, |
361 | 1.61M | kx, m_max); |
362 | 1.61M | } else { |
363 | 253k | int idx = indexsine&1; |
364 | 253k | int A = (1-((indexsine+(kx & 1))&2)); |
365 | 253k | int B = (A^(-idx)) + idx; |
366 | 253k | float *out = &Y1[i][kx][idx]; |
367 | 253k | float *in = sbr->s_m[e]; |
368 | 3.11M | for (m = 0; m+1 < m_max; m+=2) { |
369 | 2.86M | out[2*m ] += in[m ] * A; |
370 | 2.86M | out[2*m+2] += in[m+1] * B; |
371 | 2.86M | } |
372 | 253k | if(m_max&1) |
373 | 215k | out[2*m ] += in[m ] * A; |
374 | 253k | } |
375 | 1.86M | indexnoise = (indexnoise + m_max) & 0x1ff; |
376 | 1.86M | indexsine = (indexsine + 1) & 3; |
377 | 1.86M | } |
378 | 102k | } |
379 | 57.5k | ch_data->f_indexnoise = indexnoise; |
380 | 57.5k | ch_data->f_indexsine = indexsine; |
381 | 57.5k | } |
382 | | |
383 | | #include "aacsbr_template.c" |