|
|
|
@ -143,14 +143,23 @@ av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) |
|
|
|
|
{ |
|
|
|
|
int i, j, n; |
|
|
|
|
|
|
|
|
|
s->revtab = NULL; |
|
|
|
|
s->revtab32 = NULL; |
|
|
|
|
|
|
|
|
|
if (nbits < 2 || nbits > 17) |
|
|
|
|
goto fail; |
|
|
|
|
s->nbits = nbits; |
|
|
|
|
n = 1 << nbits; |
|
|
|
|
|
|
|
|
|
s->revtab = av_malloc(n * sizeof(uint16_t)); |
|
|
|
|
if (!s->revtab) |
|
|
|
|
goto fail; |
|
|
|
|
if (nbits <= 16) { |
|
|
|
|
s->revtab = av_malloc(n * sizeof(uint16_t)); |
|
|
|
|
if (!s->revtab) |
|
|
|
|
goto fail; |
|
|
|
|
} else { |
|
|
|
|
s->revtab32 = av_malloc(n * sizeof(uint32_t)); |
|
|
|
|
if (!s->revtab32) |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
s->tmp_buf = av_malloc(n * sizeof(FFTComplex)); |
|
|
|
|
if (!s->tmp_buf) |
|
|
|
|
goto fail; |
|
|
|
@ -192,16 +201,22 @@ av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) |
|
|
|
|
fft_perm_avx(s); |
|
|
|
|
} else { |
|
|
|
|
for(i=0; i<n; i++) { |
|
|
|
|
int k; |
|
|
|
|
j = i; |
|
|
|
|
if (s->fft_permutation == FF_FFT_PERM_SWAP_LSBS) |
|
|
|
|
j = (j&~3) | ((j>>1)&1) | ((j<<1)&2); |
|
|
|
|
s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = j; |
|
|
|
|
k = -split_radix_permutation(i, n, s->inverse) & (n-1); |
|
|
|
|
if (s->revtab) |
|
|
|
|
s->revtab[k] = j; |
|
|
|
|
if (s->revtab32) |
|
|
|
|
s->revtab32[k] = j; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
fail: |
|
|
|
|
av_freep(&s->revtab); |
|
|
|
|
av_freep(&s->revtab32); |
|
|
|
|
av_freep(&s->tmp_buf); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
@ -210,15 +225,21 @@ static void fft_permute_c(FFTContext *s, FFTComplex *z) |
|
|
|
|
{ |
|
|
|
|
int j, np; |
|
|
|
|
const uint16_t *revtab = s->revtab; |
|
|
|
|
const uint32_t *revtab32 = s->revtab32; |
|
|
|
|
np = 1 << s->nbits; |
|
|
|
|
/* TODO: handle split-radix permute in a more optimal way, probably in-place */ |
|
|
|
|
for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j]; |
|
|
|
|
if (revtab) { |
|
|
|
|
for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j]; |
|
|
|
|
} else |
|
|
|
|
for(j=0;j<np;j++) s->tmp_buf[revtab32[j]] = z[j]; |
|
|
|
|
|
|
|
|
|
memcpy(z, s->tmp_buf, np * sizeof(FFTComplex)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
av_cold void ff_fft_end(FFTContext *s) |
|
|
|
|
{ |
|
|
|
|
av_freep(&s->revtab); |
|
|
|
|
av_freep(&s->revtab32); |
|
|
|
|
av_freep(&s->tmp_buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|