Revision 86c9673b
libavcodec/ac3enc.c | ||
---|---|---|
37 | 37 |
#include "audioconvert.h" |
38 | 38 |
|
39 | 39 |
|
40 |
#define MDCT_NBITS 9 |
|
41 |
#define MDCT_SAMPLES (1 << MDCT_NBITS) |
|
42 |
|
|
43 | 40 |
/** Maximum number of exponent groups. +1 for separate DC exponent. */ |
44 | 41 |
#define AC3_MAX_EXP_GROUPS 85 |
45 | 42 |
|
... | ... | |
60 | 57 |
|
61 | 58 |
typedef struct AC3MDCTContext { |
62 | 59 |
AVCodecContext *avctx; ///< parent context for av_log() |
60 |
int nbits; ///< log2(transform size) |
|
61 |
int16_t *costab; ///< FFT cos table |
|
62 |
int16_t *sintab; ///< FFT sin table |
|
63 |
int16_t *xcos1; ///< MDCT cos table |
|
64 |
int16_t *xsin1; ///< MDCT sin table |
|
63 | 65 |
int16_t *rot_tmp; ///< temp buffer for pre-rotated samples |
64 | 66 |
IComplex *cplx_tmp; ///< temp buffer for complex pre-rotated samples |
65 | 67 |
} AC3MDCTContext; |
... | ... | |
145 | 147 |
} AC3EncodeContext; |
146 | 148 |
|
147 | 149 |
|
148 |
/** MDCT and FFT tables */ |
|
149 |
static int16_t costab[64]; |
|
150 |
static int16_t sintab[64]; |
|
151 |
static int16_t xcos1[128]; |
|
152 |
static int16_t xsin1[128]; |
|
153 |
|
|
154 | 150 |
/** |
155 | 151 |
* LUT for number of exponent groups. |
156 | 152 |
* exponent_group_tab[exponent strategy-1][number of coefficients] |
... | ... | |
209 | 205 |
*/ |
210 | 206 |
static av_cold void mdct_end(AC3MDCTContext *mdct) |
211 | 207 |
{ |
208 |
mdct->nbits = 0; |
|
209 |
av_freep(&mdct->costab); |
|
210 |
av_freep(&mdct->sintab); |
|
211 |
av_freep(&mdct->xcos1); |
|
212 |
av_freep(&mdct->xsin1); |
|
212 | 213 |
av_freep(&mdct->rot_tmp); |
213 | 214 |
av_freep(&mdct->cplx_tmp); |
214 | 215 |
} |
... | ... | |
219 | 220 |
* Initialize FFT tables. |
220 | 221 |
* @param ln log2(FFT size) |
221 | 222 |
*/ |
222 |
static av_cold void fft_init(int ln)
|
|
223 |
static av_cold int fft_init(AC3MDCTContext *mdct, int ln)
|
|
223 | 224 |
{ |
224 | 225 |
int i, n, n2; |
225 | 226 |
float alpha; |
... | ... | |
227 | 228 |
n = 1 << ln; |
228 | 229 |
n2 = n >> 1; |
229 | 230 |
|
231 |
FF_ALLOC_OR_GOTO(mdct->avctx, mdct->costab, n2 * sizeof(*mdct->costab), |
|
232 |
fft_alloc_fail); |
|
233 |
FF_ALLOC_OR_GOTO(mdct->avctx, mdct->sintab, n2 * sizeof(*mdct->sintab), |
|
234 |
fft_alloc_fail); |
|
235 |
|
|
230 | 236 |
for (i = 0; i < n2; i++) { |
231 | 237 |
alpha = 2.0 * M_PI * i / n; |
232 |
costab[i] = FIX15(cos(alpha)); |
|
233 |
sintab[i] = FIX15(sin(alpha)); |
|
238 |
mdct->costab[i] = FIX15(cos(alpha));
|
|
239 |
mdct->sintab[i] = FIX15(sin(alpha));
|
|
234 | 240 |
} |
241 |
|
|
242 |
return 0; |
|
243 |
fft_alloc_fail: |
|
244 |
mdct_end(mdct); |
|
245 |
return AVERROR(ENOMEM); |
|
235 | 246 |
} |
236 | 247 |
|
237 | 248 |
|
... | ... | |
241 | 252 |
*/ |
242 | 253 |
static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits) |
243 | 254 |
{ |
244 |
int i, n, n4; |
|
255 |
int i, n, n4, ret;
|
|
245 | 256 |
|
246 | 257 |
n = 1 << nbits; |
247 | 258 |
n4 = n >> 2; |
248 | 259 |
|
249 |
fft_init(nbits - 2); |
|
260 |
mdct->nbits = nbits; |
|
261 |
|
|
262 |
ret = fft_init(mdct, nbits - 2); |
|
263 |
if (ret) |
|
264 |
return ret; |
|
250 | 265 |
|
266 |
FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xcos1, n4 * sizeof(*mdct->xcos1), |
|
267 |
mdct_alloc_fail); |
|
268 |
FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xsin1 , n4 * sizeof(*mdct->xsin1), |
|
269 |
mdct_alloc_fail); |
|
251 | 270 |
FF_ALLOC_OR_GOTO(mdct->avctx, mdct->rot_tmp, n * sizeof(*mdct->rot_tmp), |
252 | 271 |
mdct_alloc_fail); |
253 | 272 |
FF_ALLOC_OR_GOTO(mdct->avctx, mdct->cplx_tmp, n4 * sizeof(*mdct->cplx_tmp), |
... | ... | |
255 | 274 |
|
256 | 275 |
for (i = 0; i < n4; i++) { |
257 | 276 |
float alpha = 2.0 * M_PI * (i + 1.0 / 8.0) / n; |
258 |
xcos1[i] = FIX15(-cos(alpha)); |
|
259 |
xsin1[i] = FIX15(-sin(alpha)); |
|
277 |
mdct->xcos1[i] = FIX15(-cos(alpha));
|
|
278 |
mdct->xsin1[i] = FIX15(-sin(alpha));
|
|
260 | 279 |
} |
261 | 280 |
|
262 | 281 |
return 0; |
263 | 282 |
mdct_alloc_fail: |
283 |
mdct_end(mdct); |
|
264 | 284 |
return AVERROR(ENOMEM); |
265 | 285 |
} |
266 | 286 |
|
... | ... | |
293 | 313 |
* @param z complex input/output samples |
294 | 314 |
* @param ln log2(FFT size) |
295 | 315 |
*/ |
296 |
static void fft(IComplex *z, int ln) |
|
316 |
static void fft(AC3MDCTContext *mdct, IComplex *z, int ln)
|
|
297 | 317 |
{ |
298 | 318 |
int j, l, np, np2; |
299 | 319 |
int nblocks, nloops; |
... | ... | |
345 | 365 |
p++; |
346 | 366 |
q++; |
347 | 367 |
for(l = nblocks; l < np2; l += nblocks) { |
348 |
CMUL(tmp_re, tmp_im, costab[l], -sintab[l], q->re, q->im);
|
|
368 |
CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im);
|
|
349 | 369 |
BF(p->re, p->im, q->re, q->im, |
350 | 370 |
p->re, p->im, tmp_re, tmp_im); |
351 | 371 |
p++; |
... | ... | |
367 | 387 |
*/ |
368 | 388 |
static void mdct512(AC3MDCTContext *mdct, int32_t *out, int16_t *in) |
369 | 389 |
{ |
370 |
int i, re, im; |
|
390 |
int i, re, im, n, n2, n4;
|
|
371 | 391 |
int16_t *rot = mdct->rot_tmp; |
372 | 392 |
IComplex *x = mdct->cplx_tmp; |
373 | 393 |
|
394 |
n = 1 << mdct->nbits; |
|
395 |
n2 = n >> 1; |
|
396 |
n4 = n >> 2; |
|
397 |
|
|
374 | 398 |
/* shift to simplify computations */ |
375 |
for (i = 0; i < MDCT_SAMPLES/4; i++)
|
|
376 |
rot[i] = -in[i + 3*MDCT_SAMPLES/4];
|
|
377 |
memcpy(&rot[MDCT_SAMPLES/4], &in[0], 3*MDCT_SAMPLES/4*sizeof(*in));
|
|
399 |
for (i = 0; i <n4; i++)
|
|
400 |
rot[i] = -in[i + 3*n4];
|
|
401 |
memcpy(&rot[n4], &in[0], 3*n4*sizeof(*in));
|
|
378 | 402 |
|
379 | 403 |
/* pre rotation */ |
380 |
for (i = 0; i < MDCT_SAMPLES/4; i++) {
|
|
381 |
re = ((int)rot[ 2*i] - (int)rot[MDCT_SAMPLES -1-2*i]) >> 1;
|
|
382 |
im = -((int)rot[MDCT_SAMPLES/2+2*i] - (int)rot[MDCT_SAMPLES/2-1-2*i]) >> 1;
|
|
383 |
CMUL(x[i].re, x[i].im, re, im, -xcos1[i], xsin1[i]);
|
|
404 |
for (i = 0; i < n4; i++) {
|
|
405 |
re = ((int)rot[ 2*i] - (int)rot[ n-1-2*i]) >> 1;
|
|
406 |
im = -((int)rot[n2+2*i] - (int)rot[n2-1-2*i]) >> 1;
|
|
407 |
CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]);
|
|
384 | 408 |
} |
385 | 409 |
|
386 |
fft(x, MDCT_NBITS - 2);
|
|
410 |
fft(mdct, x, mdct->nbits - 2);
|
|
387 | 411 |
|
388 | 412 |
/* post rotation */ |
389 |
for (i = 0; i < MDCT_SAMPLES/4; i++) {
|
|
413 |
for (i = 0; i < n4; i++) {
|
|
390 | 414 |
re = x[i].re; |
391 | 415 |
im = x[i].im; |
392 |
CMUL(out[MDCT_SAMPLES/2-1-2*i], out[2*i], re, im, xsin1[i], xcos1[i]);
|
|
416 |
CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i]);
|
|
393 | 417 |
} |
394 | 418 |
} |
395 | 419 |
|
... | ... | |
1824 | 1848 |
|
1825 | 1849 |
#include "libavutil/lfg.h" |
1826 | 1850 |
|
1851 |
#define MDCT_NBITS 9 |
|
1852 |
#define MDCT_SAMPLES (1 << MDCT_NBITS) |
|
1827 | 1853 |
#define FN (MDCT_SAMPLES/4) |
1828 | 1854 |
|
1829 | 1855 |
|
1830 |
static void fft_test(AVLFG *lfg) |
|
1856 |
static void fft_test(AC3MDCTContext *mdct, AVLFG *lfg)
|
|
1831 | 1857 |
{ |
1832 | 1858 |
IComplex in[FN], in1[FN]; |
1833 | 1859 |
int k, n, i; |
... | ... | |
1838 | 1864 |
in[i].im = av_lfg_get(lfg) % 65535 - 32767; |
1839 | 1865 |
in1[i] = in[i]; |
1840 | 1866 |
} |
1841 |
fft(in, 7); |
|
1867 |
fft(mdct, in, 7);
|
|
1842 | 1868 |
|
1843 | 1869 |
/* do it by hand */ |
1844 | 1870 |
for (k = 0; k < FN; k++) { |
... | ... | |
1855 | 1881 |
} |
1856 | 1882 |
|
1857 | 1883 |
|
1858 |
static void mdct_test(AVLFG *lfg) |
|
1884 |
static void mdct_test(AC3MDCTContext *mdct, AVLFG *lfg)
|
|
1859 | 1885 |
{ |
1860 | 1886 |
int16_t input[MDCT_SAMPLES]; |
1861 | 1887 |
int32_t output[AC3_MAX_COEFS]; |
... | ... | |
1869 | 1895 |
input1[i] = input[i]; |
1870 | 1896 |
} |
1871 | 1897 |
|
1872 |
mdct512(output, input); |
|
1898 |
mdct512(mdct, output, input);
|
|
1873 | 1899 |
|
1874 | 1900 |
/* do it by hand */ |
1875 | 1901 |
for (k = 0; k < AC3_MAX_COEFS; k++) { |
... | ... | |
1897 | 1923 |
int main(void) |
1898 | 1924 |
{ |
1899 | 1925 |
AVLFG lfg; |
1926 |
AC3MDCTContext mdct; |
|
1900 | 1927 |
|
1928 |
mdct.avctx = NULL; |
|
1901 | 1929 |
av_log_set_level(AV_LOG_DEBUG); |
1902 |
mdct_init(9); |
|
1930 |
mdct_init(&mdct, 9);
|
|
1903 | 1931 |
|
1904 |
fft_test(&lfg); |
|
1905 |
mdct_test(&lfg); |
|
1932 |
fft_test(&mdct, &lfg);
|
|
1933 |
mdct_test(&mdct, &lfg);
|
|
1906 | 1934 |
|
1907 | 1935 |
return 0; |
1908 | 1936 |
} |
Also available in: Unified diff