ref: a6b4e25628b3ea2671aec87058805b83c5b48b34
parent: dbeb86fd0531b618b501a76414536b27d8d4484f
author: Jean-Marc Valin <[email protected]>
date: Mon Aug 15 06:20:06 EDT 2011
Making the MDCT produce interleaved data
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -401,32 +401,24 @@
if (C==1 && !shortBlocks)
{
const int overlap = OVERLAP(mode);
- clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM);
+ clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM, 1);
} else {
const int overlap = OVERLAP(mode);
int N = mode->shortMdctSize<<LM;
int B = 1;
int b, c;
- VARDECL(opus_val32, tmp);
- SAVE_STACK;
if (shortBlocks)
{
- /*lookup = &mode->mdct[0];*/
N = mode->shortMdctSize;
B = shortBlocks;
}
- ALLOC(tmp, N, opus_val32);
c=0; do {
for (b=0;b<B;b++)
{
- int j;
- clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, tmp, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
- /* Interleaving the sub-frames */
- for (j=0;j<N;j++)
- out[(j*B+b)+c*N*B] = tmp[j];
+ /* Interleaving the sub-frames while doing the MDCTs */
+ clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B);
}
} while (++c<C);
- RESTORE_STACK;
}
}
--- a/libcelt/mdct.c
+++ b/libcelt/mdct.c
@@ -99,7 +99,8 @@
#endif /* CUSTOM_MODES */
-void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * restrict out, const opus_val16 *window, int overlap, int shift)
+void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * restrict out,
+ const opus_val16 *window, int overlap, int shift, int stride)
{
int i;
int N, N2, N4;
@@ -124,7 +125,7 @@
/* Temp pointers to make it really clear to the compiler what we're doing */
const kiss_fft_scalar * restrict xp1 = in+(overlap>>1);
const kiss_fft_scalar * restrict xp2 = in+N2-1+(overlap>>1);
- kiss_fft_scalar * restrict yp = out;
+ kiss_fft_scalar * restrict yp = f;
const opus_val16 * restrict wp1 = window+(overlap>>1);
const opus_val16 * restrict wp2 = window+(overlap>>1)-1;
for(i=0;i<(overlap>>2);i++)
@@ -160,7 +161,7 @@
}
/* Pre-rotation */
{
- kiss_fft_scalar * restrict yp = out;
+ kiss_fft_scalar * restrict yp = f;
const kiss_twiddle_scalar *t = &l->trig[0];
for(i=0;i<N4;i++)
{
@@ -176,14 +177,14 @@
}
/* N/4 complex FFT, down-scales by 4/N */
- opus_fft(l->kfft[shift], (kiss_fft_cpx *)out, (kiss_fft_cpx *)f);
+ opus_fft(l->kfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)in);
/* Post-rotate */
{
/* Temp pointers to make it really clear to the compiler what we're doing */
- const kiss_fft_scalar * restrict fp = f;
+ const kiss_fft_scalar * restrict fp = in;
kiss_fft_scalar * restrict yp1 = out;
- kiss_fft_scalar * restrict yp2 = out+N2-1;
+ kiss_fft_scalar * restrict yp2 = out+stride*(N2-1);
const kiss_twiddle_scalar *t = &l->trig[0];
/* Temp pointers to make it really clear to the compiler what we're doing */
for(i=0;i<N4;i++)
@@ -195,8 +196,8 @@
*yp1 = yr - S_MUL(yi,sine);
*yp2 = yi + S_MUL(yr,sine);;
fp += 2;
- yp1 += 2;
- yp2 -= 2;
+ yp1 += 2*stride;
+ yp2 -= 2*stride;
}
}
RESTORE_STACK;
--- a/libcelt/mdct.h
+++ b/libcelt/mdct.h
@@ -56,7 +56,8 @@
void clt_mdct_clear(mdct_lookup *l);
/** Compute a forward MDCT and scale by 4/N */
-void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out, const opus_val16 *window, int overlap, int shift);
+void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out,
+ const opus_val16 *window, int overlap, int shift, int stride);
/** Compute a backward MDCT (no scaling) and performs weighted overlap-add
(scales implicitly by 1/2) */
--- a/libcelt/tests/mdct-test.c
+++ b/libcelt/tests/mdct-test.c
@@ -93,6 +93,7 @@
size_t buflen = sizeof(kiss_fft_scalar)*nfft;
kiss_fft_scalar * in = (kiss_fft_scalar*)malloc(buflen);
+ kiss_fft_scalar * in_copy = (kiss_fft_scalar*)malloc(buflen);
kiss_fft_scalar * out= (kiss_fft_scalar*)malloc(buflen);
opus_val16 * window= (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
int k;
@@ -116,6 +117,8 @@
}
}
+ for (k=0;k<nfft;++k)
+ in_copy[k] = in[k];
/*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
if (isinverse)
@@ -125,8 +128,8 @@
clt_mdct_backward(&cfg,in,out, window, nfft/2, 0, 1);
check_inv(in,out,nfft,isinverse);
} else {
- clt_mdct_forward(&cfg,in,out,window, nfft/2, 0);
- check(in,out,nfft,isinverse);
+ clt_mdct_forward(&cfg,in,out,window, nfft/2, 0, 1);
+ check(in_copy,out,nfft,isinverse);
}
/*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/