/* This is a simple MDCT implementation that uses a N/4 complex FFT todomostofthework.Itshouldberelativelystraightforwardto pluginprettymuchandFFThere.
int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch)
{ int i;
kiss_twiddle_scalar *trig; int shift; int N2=N>>1;
l->n = N;
l->maxshift = maxshift; for (i=0;i<=maxshift;i++)
{ if (i==0)
l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0, arch); else
l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0], arch); #ifndef ENABLE_TI_DSPLIB55 if (l->kfft[i]==NULL) return0; #endif
}
l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N-(N2>>maxshift))*sizeof(kiss_twiddle_scalar)); if (l->trig==NULL) return0; for (shift=0;shift<=maxshift;shift++)
{ /* We have enough points that sine isn't necessary */ #ifdefined(FIXED_POINT) #ifndef ENABLE_QEXT for (i=0;i<N2;i++)
trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2+16384),N)); #else for (i=0;i<N2;i++)
trig[i] = (kiss_twiddle_scalar)MAX32(-2147483647,MIN32(2147483647,floor(.5+2147483648*cos(2*M_PI*(i+.125)/N)))); #endif #else for (i=0;i<N2;i++)
trig[i] = (kiss_twiddle_scalar)cos(2*PI*(i+.125)/N); #endif
trig += N2;
N2 >>= 1;
N >>= 1;
} return1;
}
void clt_mdct_clear(mdct_lookup *l, int arch)
{ int i; for (i=0;i<=l->maxshift;i++)
opus_fft_free(l->kfft[i], arch);
opus_free((kiss_twiddle_scalar*)l->trig);
}
#endif/* CUSTOM_MODES */
/* Forward MDCT trashes the input array */ #ifndef OVERRIDE_clt_mdct_forward void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const celt_coef *window, int overlap, int shift, int stride, int arch)
{ int i; int N, N2, N4;
VARDECL(kiss_fft_scalar, f);
VARDECL(kiss_fft_cpx, f2); const kiss_fft_state *st = l->kfft[shift]; const kiss_twiddle_scalar *trig;
celt_coef scale; #ifdef FIXED_POINT /* Allows us to scale with MULT16_32_Q16(), which is faster than
MULT16_32_Q15() on ARM. */ int scale_shift = st->scale_shift-1; int headroom; #endif
SAVE_STACK;
(void)arch;
scale = st->scale;
N = l->n;
trig = l->trig; for (i=0;i<shift;i++)
{
N >>= 1;
trig += N;
}
N2 = N>>1;
N4 = N>>2;
/* Post-rotate and de-shuffle from both ends of the buffer at once to make
it in-place. */
{
kiss_fft_scalar * yp0 = out+(overlap>>1);
kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2; const kiss_twiddle_scalar *t = &trig[0]; /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
middle pair will be computed twice. */ for(i=0;i<(N4+1)>>1;i++)
{
kiss_fft_scalar re, im, yr, yi;
kiss_twiddle_scalar t0, t1; /* We swap real and imag because we're using an FFT instead of an IFFT. */
re = yp0[1];
im = yp0[0];
t0 = t[i];
t1 = t[N4+i]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */
yr = PSHR32_ovflw(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), post_shift);
yi = PSHR32_ovflw(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), post_shift); /* We swap real and imag because we're using an FFT instead of an IFFT. */
re = yp1[1];
im = yp1[0];
yp0[0] = yr;
yp1[1] = yi;
t0 = t[(N4-i-1)];
t1 = t[(N2-i-1)]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */
yr = PSHR32_ovflw(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), post_shift);
yi = PSHR32_ovflw(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), post_shift);
yp1[0] = yr;
yp0[1] = yi;
yp0 += 2;
yp1 -= 2;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.