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>
6 * This file is part of Libav.
8 * Libav 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.
13 * Libav 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.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "libavutil/attributes.h"
27 static void sbr_sum64x5_c(float *z
)
30 for (k
= 0; k
< 64; k
++) {
31 float f
= z
[k
] + z
[k
+ 64] + z
[k
+ 128] + z
[k
+ 192] + z
[k
+ 256];
36 static float sbr_sum_square_c(float (*x
)[2], int n
)
38 float sum0
= 0.0f
, sum1
= 0.0f
;
41 for (i
= 0; i
< n
; i
+= 2)
43 sum0
+= x
[i
+ 0][0] * x
[i
+ 0][0];
44 sum1
+= x
[i
+ 0][1] * x
[i
+ 0][1];
45 sum0
+= x
[i
+ 1][0] * x
[i
+ 1][0];
46 sum1
+= x
[i
+ 1][1] * x
[i
+ 1][1];
52 static void sbr_neg_odd_64_c(float *x
)
55 for (i
= 1; i
< 64; i
+= 2)
59 static void sbr_qmf_pre_shuffle_c(float *z
)
64 for (k
= 1; k
< 32; k
++) {
65 z
[64+2*k
] = -z
[64 - k
];
66 z
[64+2*k
+1] = z
[ k
+ 1];
70 static void sbr_qmf_post_shuffle_c(float W
[32][2], const float *z
)
73 for (k
= 0; k
< 32; k
++) {
79 static void sbr_qmf_deint_neg_c(float *v
, const float *src
)
82 for (i
= 0; i
< 32; i
++) {
83 v
[ i
] = src
[63 - 2*i
];
84 v
[63 - i
] = -src
[63 - 2*i
- 1];
88 static void sbr_qmf_deint_bfly_c(float *v
, const float *src0
, const float *src1
)
91 for (i
= 0; i
< 64; i
++) {
92 v
[ i
] = src0
[i
] - src1
[63 - i
];
93 v
[127 - i
] = src0
[i
] + src1
[63 - i
];
97 static av_always_inline
void autocorrelate(const float x
[40][2],
98 float phi
[3][2][2], int lag
)
101 float real_sum
= 0.0f
;
102 float imag_sum
= 0.0f
;
104 for (i
= 1; i
< 38; i
++) {
105 real_sum
+= x
[i
][0] * x
[i
+lag
][0] + x
[i
][1] * x
[i
+lag
][1];
106 imag_sum
+= x
[i
][0] * x
[i
+lag
][1] - x
[i
][1] * x
[i
+lag
][0];
108 phi
[2-lag
][1][0] = real_sum
+ x
[ 0][0] * x
[lag
][0] + x
[ 0][1] * x
[lag
][1];
109 phi
[2-lag
][1][1] = imag_sum
+ x
[ 0][0] * x
[lag
][1] - x
[ 0][1] * x
[lag
][0];
111 phi
[0][0][0] = real_sum
+ x
[38][0] * x
[39][0] + x
[38][1] * x
[39][1];
112 phi
[0][0][1] = imag_sum
+ x
[38][0] * x
[39][1] - x
[38][1] * x
[39][0];
115 for (i
= 1; i
< 38; i
++) {
116 real_sum
+= x
[i
][0] * x
[i
][0] + x
[i
][1] * x
[i
][1];
118 phi
[2][1][0] = real_sum
+ x
[ 0][0] * x
[ 0][0] + x
[ 0][1] * x
[ 0][1];
119 phi
[1][0][0] = real_sum
+ x
[38][0] * x
[38][0] + x
[38][1] * x
[38][1];
123 static void sbr_autocorrelate_c(const float x
[40][2], float phi
[3][2][2])
125 autocorrelate(x
, phi
, 0);
126 autocorrelate(x
, phi
, 1);
127 autocorrelate(x
, phi
, 2);
130 static void sbr_hf_gen_c(float (*X_high
)[2], const float (*X_low
)[2],
131 const float alpha0
[2], const float alpha1
[2],
132 float bw
, int start
, int end
)
137 alpha
[0] = alpha1
[0] * bw
* bw
;
138 alpha
[1] = alpha1
[1] * bw
* bw
;
139 alpha
[2] = alpha0
[0] * bw
;
140 alpha
[3] = alpha0
[1] * bw
;
142 for (i
= start
; i
< end
; i
++) {
144 X_low
[i
- 2][0] * alpha
[0] -
145 X_low
[i
- 2][1] * alpha
[1] +
146 X_low
[i
- 1][0] * alpha
[2] -
147 X_low
[i
- 1][1] * alpha
[3] +
150 X_low
[i
- 2][1] * alpha
[0] +
151 X_low
[i
- 2][0] * alpha
[1] +
152 X_low
[i
- 1][1] * alpha
[2] +
153 X_low
[i
- 1][0] * alpha
[3] +
158 static void sbr_hf_g_filt_c(float (*Y
)[2], const float (*X_high
)[40][2],
159 const float *g_filt
, int m_max
, intptr_t ixh
)
163 for (m
= 0; m
< m_max
; m
++) {
164 Y
[m
][0] = X_high
[m
][ixh
][0] * g_filt
[m
];
165 Y
[m
][1] = X_high
[m
][ixh
][1] * g_filt
[m
];
169 static av_always_inline
void sbr_hf_apply_noise(float (*Y
)[2],
179 for (m
= 0; m
< m_max
; m
++) {
182 noise
= (noise
+ 1) & 0x1ff;
184 y0
+= s_m
[m
] * phi_sign0
;
185 y1
+= s_m
[m
] * phi_sign1
;
187 y0
+= q_filt
[m
] * ff_sbr_noise_table
[noise
][0];
188 y1
+= q_filt
[m
] * ff_sbr_noise_table
[noise
][1];
192 phi_sign1
= -phi_sign1
;
196 static void sbr_hf_apply_noise_0(float (*Y
)[2], const float *s_m
,
197 const float *q_filt
, int noise
,
200 sbr_hf_apply_noise(Y
, s_m
, q_filt
, noise
, 1.0, 0.0, m_max
);
203 static void sbr_hf_apply_noise_1(float (*Y
)[2], const float *s_m
,
204 const float *q_filt
, int noise
,
207 float phi_sign
= 1 - 2 * (kx
& 1);
208 sbr_hf_apply_noise(Y
, s_m
, q_filt
, noise
, 0.0, phi_sign
, m_max
);
211 static void sbr_hf_apply_noise_2(float (*Y
)[2], const float *s_m
,
212 const float *q_filt
, int noise
,
215 sbr_hf_apply_noise(Y
, s_m
, q_filt
, noise
, -1.0, 0.0, m_max
);
218 static void sbr_hf_apply_noise_3(float (*Y
)[2], const float *s_m
,
219 const float *q_filt
, int noise
,
222 float phi_sign
= 1 - 2 * (kx
& 1);
223 sbr_hf_apply_noise(Y
, s_m
, q_filt
, noise
, 0.0, -phi_sign
, m_max
);
226 av_cold
void ff_sbrdsp_init(SBRDSPContext
*s
)
228 s
->sum64x5
= sbr_sum64x5_c
;
229 s
->sum_square
= sbr_sum_square_c
;
230 s
->neg_odd_64
= sbr_neg_odd_64_c
;
231 s
->qmf_pre_shuffle
= sbr_qmf_pre_shuffle_c
;
232 s
->qmf_post_shuffle
= sbr_qmf_post_shuffle_c
;
233 s
->qmf_deint_neg
= sbr_qmf_deint_neg_c
;
234 s
->qmf_deint_bfly
= sbr_qmf_deint_bfly_c
;
235 s
->autocorrelate
= sbr_autocorrelate_c
;
236 s
->hf_gen
= sbr_hf_gen_c
;
237 s
->hf_g_filt
= sbr_hf_g_filt_c
;
239 s
->hf_apply_noise
[0] = sbr_hf_apply_noise_0
;
240 s
->hf_apply_noise
[1] = sbr_hf_apply_noise_1
;
241 s
->hf_apply_noise
[2] = sbr_hf_apply_noise_2
;
242 s
->hf_apply_noise
[3] = sbr_hf_apply_noise_3
;
245 ff_sbrdsp_init_arm(s
);
247 ff_sbrdsp_init_x86(s
);