2 * MPEG-4 Parametric Stereo decoding functions
3 * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * Note: Rounding-to-nearest used unless otherwise stated
26 #include "libavutil/common.h"
27 #include "libavutil/mathematics.h"
28 #include "libavutil/mem_internal.h"
31 #include "aacps_fixed_tablegen.h"
33 #include "libavutil/internal.h"
34 #include "aacps_tablegen.h"
35 #endif /* USE_FIXED */
37 static const INTFLOAT g1_Q2
[] = {
38 Q31(0.0f
), Q31(0.01899487526049f
), Q31(0.0f
), Q31(-0.07293139167538f
),
39 Q31(0.0f
), Q31(0.30596630545168f
), Q31(0.5f
)
42 static void ipdopd_reset(int8_t *ipd_hist
, int8_t *opd_hist
)
45 for (i
= 0; i
< PS_MAX_NR_IPDOPD
; i
++) {
51 /** Split one subband into 2 subsubbands with a symmetric real filter.
52 * The filter must have its non-center even coefficients equal to zero. */
53 static void hybrid2_re(INTFLOAT (*in
)[2], INTFLOAT (*out
)[32][2],
54 const INTFLOAT filter
[7], int len
, int reverse
)
57 for (i
= 0; i
< len
; i
++, in
++) {
58 INT64FLOAT re_in
= AAC_MUL31(filter
[6], in
[6][0]); //real inphase
59 INT64FLOAT re_op
= 0.0f
; //real out of phase
60 INT64FLOAT im_in
= AAC_MUL31(filter
[6], in
[6][1]); //imag inphase
61 INT64FLOAT im_op
= 0.0f
; //imag out of phase
62 for (j
= 0; j
< 6; j
+= 2) {
63 re_op
+= (INT64FLOAT
)filter
[j
+1] * (in
[j
+1][0] + in
[12-j
-1][0]);
64 im_op
+= (INT64FLOAT
)filter
[j
+1] * (in
[j
+1][1] + in
[12-j
-1][1]);
68 re_op
= (re_op
+ 0x40000000) >> 31;
69 im_op
= (im_op
+ 0x40000000) >> 31;
70 #endif /* USE_FIXED */
72 out
[ reverse
][i
][0] = (INTFLOAT
)(re_in
+ re_op
);
73 out
[ reverse
][i
][1] = (INTFLOAT
)(im_in
+ im_op
);
74 out
[!reverse
][i
][0] = (INTFLOAT
)(re_in
- re_op
);
75 out
[!reverse
][i
][1] = (INTFLOAT
)(im_in
- im_op
);
79 /** Split one subband into 6 subsubbands with a complex filter */
80 static void hybrid6_cx(PSDSPContext
*dsp
, INTFLOAT (*in
)[2], INTFLOAT (*out
)[32][2],
81 TABLE_CONST
INTFLOAT (*filter
)[8][2], int len
)
85 LOCAL_ALIGNED_16(INTFLOAT
, temp
, [8], [2]);
87 for (i
= 0; i
< len
; i
++, in
++) {
88 dsp
->hybrid_analysis(temp
, in
, (const INTFLOAT (*)[8][2]) filter
, 1, N
);
89 out
[0][i
][0] = temp
[6][0];
90 out
[0][i
][1] = temp
[6][1];
91 out
[1][i
][0] = temp
[7][0];
92 out
[1][i
][1] = temp
[7][1];
93 out
[2][i
][0] = temp
[0][0];
94 out
[2][i
][1] = temp
[0][1];
95 out
[3][i
][0] = temp
[1][0];
96 out
[3][i
][1] = temp
[1][1];
97 out
[4][i
][0] = temp
[2][0] + temp
[5][0];
98 out
[4][i
][1] = temp
[2][1] + temp
[5][1];
99 out
[5][i
][0] = temp
[3][0] + temp
[4][0];
100 out
[5][i
][1] = temp
[3][1] + temp
[4][1];
104 static void hybrid4_8_12_cx(PSDSPContext
*dsp
,
105 INTFLOAT (*in
)[2], INTFLOAT (*out
)[32][2],
106 TABLE_CONST
INTFLOAT (*filter
)[8][2], int N
, int len
)
110 for (i
= 0; i
< len
; i
++, in
++) {
111 dsp
->hybrid_analysis(out
[0] + i
, in
, (const INTFLOAT (*)[8][2]) filter
, 32, N
);
115 static void hybrid_analysis(PSDSPContext
*dsp
, INTFLOAT out
[91][32][2],
116 INTFLOAT in
[5][44][2], INTFLOAT L
[2][38][64],
120 for (i
= 0; i
< 5; i
++) {
121 for (j
= 0; j
< 38; j
++) {
122 in
[i
][j
+6][0] = L
[0][j
][i
];
123 in
[i
][j
+6][1] = L
[1][j
][i
];
127 hybrid4_8_12_cx(dsp
, in
[0], out
, f34_0_12
, 12, len
);
128 hybrid4_8_12_cx(dsp
, in
[1], out
+12, f34_1_8
, 8, len
);
129 hybrid4_8_12_cx(dsp
, in
[2], out
+20, f34_2_4
, 4, len
);
130 hybrid4_8_12_cx(dsp
, in
[3], out
+24, f34_2_4
, 4, len
);
131 hybrid4_8_12_cx(dsp
, in
[4], out
+28, f34_2_4
, 4, len
);
132 dsp
->hybrid_analysis_ileave(out
+ 27, L
, 5, len
);
134 hybrid6_cx(dsp
, in
[0], out
, f20_0_8
, len
);
135 hybrid2_re(in
[1], out
+6, g1_Q2
, len
, 1);
136 hybrid2_re(in
[2], out
+8, g1_Q2
, len
, 0);
137 dsp
->hybrid_analysis_ileave(out
+ 7, L
, 3, len
);
140 for (i
= 0; i
< 5; i
++) {
141 memcpy(in
[i
], in
[i
]+32, 6 * sizeof(in
[i
][0]));
145 static void hybrid_synthesis(PSDSPContext
*dsp
, INTFLOAT out
[2][38][64],
146 INTFLOAT in
[91][32][2], int is34
, int len
)
150 for (n
= 0; n
< len
; n
++) {
151 memset(out
[0][n
], 0, 5*sizeof(out
[0][n
][0]));
152 memset(out
[1][n
], 0, 5*sizeof(out
[1][n
][0]));
153 for (i
= 0; i
< 12; i
++) {
154 out
[0][n
][0] += (UINTFLOAT
)in
[ i
][n
][0];
155 out
[1][n
][0] += (UINTFLOAT
)in
[ i
][n
][1];
157 for (i
= 0; i
< 8; i
++) {
158 out
[0][n
][1] += (UINTFLOAT
)in
[12+i
][n
][0];
159 out
[1][n
][1] += (UINTFLOAT
)in
[12+i
][n
][1];
161 for (i
= 0; i
< 4; i
++) {
162 out
[0][n
][2] += (UINTFLOAT
)in
[20+i
][n
][0];
163 out
[1][n
][2] += (UINTFLOAT
)in
[20+i
][n
][1];
164 out
[0][n
][3] += (UINTFLOAT
)in
[24+i
][n
][0];
165 out
[1][n
][3] += (UINTFLOAT
)in
[24+i
][n
][1];
166 out
[0][n
][4] += (UINTFLOAT
)in
[28+i
][n
][0];
167 out
[1][n
][4] += (UINTFLOAT
)in
[28+i
][n
][1];
170 dsp
->hybrid_synthesis_deint(out
, in
+ 27, 5, len
);
172 for (n
= 0; n
< len
; n
++) {
173 out
[0][n
][0] = (UINTFLOAT
)in
[0][n
][0] + in
[1][n
][0] + in
[2][n
][0] +
174 (UINTFLOAT
)in
[3][n
][0] + in
[4][n
][0] + in
[5][n
][0];
175 out
[1][n
][0] = (UINTFLOAT
)in
[0][n
][1] + in
[1][n
][1] + in
[2][n
][1] +
176 (UINTFLOAT
)in
[3][n
][1] + in
[4][n
][1] + in
[5][n
][1];
177 out
[0][n
][1] = (UINTFLOAT
)in
[6][n
][0] + in
[7][n
][0];
178 out
[1][n
][1] = (UINTFLOAT
)in
[6][n
][1] + in
[7][n
][1];
179 out
[0][n
][2] = (UINTFLOAT
)in
[8][n
][0] + in
[9][n
][0];
180 out
[1][n
][2] = (UINTFLOAT
)in
[8][n
][1] + in
[9][n
][1];
182 dsp
->hybrid_synthesis_deint(out
, in
+ 7, 3, len
);
186 /// All-pass filter decay slope
187 #define DECAY_SLOPE Q30(0.05f)
188 /// Number of frequency bands that can be addressed by the parameter index, b(k)
189 static const int NR_PAR_BANDS
[] = { 20, 34 };
190 static const int NR_IPDOPD_BANDS
[] = { 11, 17 };
191 /// Number of frequency bands that can be addressed by the sub subband index, k
192 static const int NR_BANDS
[] = { 71, 91 };
193 /// Start frequency band for the all-pass filter decay slope
194 static const int DECAY_CUTOFF
[] = { 10, 32 };
195 /// Number of all-pass filer bands
196 static const int NR_ALLPASS_BANDS
[] = { 30, 50 };
197 /// First stereo band using the short one sample delay
198 static const int SHORT_DELAY_BAND
[] = { 42, 62 };
201 static void map_idx_10_to_20(int8_t *par_mapped
, const int8_t *par
, int full
)
210 for (; b
>= 0; b
--) {
211 par_mapped
[2*b
+1] = par_mapped
[2*b
] = par
[b
];
215 static void map_idx_34_to_20(int8_t *par_mapped
, const int8_t *par
, int full
)
217 par_mapped
[ 0] = (2*par
[ 0] + par
[ 1]) / 3;
218 par_mapped
[ 1] = ( par
[ 1] + 2*par
[ 2]) / 3;
219 par_mapped
[ 2] = (2*par
[ 3] + par
[ 4]) / 3;
220 par_mapped
[ 3] = ( par
[ 4] + 2*par
[ 5]) / 3;
221 par_mapped
[ 4] = ( par
[ 6] + par
[ 7]) / 2;
222 par_mapped
[ 5] = ( par
[ 8] + par
[ 9]) / 2;
223 par_mapped
[ 6] = par
[10];
224 par_mapped
[ 7] = par
[11];
225 par_mapped
[ 8] = ( par
[12] + par
[13]) / 2;
226 par_mapped
[ 9] = ( par
[14] + par
[15]) / 2;
227 par_mapped
[10] = par
[16];
229 par_mapped
[11] = par
[17];
230 par_mapped
[12] = par
[18];
231 par_mapped
[13] = par
[19];
232 par_mapped
[14] = ( par
[20] + par
[21]) / 2;
233 par_mapped
[15] = ( par
[22] + par
[23]) / 2;
234 par_mapped
[16] = ( par
[24] + par
[25]) / 2;
235 par_mapped
[17] = ( par
[26] + par
[27]) / 2;
236 par_mapped
[18] = ( par
[28] + par
[29] + par
[30] + par
[31]) / 4;
237 par_mapped
[19] = ( par
[32] + par
[33]) / 2;
241 static void map_val_34_to_20(INTFLOAT par
[PS_MAX_NR_IIDICC
])
244 par
[ 0] = (int)(((int64_t)(par
[ 0] + (unsigned)(par
[ 1]>>1)) * 1431655765 + \
246 par
[ 1] = (int)(((int64_t)((par
[ 1]>>1) + (unsigned)par
[ 2]) * 1431655765 + \
248 par
[ 2] = (int)(((int64_t)(par
[ 3] + (unsigned)(par
[ 4]>>1)) * 1431655765 + \
250 par
[ 3] = (int)(((int64_t)((par
[ 4]>>1) + (unsigned)par
[ 5]) * 1431655765 + \
253 par
[ 0] = (2*par
[ 0] + par
[ 1]) * 0.33333333f
;
254 par
[ 1] = ( par
[ 1] + 2*par
[ 2]) * 0.33333333f
;
255 par
[ 2] = (2*par
[ 3] + par
[ 4]) * 0.33333333f
;
256 par
[ 3] = ( par
[ 4] + 2*par
[ 5]) * 0.33333333f
;
257 #endif /* USE_FIXED */
258 par
[ 4] = AAC_HALF_SUM(par
[ 6], par
[ 7]);
259 par
[ 5] = AAC_HALF_SUM(par
[ 8], par
[ 9]);
262 par
[ 8] = AAC_HALF_SUM(par
[12], par
[13]);
263 par
[ 9] = AAC_HALF_SUM(par
[14], par
[15]);
268 par
[14] = AAC_HALF_SUM(par
[20], par
[21]);
269 par
[15] = AAC_HALF_SUM(par
[22], par
[23]);
270 par
[16] = AAC_HALF_SUM(par
[24], par
[25]);
271 par
[17] = AAC_HALF_SUM(par
[26], par
[27]);
273 par
[18] = (((par
[28]+2)>>2) + ((par
[29]+2)>>2) + ((par
[30]+2)>>2) + ((par
[31]+2)>>2));
275 par
[18] = ( par
[28] + par
[29] + par
[30] + par
[31]) * 0.25f
;
276 #endif /* USE_FIXED */
277 par
[19] = AAC_HALF_SUM(par
[32], par
[33]);
280 static void map_idx_10_to_34(int8_t *par_mapped
, const int8_t *par
, int full
)
283 par_mapped
[33] = par
[9];
284 par_mapped
[32] = par
[9];
285 par_mapped
[31] = par
[9];
286 par_mapped
[30] = par
[9];
287 par_mapped
[29] = par
[9];
288 par_mapped
[28] = par
[9];
289 par_mapped
[27] = par
[8];
290 par_mapped
[26] = par
[8];
291 par_mapped
[25] = par
[8];
292 par_mapped
[24] = par
[8];
293 par_mapped
[23] = par
[7];
294 par_mapped
[22] = par
[7];
295 par_mapped
[21] = par
[7];
296 par_mapped
[20] = par
[7];
297 par_mapped
[19] = par
[6];
298 par_mapped
[18] = par
[6];
299 par_mapped
[17] = par
[5];
300 par_mapped
[16] = par
[5];
304 par_mapped
[15] = par
[4];
305 par_mapped
[14] = par
[4];
306 par_mapped
[13] = par
[4];
307 par_mapped
[12] = par
[4];
308 par_mapped
[11] = par
[3];
309 par_mapped
[10] = par
[3];
310 par_mapped
[ 9] = par
[2];
311 par_mapped
[ 8] = par
[2];
312 par_mapped
[ 7] = par
[2];
313 par_mapped
[ 6] = par
[2];
314 par_mapped
[ 5] = par
[1];
315 par_mapped
[ 4] = par
[1];
316 par_mapped
[ 3] = par
[1];
317 par_mapped
[ 2] = par
[0];
318 par_mapped
[ 1] = par
[0];
319 par_mapped
[ 0] = par
[0];
322 static void map_idx_20_to_34(int8_t *par_mapped
, const int8_t *par
, int full
)
325 par_mapped
[33] = par
[19];
326 par_mapped
[32] = par
[19];
327 par_mapped
[31] = par
[18];
328 par_mapped
[30] = par
[18];
329 par_mapped
[29] = par
[18];
330 par_mapped
[28] = par
[18];
331 par_mapped
[27] = par
[17];
332 par_mapped
[26] = par
[17];
333 par_mapped
[25] = par
[16];
334 par_mapped
[24] = par
[16];
335 par_mapped
[23] = par
[15];
336 par_mapped
[22] = par
[15];
337 par_mapped
[21] = par
[14];
338 par_mapped
[20] = par
[14];
339 par_mapped
[19] = par
[13];
340 par_mapped
[18] = par
[12];
341 par_mapped
[17] = par
[11];
343 par_mapped
[16] = par
[10];
344 par_mapped
[15] = par
[ 9];
345 par_mapped
[14] = par
[ 9];
346 par_mapped
[13] = par
[ 8];
347 par_mapped
[12] = par
[ 8];
348 par_mapped
[11] = par
[ 7];
349 par_mapped
[10] = par
[ 6];
350 par_mapped
[ 9] = par
[ 5];
351 par_mapped
[ 8] = par
[ 5];
352 par_mapped
[ 7] = par
[ 4];
353 par_mapped
[ 6] = par
[ 4];
354 par_mapped
[ 5] = par
[ 3];
355 par_mapped
[ 4] = (par
[ 2] + par
[ 3]) / 2;
356 par_mapped
[ 3] = par
[ 2];
357 par_mapped
[ 2] = par
[ 1];
358 par_mapped
[ 1] = (par
[ 0] + par
[ 1]) / 2;
359 par_mapped
[ 0] = par
[ 0];
362 static void map_val_20_to_34(INTFLOAT par
[PS_MAX_NR_IIDICC
])
393 par
[ 4] = AAC_HALF_SUM(par
[ 2], par
[ 3]);
396 par
[ 1] = AAC_HALF_SUM(par
[ 0], par
[ 1]);
399 static void decorrelation(PSContext
*ps
, INTFLOAT (*out
)[32][2], const INTFLOAT (*s
)[32][2], int is34
)
401 LOCAL_ALIGNED_16(INTFLOAT
, power
, [34], [PS_QMF_TIME_SLOTS
]);
402 LOCAL_ALIGNED_16(INTFLOAT
, transient_gain
, [34], [PS_QMF_TIME_SLOTS
]);
403 INTFLOAT
*peak_decay_nrg
= ps
->peak_decay_nrg
;
404 INTFLOAT
*power_smooth
= ps
->power_smooth
;
405 INTFLOAT
*peak_decay_diff_smooth
= ps
->peak_decay_diff_smooth
;
406 INTFLOAT (*delay
)[PS_QMF_TIME_SLOTS
+ PS_MAX_DELAY
][2] = ps
->delay
;
407 INTFLOAT (*ap_delay
)[PS_AP_LINKS
][PS_QMF_TIME_SLOTS
+ PS_MAX_AP_DELAY
][2] = ps
->ap_delay
;
409 const float transient_impact
= 1.5f
;
410 const float a_smooth
= 0.25f
; ///< Smoothing coefficient
411 #endif /* USE_FIXED */
412 const int8_t *const k_to_i
= is34
? ff_k_to_i_34
: ff_k_to_i_20
;
415 const INTFLOAT peak_decay_factor
= Q31(0.76592833836465f
);
417 memset(power
, 0, 34 * sizeof(*power
));
419 if (is34
!= ps
->common
.is34bands_old
) {
420 memset(ps
->peak_decay_nrg
, 0, sizeof(ps
->peak_decay_nrg
));
421 memset(ps
->power_smooth
, 0, sizeof(ps
->power_smooth
));
422 memset(ps
->peak_decay_diff_smooth
, 0, sizeof(ps
->peak_decay_diff_smooth
));
423 memset(ps
->delay
, 0, sizeof(ps
->delay
));
424 memset(ps
->ap_delay
, 0, sizeof(ps
->ap_delay
));
427 for (k
= 0; k
< NR_BANDS
[is34
]; k
++) {
429 ps
->dsp
.add_squares(power
[i
], s
[k
], nL
- n0
);
432 //Transient detection
434 for (i
= 0; i
< NR_PAR_BANDS
[is34
]; i
++) {
435 for (n
= n0
; n
< nL
; n
++) {
437 decayed_peak
= (int)(((int64_t)peak_decay_factor
* \
438 peak_decay_nrg
[i
] + 0x40000000) >> 31);
439 peak_decay_nrg
[i
] = FFMAX(decayed_peak
, power
[i
][n
]);
440 power_smooth
[i
] += (power
[i
][n
] + 2LL - power_smooth
[i
]) >> 2;
441 peak_decay_diff_smooth
[i
] += (peak_decay_nrg
[i
] + 2LL - power
[i
][n
] - \
442 peak_decay_diff_smooth
[i
]) >> 2;
444 if (peak_decay_diff_smooth
[i
]) {
445 transient_gain
[i
][n
] = FFMIN(power_smooth
[i
]*43691LL / peak_decay_diff_smooth
[i
], 1<<16);
447 transient_gain
[i
][n
] = 1 << 16;
451 for (i
= 0; i
< NR_PAR_BANDS
[is34
]; i
++) {
452 for (n
= n0
; n
< nL
; n
++) {
453 float decayed_peak
= peak_decay_factor
* peak_decay_nrg
[i
];
455 peak_decay_nrg
[i
] = FFMAX(decayed_peak
, power
[i
][n
]);
456 power_smooth
[i
] += a_smooth
* (power
[i
][n
] - power_smooth
[i
]);
457 peak_decay_diff_smooth
[i
] += a_smooth
* (peak_decay_nrg
[i
] - power
[i
][n
] - peak_decay_diff_smooth
[i
]);
458 denom
= transient_impact
* peak_decay_diff_smooth
[i
];
459 transient_gain
[i
][n
] = (denom
> power_smooth
[i
]) ?
460 power_smooth
[i
] / denom
: 1.0f
;
464 #endif /* USE_FIXED */
465 //Decorrelation and transient reduction
468 // | | Q_fract_allpass[k][m]*z^-link_delay[m] - a[m]*g_decay_slope[k]
469 //H[k][z] = z^-2 * phi_fract[k] * | | ----------------------------------------------------------------
470 // | | 1 - a[m]*g_decay_slope[k]*Q_fract_allpass[k][m]*z^-link_delay[m]
472 //d[k][z] (out) = transient_gain_mapped[k][z] * H[k][z] * s[k][z]
473 for (k
= 0; k
< NR_ALLPASS_BANDS
[is34
]; k
++) {
478 if (k
- DECAY_CUTOFF
[is34
] <= 0) {
479 g_decay_slope
= 1 << 30;
481 else if (k
- DECAY_CUTOFF
[is34
] >= 20) {
485 g_decay_slope
= (1 << 30) - DECAY_SLOPE
* (k
- DECAY_CUTOFF
[is34
]);
488 float g_decay_slope
= 1.f
- DECAY_SLOPE
* (k
- DECAY_CUTOFF
[is34
]);
489 g_decay_slope
= av_clipf(g_decay_slope
, 0.f
, 1.f
);
490 #endif /* USE_FIXED */
491 memcpy(delay
[k
], delay
[k
]+nL
, PS_MAX_DELAY
*sizeof(delay
[k
][0]));
492 memcpy(delay
[k
]+PS_MAX_DELAY
, s
[k
], numQMFSlots
*sizeof(delay
[k
][0]));
493 for (m
= 0; m
< PS_AP_LINKS
; m
++) {
494 memcpy(ap_delay
[k
][m
], ap_delay
[k
][m
]+numQMFSlots
, 5*sizeof(ap_delay
[k
][m
][0]));
496 ps
->dsp
.decorrelate(out
[k
], delay
[k
] + PS_MAX_DELAY
- 2, ap_delay
[k
],
498 (const INTFLOAT (*)[2]) Q_fract_allpass
[is34
][k
],
499 transient_gain
[b
], g_decay_slope
, nL
- n0
);
501 for (; k
< SHORT_DELAY_BAND
[is34
]; k
++) {
503 memcpy(delay
[k
], delay
[k
]+nL
, PS_MAX_DELAY
*sizeof(delay
[k
][0]));
504 memcpy(delay
[k
]+PS_MAX_DELAY
, s
[k
], numQMFSlots
*sizeof(delay
[k
][0]));
506 ps
->dsp
.mul_pair_single(out
[k
], delay
[k
] + PS_MAX_DELAY
- 14,
507 transient_gain
[i
], nL
- n0
);
509 for (; k
< NR_BANDS
[is34
]; k
++) {
511 memcpy(delay
[k
], delay
[k
]+nL
, PS_MAX_DELAY
*sizeof(delay
[k
][0]));
512 memcpy(delay
[k
]+PS_MAX_DELAY
, s
[k
], numQMFSlots
*sizeof(delay
[k
][0]));
514 ps
->dsp
.mul_pair_single(out
[k
], delay
[k
] + PS_MAX_DELAY
- 1,
515 transient_gain
[i
], nL
- n0
);
519 static void remap34(int8_t (**p_par_mapped
)[PS_MAX_NR_IIDICC
],
520 int8_t (*par
)[PS_MAX_NR_IIDICC
],
521 int num_par
, int num_env
, int full
)
523 int8_t (*par_mapped
)[PS_MAX_NR_IIDICC
] = *p_par_mapped
;
525 if (num_par
== 20 || num_par
== 11) {
526 for (e
= 0; e
< num_env
; e
++) {
527 map_idx_20_to_34(par_mapped
[e
], par
[e
], full
);
529 } else if (num_par
== 10 || num_par
== 5) {
530 for (e
= 0; e
< num_env
; e
++) {
531 map_idx_10_to_34(par_mapped
[e
], par
[e
], full
);
538 static void remap20(int8_t (**p_par_mapped
)[PS_MAX_NR_IIDICC
],
539 int8_t (*par
)[PS_MAX_NR_IIDICC
],
540 int num_par
, int num_env
, int full
)
542 int8_t (*par_mapped
)[PS_MAX_NR_IIDICC
] = *p_par_mapped
;
544 if (num_par
== 34 || num_par
== 17) {
545 for (e
= 0; e
< num_env
; e
++) {
546 map_idx_34_to_20(par_mapped
[e
], par
[e
], full
);
548 } else if (num_par
== 10 || num_par
== 5) {
549 for (e
= 0; e
< num_env
; e
++) {
550 map_idx_10_to_20(par_mapped
[e
], par
[e
], full
);
557 static void stereo_processing(PSContext
*ps
, INTFLOAT (*l
)[32][2], INTFLOAT (*r
)[32][2], int is34
)
561 PSCommonContext
*const ps2
= &ps
->common
;
562 INTFLOAT (*H11
)[PS_MAX_NUM_ENV
+1][PS_MAX_NR_IIDICC
] = ps
->H11
;
563 INTFLOAT (*H12
)[PS_MAX_NUM_ENV
+1][PS_MAX_NR_IIDICC
] = ps
->H12
;
564 INTFLOAT (*H21
)[PS_MAX_NUM_ENV
+1][PS_MAX_NR_IIDICC
] = ps
->H21
;
565 INTFLOAT (*H22
)[PS_MAX_NUM_ENV
+1][PS_MAX_NR_IIDICC
] = ps
->H22
;
566 int8_t *opd_hist
= ps
->opd_hist
;
567 int8_t *ipd_hist
= ps
->ipd_hist
;
568 int8_t iid_mapped_buf
[PS_MAX_NUM_ENV
][PS_MAX_NR_IIDICC
];
569 int8_t icc_mapped_buf
[PS_MAX_NUM_ENV
][PS_MAX_NR_IIDICC
];
570 int8_t ipd_mapped_buf
[PS_MAX_NUM_ENV
][PS_MAX_NR_IIDICC
];
571 int8_t opd_mapped_buf
[PS_MAX_NUM_ENV
][PS_MAX_NR_IIDICC
];
572 int8_t (*iid_mapped
)[PS_MAX_NR_IIDICC
] = iid_mapped_buf
;
573 int8_t (*icc_mapped
)[PS_MAX_NR_IIDICC
] = icc_mapped_buf
;
574 int8_t (*ipd_mapped
)[PS_MAX_NR_IIDICC
] = ipd_mapped_buf
;
575 int8_t (*opd_mapped
)[PS_MAX_NR_IIDICC
] = opd_mapped_buf
;
576 const int8_t *const k_to_i
= is34
? ff_k_to_i_34
: ff_k_to_i_20
;
577 TABLE_CONST
INTFLOAT (*H_LUT
)[8][4] = (PS_BASELINE
|| ps2
->icc_mode
< 3) ? HA
: HB
;
580 if (ps2
->num_env_old
) {
581 memcpy(H11
[0][0], H11
[0][ps2
->num_env_old
], sizeof(H11
[0][0]));
582 memcpy(H11
[1][0], H11
[1][ps2
->num_env_old
], sizeof(H11
[1][0]));
583 memcpy(H12
[0][0], H12
[0][ps2
->num_env_old
], sizeof(H12
[0][0]));
584 memcpy(H12
[1][0], H12
[1][ps2
->num_env_old
], sizeof(H12
[1][0]));
585 memcpy(H21
[0][0], H21
[0][ps2
->num_env_old
], sizeof(H21
[0][0]));
586 memcpy(H21
[1][0], H21
[1][ps2
->num_env_old
], sizeof(H21
[1][0]));
587 memcpy(H22
[0][0], H22
[0][ps2
->num_env_old
], sizeof(H22
[0][0]));
588 memcpy(H22
[1][0], H22
[1][ps2
->num_env_old
], sizeof(H22
[1][0]));
592 remap34(&iid_mapped
, ps2
->iid_par
, ps2
->nr_iid_par
, ps2
->num_env
, 1);
593 remap34(&icc_mapped
, ps2
->icc_par
, ps2
->nr_icc_par
, ps2
->num_env
, 1);
594 if (ps2
->enable_ipdopd
) {
595 remap34(&ipd_mapped
, ps2
->ipd_par
, ps2
->nr_ipdopd_par
, ps2
->num_env
, 0);
596 remap34(&opd_mapped
, ps2
->opd_par
, ps2
->nr_ipdopd_par
, ps2
->num_env
, 0);
598 if (!ps2
->is34bands_old
) {
599 map_val_20_to_34(H11
[0][0]);
600 map_val_20_to_34(H11
[1][0]);
601 map_val_20_to_34(H12
[0][0]);
602 map_val_20_to_34(H12
[1][0]);
603 map_val_20_to_34(H21
[0][0]);
604 map_val_20_to_34(H21
[1][0]);
605 map_val_20_to_34(H22
[0][0]);
606 map_val_20_to_34(H22
[1][0]);
607 ipdopd_reset(ipd_hist
, opd_hist
);
610 remap20(&iid_mapped
, ps2
->iid_par
, ps2
->nr_iid_par
, ps2
->num_env
, 1);
611 remap20(&icc_mapped
, ps2
->icc_par
, ps2
->nr_icc_par
, ps2
->num_env
, 1);
612 if (ps2
->enable_ipdopd
) {
613 remap20(&ipd_mapped
, ps2
->ipd_par
, ps2
->nr_ipdopd_par
, ps2
->num_env
, 0);
614 remap20(&opd_mapped
, ps2
->opd_par
, ps2
->nr_ipdopd_par
, ps2
->num_env
, 0);
616 if (ps2
->is34bands_old
) {
617 map_val_34_to_20(H11
[0][0]);
618 map_val_34_to_20(H11
[1][0]);
619 map_val_34_to_20(H12
[0][0]);
620 map_val_34_to_20(H12
[1][0]);
621 map_val_34_to_20(H21
[0][0]);
622 map_val_34_to_20(H21
[1][0]);
623 map_val_34_to_20(H22
[0][0]);
624 map_val_34_to_20(H22
[1][0]);
625 ipdopd_reset(ipd_hist
, opd_hist
);
630 for (e
= 0; e
< ps2
->num_env
; e
++) {
631 for (b
= 0; b
< NR_PAR_BANDS
[is34
]; b
++) {
632 INTFLOAT h11
, h12
, h21
, h22
;
633 h11
= H_LUT
[iid_mapped
[e
][b
] + 7 + 23 * ps2
->iid_quant
][icc_mapped
[e
][b
]][0];
634 h12
= H_LUT
[iid_mapped
[e
][b
] + 7 + 23 * ps2
->iid_quant
][icc_mapped
[e
][b
]][1];
635 h21
= H_LUT
[iid_mapped
[e
][b
] + 7 + 23 * ps2
->iid_quant
][icc_mapped
[e
][b
]][2];
636 h22
= H_LUT
[iid_mapped
[e
][b
] + 7 + 23 * ps2
->iid_quant
][icc_mapped
[e
][b
]][3];
638 if (!PS_BASELINE
&& ps2
->enable_ipdopd
&& b
< NR_IPDOPD_BANDS
[is34
]) {
639 //The spec say says to only run this smoother when enable_ipdopd
640 //is set but the reference decoder appears to run it constantly
641 INTFLOAT h11i
, h12i
, h21i
, h22i
;
642 INTFLOAT ipd_adj_re
, ipd_adj_im
;
643 int opd_idx
= opd_hist
[b
] * 8 + opd_mapped
[e
][b
];
644 int ipd_idx
= ipd_hist
[b
] * 8 + ipd_mapped
[e
][b
];
645 INTFLOAT opd_re
= pd_re_smooth
[opd_idx
];
646 INTFLOAT opd_im
= pd_im_smooth
[opd_idx
];
647 INTFLOAT ipd_re
= pd_re_smooth
[ipd_idx
];
648 INTFLOAT ipd_im
= pd_im_smooth
[ipd_idx
];
649 opd_hist
[b
] = opd_idx
& 0x3F;
650 ipd_hist
[b
] = ipd_idx
& 0x3F;
652 ipd_adj_re
= AAC_MADD30(opd_re
, ipd_re
, opd_im
, ipd_im
);
653 ipd_adj_im
= AAC_MSUB30(opd_im
, ipd_re
, opd_re
, ipd_im
);
654 h11i
= AAC_MUL30(h11
, opd_im
);
655 h11
= AAC_MUL30(h11
, opd_re
);
656 h12i
= AAC_MUL30(h12
, ipd_adj_im
);
657 h12
= AAC_MUL30(h12
, ipd_adj_re
);
658 h21i
= AAC_MUL30(h21
, opd_im
);
659 h21
= AAC_MUL30(h21
, opd_re
);
660 h22i
= AAC_MUL30(h22
, ipd_adj_im
);
661 h22
= AAC_MUL30(h22
, ipd_adj_re
);
662 H11
[1][e
+1][b
] = h11i
;
663 H12
[1][e
+1][b
] = h12i
;
664 H21
[1][e
+1][b
] = h21i
;
665 H22
[1][e
+1][b
] = h22i
;
667 H11
[0][e
+1][b
] = h11
;
668 H12
[0][e
+1][b
] = h12
;
669 H21
[0][e
+1][b
] = h21
;
670 H22
[0][e
+1][b
] = h22
;
672 for (k
= 0; k
< NR_BANDS
[is34
]; k
++) {
673 LOCAL_ALIGNED_16(INTFLOAT
, h
, [2], [4]);
674 LOCAL_ALIGNED_16(INTFLOAT
, h_step
, [2], [4]);
675 int start
= ps2
->border_position
[e
];
676 int stop
= ps2
->border_position
[e
+1];
677 INTFLOAT width
= Q30(1.f
) / ((stop
- start
) ? (stop
- start
) : 1);
679 width
= FFMIN(2U*width
, INT_MAX
);
682 h
[0][0] = H11
[0][e
][b
];
683 h
[0][1] = H12
[0][e
][b
];
684 h
[0][2] = H21
[0][e
][b
];
685 h
[0][3] = H22
[0][e
][b
];
686 if (!PS_BASELINE
&& ps2
->enable_ipdopd
) {
687 //Is this necessary? ps_04_new seems unchanged
688 if ((is34
&& k
<= 13 && k
>= 9) || (!is34
&& k
<= 1)) {
689 h
[1][0] = -H11
[1][e
][b
];
690 h
[1][1] = -H12
[1][e
][b
];
691 h
[1][2] = -H21
[1][e
][b
];
692 h
[1][3] = -H22
[1][e
][b
];
694 h
[1][0] = H11
[1][e
][b
];
695 h
[1][1] = H12
[1][e
][b
];
696 h
[1][2] = H21
[1][e
][b
];
697 h
[1][3] = H22
[1][e
][b
];
701 h_step
[0][0] = AAC_MSUB31_V3(H11
[0][e
+1][b
], h
[0][0], width
);
702 h_step
[0][1] = AAC_MSUB31_V3(H12
[0][e
+1][b
], h
[0][1], width
);
703 h_step
[0][2] = AAC_MSUB31_V3(H21
[0][e
+1][b
], h
[0][2], width
);
704 h_step
[0][3] = AAC_MSUB31_V3(H22
[0][e
+1][b
], h
[0][3], width
);
705 if (!PS_BASELINE
&& ps2
->enable_ipdopd
) {
706 h_step
[1][0] = AAC_MSUB31_V3(H11
[1][e
+1][b
], h
[1][0], width
);
707 h_step
[1][1] = AAC_MSUB31_V3(H12
[1][e
+1][b
], h
[1][1], width
);
708 h_step
[1][2] = AAC_MSUB31_V3(H21
[1][e
+1][b
], h
[1][2], width
);
709 h_step
[1][3] = AAC_MSUB31_V3(H22
[1][e
+1][b
], h
[1][3], width
);
712 ps
->dsp
.stereo_interpolate
[!PS_BASELINE
&& ps2
->enable_ipdopd
](
713 l
[k
] + 1 + start
, r
[k
] + 1 + start
,
714 h
, h_step
, stop
- start
);
719 int AAC_RENAME(ff_ps_apply
)(PSContext
*ps
, INTFLOAT L
[2][38][64], INTFLOAT R
[2][38][64], int top
)
721 INTFLOAT (*Lbuf
)[32][2] = ps
->Lbuf
;
722 INTFLOAT (*Rbuf
)[32][2] = ps
->Rbuf
;
724 int is34
= ps
->common
.is34bands
;
726 top
+= NR_BANDS
[is34
] - 64;
727 memset(ps
->delay
+top
, 0, (NR_BANDS
[is34
] - top
)*sizeof(ps
->delay
[0]));
728 if (top
< NR_ALLPASS_BANDS
[is34
])
729 memset(ps
->ap_delay
+ top
, 0, (NR_ALLPASS_BANDS
[is34
] - top
)*sizeof(ps
->ap_delay
[0]));
731 hybrid_analysis(&ps
->dsp
, Lbuf
, ps
->in_buf
, L
, is34
, len
);
732 decorrelation(ps
, Rbuf
, (const INTFLOAT (*)[32][2]) Lbuf
, is34
);
733 stereo_processing(ps
, Lbuf
, Rbuf
, is34
);
734 hybrid_synthesis(&ps
->dsp
, L
, Lbuf
, is34
, len
);
735 hybrid_synthesis(&ps
->dsp
, R
, Rbuf
, is34
, len
);
740 av_cold
void AAC_RENAME(ff_ps_init
)(void) {