yading@10
|
1 /*
|
yading@10
|
2 * AAC Spectral Band Replication decoding functions
|
yading@10
|
3 * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
|
yading@10
|
4 * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
|
yading@10
|
5 *
|
yading@10
|
6 * This file is part of Libav.
|
yading@10
|
7 *
|
yading@10
|
8 * Libav is free software; you can redistribute it and/or
|
yading@10
|
9 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
10 * License as published by the Free Software Foundation; either
|
yading@10
|
11 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
12 *
|
yading@10
|
13 * Libav is distributed in the hope that it will be useful,
|
yading@10
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
16 * Lesser General Public License for more details.
|
yading@10
|
17 *
|
yading@10
|
18 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
19 * License along with Libav; if not, write to the Free Software
|
yading@10
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
21 */
|
yading@10
|
22
|
yading@10
|
23 #include "config.h"
|
yading@10
|
24 #include "libavutil/attributes.h"
|
yading@10
|
25 #include "libavutil/intfloat.h"
|
yading@10
|
26 #include "sbrdsp.h"
|
yading@10
|
27
|
yading@10
|
28 static void sbr_sum64x5_c(float *z)
|
yading@10
|
29 {
|
yading@10
|
30 int k;
|
yading@10
|
31 for (k = 0; k < 64; k++) {
|
yading@10
|
32 float f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256];
|
yading@10
|
33 z[k] = f;
|
yading@10
|
34 }
|
yading@10
|
35 }
|
yading@10
|
36
|
yading@10
|
37 static float sbr_sum_square_c(float (*x)[2], int n)
|
yading@10
|
38 {
|
yading@10
|
39 float sum0 = 0.0f, sum1 = 0.0f;
|
yading@10
|
40 int i;
|
yading@10
|
41
|
yading@10
|
42 for (i = 0; i < n; i += 2)
|
yading@10
|
43 {
|
yading@10
|
44 sum0 += x[i + 0][0] * x[i + 0][0];
|
yading@10
|
45 sum1 += x[i + 0][1] * x[i + 0][1];
|
yading@10
|
46 sum0 += x[i + 1][0] * x[i + 1][0];
|
yading@10
|
47 sum1 += x[i + 1][1] * x[i + 1][1];
|
yading@10
|
48 }
|
yading@10
|
49
|
yading@10
|
50 return sum0 + sum1;
|
yading@10
|
51 }
|
yading@10
|
52
|
yading@10
|
53 static void sbr_neg_odd_64_c(float *x)
|
yading@10
|
54 {
|
yading@10
|
55 union av_intfloat32 *xi = (union av_intfloat32*)x;
|
yading@10
|
56 int i;
|
yading@10
|
57 for (i = 1; i < 64; i += 4)
|
yading@10
|
58 {
|
yading@10
|
59 xi[i+0].i ^= 1U<<31;
|
yading@10
|
60 xi[i+2].i ^= 1U<<31;
|
yading@10
|
61 }
|
yading@10
|
62 }
|
yading@10
|
63
|
yading@10
|
64 static void sbr_qmf_pre_shuffle_c(float *z)
|
yading@10
|
65 {
|
yading@10
|
66 union av_intfloat32 *zi = (union av_intfloat32*)z;
|
yading@10
|
67 int k;
|
yading@10
|
68 zi[64].i = zi[0].i;
|
yading@10
|
69 zi[65].i = zi[1].i;
|
yading@10
|
70 for (k = 1; k < 31; k+=2) {
|
yading@10
|
71 zi[64+2*k+0].i = zi[64 - k].i ^ (1U<<31);
|
yading@10
|
72 zi[64+2*k+1].i = zi[ k + 1].i;
|
yading@10
|
73 zi[64+2*k+2].i = zi[63 - k].i ^ (1U<<31);
|
yading@10
|
74 zi[64+2*k+3].i = zi[ k + 2].i;
|
yading@10
|
75 }
|
yading@10
|
76 zi[64+2*31+0].i = zi[64 - 31].i ^ (1U<<31);
|
yading@10
|
77 zi[64+2*31+1].i = zi[31 + 1].i;
|
yading@10
|
78 }
|
yading@10
|
79
|
yading@10
|
80 static void sbr_qmf_post_shuffle_c(float W[32][2], const float *z)
|
yading@10
|
81 {
|
yading@10
|
82 const union av_intfloat32 *zi = (const union av_intfloat32*)z;
|
yading@10
|
83 union av_intfloat32 *Wi = (union av_intfloat32*)W;
|
yading@10
|
84 int k;
|
yading@10
|
85 for (k = 0; k < 32; k+=2) {
|
yading@10
|
86 Wi[2*k+0].i = zi[63-k].i ^ (1U<<31);
|
yading@10
|
87 Wi[2*k+1].i = zi[k+0].i;
|
yading@10
|
88 Wi[2*k+2].i = zi[62-k].i ^ (1U<<31);
|
yading@10
|
89 Wi[2*k+3].i = zi[k+1].i;
|
yading@10
|
90 }
|
yading@10
|
91 }
|
yading@10
|
92
|
yading@10
|
93 static void sbr_qmf_deint_neg_c(float *v, const float *src)
|
yading@10
|
94 {
|
yading@10
|
95 const union av_intfloat32 *si = (const union av_intfloat32*)src;
|
yading@10
|
96 union av_intfloat32 *vi = (union av_intfloat32*)v;
|
yading@10
|
97 int i;
|
yading@10
|
98 for (i = 0; i < 32; i++) {
|
yading@10
|
99 vi[ i].i = si[63 - 2*i ].i;
|
yading@10
|
100 vi[63 - i].i = si[63 - 2*i - 1].i ^ (1U<<31);
|
yading@10
|
101 }
|
yading@10
|
102 }
|
yading@10
|
103
|
yading@10
|
104 static void sbr_qmf_deint_bfly_c(float *v, const float *src0, const float *src1)
|
yading@10
|
105 {
|
yading@10
|
106 int i;
|
yading@10
|
107 for (i = 0; i < 64; i++) {
|
yading@10
|
108 v[ i] = src0[i] - src1[63 - i];
|
yading@10
|
109 v[127 - i] = src0[i] + src1[63 - i];
|
yading@10
|
110 }
|
yading@10
|
111 }
|
yading@10
|
112
|
yading@10
|
113 static av_always_inline void autocorrelate(const float x[40][2],
|
yading@10
|
114 float phi[3][2][2], int lag)
|
yading@10
|
115 {
|
yading@10
|
116 int i;
|
yading@10
|
117 float real_sum = 0.0f;
|
yading@10
|
118 float imag_sum = 0.0f;
|
yading@10
|
119 if (lag) {
|
yading@10
|
120 for (i = 1; i < 38; i++) {
|
yading@10
|
121 real_sum += x[i][0] * x[i+lag][0] + x[i][1] * x[i+lag][1];
|
yading@10
|
122 imag_sum += x[i][0] * x[i+lag][1] - x[i][1] * x[i+lag][0];
|
yading@10
|
123 }
|
yading@10
|
124 phi[2-lag][1][0] = real_sum + x[ 0][0] * x[lag][0] + x[ 0][1] * x[lag][1];
|
yading@10
|
125 phi[2-lag][1][1] = imag_sum + x[ 0][0] * x[lag][1] - x[ 0][1] * x[lag][0];
|
yading@10
|
126 if (lag == 1) {
|
yading@10
|
127 phi[0][0][0] = real_sum + x[38][0] * x[39][0] + x[38][1] * x[39][1];
|
yading@10
|
128 phi[0][0][1] = imag_sum + x[38][0] * x[39][1] - x[38][1] * x[39][0];
|
yading@10
|
129 }
|
yading@10
|
130 } else {
|
yading@10
|
131 for (i = 1; i < 38; i++) {
|
yading@10
|
132 real_sum += x[i][0] * x[i][0] + x[i][1] * x[i][1];
|
yading@10
|
133 }
|
yading@10
|
134 phi[2][1][0] = real_sum + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1];
|
yading@10
|
135 phi[1][0][0] = real_sum + x[38][0] * x[38][0] + x[38][1] * x[38][1];
|
yading@10
|
136 }
|
yading@10
|
137 }
|
yading@10
|
138
|
yading@10
|
139 static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2])
|
yading@10
|
140 {
|
yading@10
|
141 #if 0
|
yading@10
|
142 // This code is slower because it multiplies memory accesses.
|
yading@10
|
143 // It is left as eucational purpose and because it may offer
|
yading@10
|
144 // a better reference for writing arch-specific dsp functions.
|
yading@10
|
145 autocorrelate(x, phi, 0);
|
yading@10
|
146 autocorrelate(x, phi, 1);
|
yading@10
|
147 autocorrelate(x, phi, 2);
|
yading@10
|
148 #else
|
yading@10
|
149 float real_sum2 = x[ 0][0] * x[ 2][0] + x[ 0][1] * x[ 2][1];
|
yading@10
|
150 float imag_sum2 = x[ 0][0] * x[ 2][1] - x[ 0][1] * x[ 2][0];
|
yading@10
|
151 float real_sum1 = 0.f, imag_sum1 = 0.f, real_sum0 = 0.0f;
|
yading@10
|
152 int i;
|
yading@10
|
153 for (i = 1; i < 38; i++) {
|
yading@10
|
154 real_sum0 += x[i][0] * x[i ][0] + x[i][1] * x[i ][1];
|
yading@10
|
155 real_sum1 += x[i][0] * x[i+1][0] + x[i][1] * x[i+1][1];
|
yading@10
|
156 imag_sum1 += x[i][0] * x[i+1][1] - x[i][1] * x[i+1][0];
|
yading@10
|
157 real_sum2 += x[i][0] * x[i+2][0] + x[i][1] * x[i+2][1];
|
yading@10
|
158 imag_sum2 += x[i][0] * x[i+2][1] - x[i][1] * x[i+2][0];
|
yading@10
|
159 }
|
yading@10
|
160 phi[2-2][1][0] = real_sum2;
|
yading@10
|
161 phi[2-2][1][1] = imag_sum2;
|
yading@10
|
162 phi[2 ][1][0] = real_sum0 + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1];
|
yading@10
|
163 phi[1 ][0][0] = real_sum0 + x[38][0] * x[38][0] + x[38][1] * x[38][1];
|
yading@10
|
164 phi[2-1][1][0] = real_sum1 + x[ 0][0] * x[ 1][0] + x[ 0][1] * x[ 1][1];
|
yading@10
|
165 phi[2-1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0];
|
yading@10
|
166 phi[0 ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1];
|
yading@10
|
167 phi[0 ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0];
|
yading@10
|
168 #endif
|
yading@10
|
169 }
|
yading@10
|
170
|
yading@10
|
171 static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2],
|
yading@10
|
172 const float alpha0[2], const float alpha1[2],
|
yading@10
|
173 float bw, int start, int end)
|
yading@10
|
174 {
|
yading@10
|
175 float alpha[4];
|
yading@10
|
176 int i;
|
yading@10
|
177
|
yading@10
|
178 alpha[0] = alpha1[0] * bw * bw;
|
yading@10
|
179 alpha[1] = alpha1[1] * bw * bw;
|
yading@10
|
180 alpha[2] = alpha0[0] * bw;
|
yading@10
|
181 alpha[3] = alpha0[1] * bw;
|
yading@10
|
182
|
yading@10
|
183 for (i = start; i < end; i++) {
|
yading@10
|
184 X_high[i][0] =
|
yading@10
|
185 X_low[i - 2][0] * alpha[0] -
|
yading@10
|
186 X_low[i - 2][1] * alpha[1] +
|
yading@10
|
187 X_low[i - 1][0] * alpha[2] -
|
yading@10
|
188 X_low[i - 1][1] * alpha[3] +
|
yading@10
|
189 X_low[i][0];
|
yading@10
|
190 X_high[i][1] =
|
yading@10
|
191 X_low[i - 2][1] * alpha[0] +
|
yading@10
|
192 X_low[i - 2][0] * alpha[1] +
|
yading@10
|
193 X_low[i - 1][1] * alpha[2] +
|
yading@10
|
194 X_low[i - 1][0] * alpha[3] +
|
yading@10
|
195 X_low[i][1];
|
yading@10
|
196 }
|
yading@10
|
197 }
|
yading@10
|
198
|
yading@10
|
199 static void sbr_hf_g_filt_c(float (*Y)[2], const float (*X_high)[40][2],
|
yading@10
|
200 const float *g_filt, int m_max, intptr_t ixh)
|
yading@10
|
201 {
|
yading@10
|
202 int m;
|
yading@10
|
203
|
yading@10
|
204 for (m = 0; m < m_max; m++) {
|
yading@10
|
205 Y[m][0] = X_high[m][ixh][0] * g_filt[m];
|
yading@10
|
206 Y[m][1] = X_high[m][ixh][1] * g_filt[m];
|
yading@10
|
207 }
|
yading@10
|
208 }
|
yading@10
|
209
|
yading@10
|
210 static av_always_inline void sbr_hf_apply_noise(float (*Y)[2],
|
yading@10
|
211 const float *s_m,
|
yading@10
|
212 const float *q_filt,
|
yading@10
|
213 int noise,
|
yading@10
|
214 float phi_sign0,
|
yading@10
|
215 float phi_sign1,
|
yading@10
|
216 int m_max)
|
yading@10
|
217 {
|
yading@10
|
218 int m;
|
yading@10
|
219
|
yading@10
|
220 for (m = 0; m < m_max; m++) {
|
yading@10
|
221 float y0 = Y[m][0];
|
yading@10
|
222 float y1 = Y[m][1];
|
yading@10
|
223 noise = (noise + 1) & 0x1ff;
|
yading@10
|
224 if (s_m[m]) {
|
yading@10
|
225 y0 += s_m[m] * phi_sign0;
|
yading@10
|
226 y1 += s_m[m] * phi_sign1;
|
yading@10
|
227 } else {
|
yading@10
|
228 y0 += q_filt[m] * ff_sbr_noise_table[noise][0];
|
yading@10
|
229 y1 += q_filt[m] * ff_sbr_noise_table[noise][1];
|
yading@10
|
230 }
|
yading@10
|
231 Y[m][0] = y0;
|
yading@10
|
232 Y[m][1] = y1;
|
yading@10
|
233 phi_sign1 = -phi_sign1;
|
yading@10
|
234 }
|
yading@10
|
235 }
|
yading@10
|
236
|
yading@10
|
237 static void sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m,
|
yading@10
|
238 const float *q_filt, int noise,
|
yading@10
|
239 int kx, int m_max)
|
yading@10
|
240 {
|
yading@10
|
241 sbr_hf_apply_noise(Y, s_m, q_filt, noise, 1.0, 0.0, m_max);
|
yading@10
|
242 }
|
yading@10
|
243
|
yading@10
|
244 static void sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m,
|
yading@10
|
245 const float *q_filt, int noise,
|
yading@10
|
246 int kx, int m_max)
|
yading@10
|
247 {
|
yading@10
|
248 float phi_sign = 1 - 2 * (kx & 1);
|
yading@10
|
249 sbr_hf_apply_noise(Y, s_m, q_filt, noise, 0.0, phi_sign, m_max);
|
yading@10
|
250 }
|
yading@10
|
251
|
yading@10
|
252 static void sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m,
|
yading@10
|
253 const float *q_filt, int noise,
|
yading@10
|
254 int kx, int m_max)
|
yading@10
|
255 {
|
yading@10
|
256 sbr_hf_apply_noise(Y, s_m, q_filt, noise, -1.0, 0.0, m_max);
|
yading@10
|
257 }
|
yading@10
|
258
|
yading@10
|
259 static void sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m,
|
yading@10
|
260 const float *q_filt, int noise,
|
yading@10
|
261 int kx, int m_max)
|
yading@10
|
262 {
|
yading@10
|
263 float phi_sign = 1 - 2 * (kx & 1);
|
yading@10
|
264 sbr_hf_apply_noise(Y, s_m, q_filt, noise, 0.0, -phi_sign, m_max);
|
yading@10
|
265 }
|
yading@10
|
266
|
yading@10
|
267 av_cold void ff_sbrdsp_init(SBRDSPContext *s)
|
yading@10
|
268 {
|
yading@10
|
269 s->sum64x5 = sbr_sum64x5_c;
|
yading@10
|
270 s->sum_square = sbr_sum_square_c;
|
yading@10
|
271 s->neg_odd_64 = sbr_neg_odd_64_c;
|
yading@10
|
272 s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_c;
|
yading@10
|
273 s->qmf_post_shuffle = sbr_qmf_post_shuffle_c;
|
yading@10
|
274 s->qmf_deint_neg = sbr_qmf_deint_neg_c;
|
yading@10
|
275 s->qmf_deint_bfly = sbr_qmf_deint_bfly_c;
|
yading@10
|
276 s->autocorrelate = sbr_autocorrelate_c;
|
yading@10
|
277 s->hf_gen = sbr_hf_gen_c;
|
yading@10
|
278 s->hf_g_filt = sbr_hf_g_filt_c;
|
yading@10
|
279
|
yading@10
|
280 s->hf_apply_noise[0] = sbr_hf_apply_noise_0;
|
yading@10
|
281 s->hf_apply_noise[1] = sbr_hf_apply_noise_1;
|
yading@10
|
282 s->hf_apply_noise[2] = sbr_hf_apply_noise_2;
|
yading@10
|
283 s->hf_apply_noise[3] = sbr_hf_apply_noise_3;
|
yading@10
|
284
|
yading@10
|
285 if (ARCH_ARM)
|
yading@10
|
286 ff_sbrdsp_init_arm(s);
|
yading@10
|
287 if (ARCH_X86)
|
yading@10
|
288 ff_sbrdsp_init_x86(s);
|
yading@10
|
289 if (ARCH_MIPS)
|
yading@10
|
290 ff_sbrdsp_init_mips(s);
|
yading@10
|
291 }
|