Signed-off-by: Mans Rullgard <mans@mansr.com>
| ... | ... |
@@ -39,6 +39,8 @@ |
| 39 | 39 |
#include "libavutil/intmath.h" |
| 40 | 40 |
#include "mathops.h" |
| 41 | 41 |
|
| 42 |
+void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input); |
|
| 43 |
+ |
|
| 42 | 44 |
#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits))) |
| 43 | 45 |
#define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767) |
| 44 | 46 |
|
| ... | ... |
@@ -49,11 +51,17 @@ |
| 49 | 49 |
y = (a + b) >> 1; \ |
| 50 | 50 |
} while (0) |
| 51 | 51 |
|
| 52 |
-#define CMUL(dre, dim, are, aim, bre, bim) do { \
|
|
| 53 |
- (dre) = (MUL16(are, bre) - MUL16(aim, bim)) >> 15; \ |
|
| 54 |
- (dim) = (MUL16(are, bim) + MUL16(aim, bre)) >> 15; \ |
|
| 52 |
+#define CMULS(dre, dim, are, aim, bre, bim, sh) do { \
|
|
| 53 |
+ (dre) = (MUL16(are, bre) - MUL16(aim, bim)) >> sh; \ |
|
| 54 |
+ (dim) = (MUL16(are, bim) + MUL16(aim, bre)) >> sh; \ |
|
| 55 | 55 |
} while (0) |
| 56 | 56 |
|
| 57 |
+#define CMUL(dre, dim, are, aim, bre, bim) \ |
|
| 58 |
+ CMULS(dre, dim, are, aim, bre, bim, 15) |
|
| 59 |
+ |
|
| 60 |
+#define CMULL(dre, dim, are, aim, bre, bim) \ |
|
| 61 |
+ CMULS(dre, dim, are, aim, bre, bim, 0) |
|
| 62 |
+ |
|
| 57 | 63 |
#endif /* CONFIG_FFT_FLOAT */ |
| 58 | 64 |
|
| 59 | 65 |
#define ff_imdct_calc_c FFT_NAME(ff_imdct_calc_c) |
| ... | ... |
@@ -123,6 +123,9 @@ av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) |
| 123 | 123 |
if (ARCH_ARM) ff_fft_init_arm(s); |
| 124 | 124 |
if (HAVE_ALTIVEC) ff_fft_init_altivec(s); |
| 125 | 125 |
if (HAVE_MMX) ff_fft_init_mmx(s); |
| 126 |
+ if (CONFIG_MDCT) s->mdct_calcw = s->mdct_calc; |
|
| 127 |
+#else |
|
| 128 |
+ if (CONFIG_MDCT) s->mdct_calcw = ff_mdct_calcw_c; |
|
| 126 | 129 |
#endif |
| 127 | 130 |
|
| 128 | 131 |
for(j=4; j<=nbits; j++) {
|
| ... | ... |
@@ -53,6 +53,10 @@ typedef struct FFTContext FFTContext; |
| 53 | 53 |
|
| 54 | 54 |
#endif /* CONFIG_FFT_FLOAT */ |
| 55 | 55 |
|
| 56 |
+typedef struct FFTDComplex {
|
|
| 57 |
+ FFTDouble re, im; |
|
| 58 |
+} FFTDComplex; |
|
| 59 |
+ |
|
| 56 | 60 |
/* FFT computation */ |
| 57 | 61 |
|
| 58 | 62 |
struct FFTContext {
|
| ... | ... |
@@ -77,6 +81,7 @@ struct FFTContext {
|
| 77 | 77 |
void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); |
| 78 | 78 |
void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input); |
| 79 | 79 |
void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); |
| 80 |
+ void (*mdct_calcw)(struct FFTContext *s, FFTDouble *output, const FFTSample *input); |
|
| 80 | 81 |
int fft_permutation; |
| 81 | 82 |
#define FF_FFT_PERM_DEFAULT 0 |
| 82 | 83 |
#define FF_FFT_PERM_SWAP_LSBS 1 |
| ... | ... |
@@ -18,3 +18,47 @@ |
| 18 | 18 |
|
| 19 | 19 |
#define CONFIG_FFT_FLOAT 0 |
| 20 | 20 |
#include "mdct.c" |
| 21 |
+ |
|
| 22 |
+/* same as ff_mdct_calcw_c with double-width unscaled output */ |
|
| 23 |
+void ff_mdct_calcw_c(FFTContext *s, FFTDouble *out, const FFTSample *input) |
|
| 24 |
+{
|
|
| 25 |
+ int i, j, n, n8, n4, n2, n3; |
|
| 26 |
+ FFTDouble re, im; |
|
| 27 |
+ const uint16_t *revtab = s->revtab; |
|
| 28 |
+ const FFTSample *tcos = s->tcos; |
|
| 29 |
+ const FFTSample *tsin = s->tsin; |
|
| 30 |
+ FFTComplex *x = s->tmp_buf; |
|
| 31 |
+ FFTDComplex *o = (FFTDComplex *)out; |
|
| 32 |
+ |
|
| 33 |
+ n = 1 << s->mdct_bits; |
|
| 34 |
+ n2 = n >> 1; |
|
| 35 |
+ n4 = n >> 2; |
|
| 36 |
+ n8 = n >> 3; |
|
| 37 |
+ n3 = 3 * n4; |
|
| 38 |
+ |
|
| 39 |
+ /* pre rotation */ |
|
| 40 |
+ for(i=0;i<n8;i++) {
|
|
| 41 |
+ re = RSCALE(-input[2*i+n3] - input[n3-1-2*i]); |
|
| 42 |
+ im = RSCALE(-input[n4+2*i] + input[n4-1-2*i]); |
|
| 43 |
+ j = revtab[i]; |
|
| 44 |
+ CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]); |
|
| 45 |
+ |
|
| 46 |
+ re = RSCALE( input[2*i] - input[n2-1-2*i]); |
|
| 47 |
+ im = RSCALE(-input[n2+2*i] - input[ n-1-2*i]); |
|
| 48 |
+ j = revtab[n8 + i]; |
|
| 49 |
+ CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]); |
|
| 50 |
+ } |
|
| 51 |
+ |
|
| 52 |
+ s->fft_calc(s, x); |
|
| 53 |
+ |
|
| 54 |
+ /* post rotation */ |
|
| 55 |
+ for(i=0;i<n8;i++) {
|
|
| 56 |
+ FFTDouble r0, i0, r1, i1; |
|
| 57 |
+ CMULL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]); |
|
| 58 |
+ CMULL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]); |
|
| 59 |
+ o[n8-i-1].re = r0; |
|
| 60 |
+ o[n8-i-1].im = i0; |
|
| 61 |
+ o[n8+i ].re = r1; |
|
| 62 |
+ o[n8+i ].im = i1; |
|
| 63 |
+ } |
|
| 64 |
+} |