static void celt_imdct_half(CeltIMDCTContext *s, float *dst, const float *src, ptrdiff_t stride, float scale) { FFTComplex *z = (FFTComplex *)dst; const int len8 = s->len4 / 2; const float *in1 = src; const float *in2 = src + (s->len2 - 1) * stride; int i; for (i = 0; i < s->len4; i++) { FFTComplex tmp = { *in2, *in1 }; CMUL(s->tmp[i], tmp, s->twiddle_exptab[i]); in1 += 2 * stride; in2 -= 2 * stride; } fft_calc(s, z, s->tmp, s->fft_n, 1); for (i = 0; i < len8; i++) { float r0, i0, r1, i1; CMUL3(r0, i1, z[len8 - i - 1].im, z[len8 - i - 1].re, s->twiddle_exptab[len8 - i - 1].im, s->twiddle_exptab[len8 - i - 1].re); CMUL3(r1, i0, z[len8 + i].im, z[len8 + i].re, s->twiddle_exptab[len8 + i].im, s->twiddle_exptab[len8 + i].re); z[len8 - i - 1].re = scale * r0; z[len8 - i - 1].im = scale * i0; z[len8 + i].re = scale * r1; z[len8 + i].im = scale * i1; } }
static void imdct15_half(MDCT15Context *s, float *dst, const float *src, ptrdiff_t stride) { FFTComplex fft15in[15]; FFTComplex *z = (FFTComplex *)dst; int i, j, len8 = s->len4 >> 1, l_ptwo = 1 << s->ptwo_fft.nbits; const float *in1 = src, *in2 = src + (s->len2 - 1) * stride; /* Reindex input, putting it into a buffer and doing an Nx15 FFT */ for (i = 0; i < l_ptwo; i++) { for (j = 0; j < 15; j++) { const int k = s->pfa_prereindex[i*15 + j]; FFTComplex tmp = { *(in2 - 2*k*stride), *(in1 + 2*k*stride) }; CMUL3(fft15in[j], tmp, s->twiddle_exptab[k]); } s->fft15(s->tmp + s->ptwo_fft.revtab[i], fft15in, s->exptab, l_ptwo); } /* Then a 15xN FFT (where N is a power of two) */ for (i = 0; i < 15; i++) s->ptwo_fft.fft_calc(&s->ptwo_fft, s->tmp + l_ptwo*i); /* Reindex again, apply twiddles and output */ for (i = 0; i < len8; i++) { const int i0 = len8 + i, i1 = len8 - i - 1; const int s0 = s->pfa_postreindex[i0], s1 = s->pfa_postreindex[i1]; CMUL(z[i1].re, z[i0].im, s->tmp[s1].im, s->tmp[s1].re, s->twiddle_exptab[i1].im, s->twiddle_exptab[i1].re); CMUL(z[i0].re, z[i1].im, s->tmp[s0].im, s->tmp[s0].re, s->twiddle_exptab[i0].im, s->twiddle_exptab[i0].re); } }
static void fft15_c(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride) { int k; FFTComplex tmp1[5], tmp2[5], tmp3[5]; fft5(tmp1, in + 0, exptab + 19); fft5(tmp2, in + 1, exptab + 19); fft5(tmp3, in + 2, exptab + 19); for (k = 0; k < 5; k++) { FFTComplex t[2]; CMUL3(t[0], tmp2[k], exptab[k]); CMUL3(t[1], tmp3[k], exptab[2 * k]); out[stride*k].re = tmp1[k].re + t[0].re + t[1].re; out[stride*k].im = tmp1[k].im + t[0].im + t[1].im; CMUL3(t[0], tmp2[k], exptab[k + 5]); CMUL3(t[1], tmp3[k], exptab[2 * (k + 5)]); out[stride*(k + 5)].re = tmp1[k].re + t[0].re + t[1].re; out[stride*(k + 5)].im = tmp1[k].im + t[0].im + t[1].im; CMUL3(t[0], tmp2[k], exptab[k + 10]); CMUL3(t[1], tmp3[k], exptab[2 * k + 5]); out[stride*(k + 10)].re = tmp1[k].re + t[0].re + t[1].re; out[stride*(k + 10)].im = tmp1[k].im + t[0].im + t[1].im; } }