mdct_backward now does the WOLA, so there isn't much left in compute_inv_mdcts
This commit is contained in:
parent
4989c1212a
commit
8ddd7f400d
3 changed files with 55 additions and 34 deletions
|
@ -102,7 +102,7 @@ CELTEncoder EXPORT *celt_encoder_create(const CELTMode *mode)
|
||||||
|
|
||||||
st->in_mem = celt_alloc(st->overlap*C*sizeof(celt_sig_t));
|
st->in_mem = celt_alloc(st->overlap*C*sizeof(celt_sig_t));
|
||||||
st->mdct_overlap = celt_alloc(st->overlap*C*sizeof(celt_sig_t));
|
st->mdct_overlap = celt_alloc(st->overlap*C*sizeof(celt_sig_t));
|
||||||
st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(celt_sig_t));
|
st->out_mem = celt_alloc((MAX_PERIOD+st->overlap)*C*sizeof(celt_sig_t));
|
||||||
|
|
||||||
st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
|
st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
|
||||||
|
|
||||||
|
@ -185,37 +185,39 @@ static void compute_mdcts(const CELTMode *mode, const celt_word16_t * restrict w
|
||||||
static void compute_inv_mdcts(const CELTMode *mode, const celt_word16_t * restrict window, celt_sig_t *X, celt_sig_t * restrict out_mem, celt_sig_t * restrict mdct_overlap)
|
static void compute_inv_mdcts(const CELTMode *mode, const celt_word16_t * restrict window, celt_sig_t *X, celt_sig_t * restrict out_mem, celt_sig_t * restrict mdct_overlap)
|
||||||
{
|
{
|
||||||
int c, N4;
|
int c, N4;
|
||||||
VARDECL(celt_word32_t, x);
|
|
||||||
VARDECL(celt_word32_t, tmp);
|
|
||||||
const int C = CHANNELS(mode);
|
const int C = CHANNELS(mode);
|
||||||
const mdct_lookup *lookup = MDCT(mode);
|
const mdct_lookup *lookup = MDCT(mode);
|
||||||
const int N = FRAMESIZE(mode);
|
const int N = FRAMESIZE(mode);
|
||||||
const int overlap = OVERLAP(mode);
|
const int overlap = OVERLAP(mode);
|
||||||
SAVE_STACK;
|
|
||||||
ALLOC(x, 2*N, celt_word32_t);
|
|
||||||
ALLOC(tmp, N, celt_word32_t);
|
|
||||||
N4 = (N-overlap)>>1;
|
N4 = (N-overlap)>>1;
|
||||||
for (c=0;c<C;c++)
|
for (c=0;c<C;c++)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
if (C==1) {
|
if (C==1) {
|
||||||
mdct_backward(lookup, X, x, window, overlap);
|
mdct_backward(lookup, X, out_mem+C*(MAX_PERIOD-N-N4), window, overlap);
|
||||||
} else {
|
} else {
|
||||||
|
VARDECL(celt_word32_t, x);
|
||||||
|
VARDECL(celt_word32_t, tmp);
|
||||||
|
SAVE_STACK;
|
||||||
|
ALLOC(x, 2*N, celt_word32_t);
|
||||||
|
ALLOC(tmp, N, celt_word32_t);
|
||||||
/* De-interleaving the sub-frames */
|
/* De-interleaving the sub-frames */
|
||||||
for (j=0;j<N;j++)
|
for (j=0;j<N;j++)
|
||||||
tmp[j] = X[C*j+c];
|
tmp[j] = X[C*j+c];
|
||||||
|
/* Prevents problems from the imdct doing the overlap-add */
|
||||||
|
CELT_MEMSET(x+N4, 0, overlap);
|
||||||
mdct_backward(lookup, tmp, x, window, overlap);
|
mdct_backward(lookup, tmp, x, window, overlap);
|
||||||
}
|
|
||||||
/* The first and last part would need to be set to zero if we actually
|
/* The first and last part would need to be set to zero if we actually
|
||||||
wanted to use them. */
|
wanted to use them. */
|
||||||
for (j=0;j<overlap;j++)
|
for (j=0;j<overlap;j++)
|
||||||
out_mem[C*(MAX_PERIOD-N)+C*j+c] = mdct_overlap[C*j+c]+x[j+N4];
|
out_mem[C*(MAX_PERIOD-N)+C*j+c] += x[j+N4];
|
||||||
for (j=0;j<overlap;j++)
|
for (j=0;j<overlap;j++)
|
||||||
mdct_overlap[C*(overlap-j-1)+c] = x[2*N-j-N4-1];
|
out_mem[C*(MAX_PERIOD)+C*(overlap-j-1)+c] = x[2*N-j-N4-1];
|
||||||
for (j=0;j<2*N4;j++)
|
for (j=0;j<2*N4;j++)
|
||||||
out_mem[C*(MAX_PERIOD-N)+C*(j+overlap)+c] = x[j+N4+overlap];
|
out_mem[C*(MAX_PERIOD-N)+C*(j+overlap)+c] = x[j+N4+overlap];
|
||||||
|
RESTORE_STACK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RESTORE_STACK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int EXPORT celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned char *compressed, int nbCompressedBytes)
|
int EXPORT celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned char *compressed, int nbCompressedBytes)
|
||||||
|
@ -358,7 +360,7 @@ int EXPORT celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, u
|
||||||
denormalise_bands(st->mode, X, freq, bandE);
|
denormalise_bands(st->mode, X, freq, bandE);
|
||||||
|
|
||||||
|
|
||||||
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD-N));
|
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
|
||||||
|
|
||||||
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap);
|
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap);
|
||||||
/* De-emphasis and put everything back at the right place in the synthesis history */
|
/* De-emphasis and put everything back at the right place in the synthesis history */
|
||||||
|
@ -462,7 +464,7 @@ CELTDecoder EXPORT *celt_decoder_create(const CELTMode *mode)
|
||||||
st->overlap = mode->overlap;
|
st->overlap = mode->overlap;
|
||||||
|
|
||||||
st->mdct_overlap = celt_alloc(st->overlap*C*sizeof(celt_sig_t));
|
st->mdct_overlap = celt_alloc(st->overlap*C*sizeof(celt_sig_t));
|
||||||
st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(celt_sig_t));
|
st->out_mem = celt_alloc((MAX_PERIOD+st->overlap)*C*sizeof(celt_sig_t));
|
||||||
|
|
||||||
st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
|
st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
|
||||||
|
|
||||||
|
@ -614,7 +616,7 @@ int EXPORT celt_decode(CELTDecoder * restrict st, unsigned char *data, int len,
|
||||||
denormalise_bands(st->mode, X, freq, bandE);
|
denormalise_bands(st->mode, X, freq, bandE);
|
||||||
|
|
||||||
|
|
||||||
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD-N));
|
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
|
||||||
/* Compute inverse MDCTs */
|
/* Compute inverse MDCTs */
|
||||||
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap);
|
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap);
|
||||||
|
|
||||||
|
|
|
@ -189,18 +189,20 @@ void mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *
|
||||||
int i;
|
int i;
|
||||||
int N, N2, N4;
|
int N, N2, N4;
|
||||||
VARDECL(kiss_fft_scalar, f);
|
VARDECL(kiss_fft_scalar, f);
|
||||||
|
VARDECL(kiss_fft_scalar, f2);
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
N = l->n;
|
N = l->n;
|
||||||
N2 = N>>1;
|
N2 = N>>1;
|
||||||
N4 = N>>2;
|
N4 = N>>2;
|
||||||
ALLOC(f, N2, kiss_fft_scalar);
|
ALLOC(f, N2, kiss_fft_scalar);
|
||||||
|
ALLOC(f2, N2, kiss_fft_scalar);
|
||||||
|
|
||||||
/* Pre-rotate */
|
/* Pre-rotate */
|
||||||
{
|
{
|
||||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||||
const kiss_fft_scalar * restrict xp1 = in;
|
const kiss_fft_scalar * restrict xp1 = in;
|
||||||
const kiss_fft_scalar * restrict xp2 = in+N2-1;
|
const kiss_fft_scalar * restrict xp2 = in+N2-1;
|
||||||
kiss_fft_scalar * restrict yp = out;
|
kiss_fft_scalar * restrict yp = f2;
|
||||||
kiss_fft_scalar *t = &l->trig[0];
|
kiss_fft_scalar *t = &l->trig[0];
|
||||||
for(i=0;i<N4;i++)
|
for(i=0;i<N4;i++)
|
||||||
{
|
{
|
||||||
|
@ -213,7 +215,7 @@ void mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inverse N/4 complex FFT. This one should *not* downscale even in fixed-point */
|
/* Inverse N/4 complex FFT. This one should *not* downscale even in fixed-point */
|
||||||
cpx32_ifft(l->kfft, out, f, N4);
|
cpx32_ifft(l->kfft, f2, f, N4);
|
||||||
|
|
||||||
/* Post-rotate */
|
/* Post-rotate */
|
||||||
{
|
{
|
||||||
|
@ -235,7 +237,7 @@ void mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *
|
||||||
{
|
{
|
||||||
const kiss_fft_scalar * restrict fp1 = f;
|
const kiss_fft_scalar * restrict fp1 = f;
|
||||||
const kiss_fft_scalar * restrict fp2 = f+N2-1;
|
const kiss_fft_scalar * restrict fp2 = f+N2-1;
|
||||||
kiss_fft_scalar * restrict yp = out+N4;
|
kiss_fft_scalar * restrict yp = f2;
|
||||||
for(i = 0; i < N4; i++)
|
for(i = 0; i < N4; i++)
|
||||||
{
|
{
|
||||||
*yp++ =-*fp1*2;
|
*yp++ =-*fp1*2;
|
||||||
|
@ -247,28 +249,45 @@ void mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *
|
||||||
|
|
||||||
/* Mirror on both sides for TDAC */
|
/* Mirror on both sides for TDAC */
|
||||||
{
|
{
|
||||||
|
kiss_fft_scalar * restrict fp1 = f2+N4-1;
|
||||||
kiss_fft_scalar * restrict xp1 = out+N2-1;
|
kiss_fft_scalar * restrict xp1 = out+N2-1;
|
||||||
kiss_fft_scalar * restrict xp2 = out+N2;
|
|
||||||
kiss_fft_scalar * restrict yp1 = out+N4-overlap/2;
|
kiss_fft_scalar * restrict yp1 = out+N4-overlap/2;
|
||||||
|
const celt_word16_t * restrict wp1 = window;
|
||||||
|
const celt_word16_t * restrict wp2 = window+overlap-1;
|
||||||
|
for(i = 0; i< N4-overlap/2; i++)
|
||||||
|
{
|
||||||
|
*xp1 = *fp1;
|
||||||
|
xp1--;
|
||||||
|
fp1--;
|
||||||
|
}
|
||||||
|
for(; i < N4; i++)
|
||||||
|
{
|
||||||
|
kiss_fft_scalar x1;
|
||||||
|
x1 = *fp1--;
|
||||||
|
*yp1++ +=-MULT16_32_Q15(*wp1, x1);
|
||||||
|
*xp1-- += MULT16_32_Q15(*wp2, x1);
|
||||||
|
wp1++;
|
||||||
|
wp2--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
kiss_fft_scalar * restrict fp2 = f2+N4;
|
||||||
|
kiss_fft_scalar * restrict xp2 = out+N2;
|
||||||
kiss_fft_scalar * restrict yp2 = out+N-1-(N4-overlap/2);
|
kiss_fft_scalar * restrict yp2 = out+N-1-(N4-overlap/2);
|
||||||
const celt_word16_t * restrict wp1 = window;
|
const celt_word16_t * restrict wp1 = window;
|
||||||
const celt_word16_t * restrict wp2 = window+overlap-1;
|
const celt_word16_t * restrict wp2 = window+overlap-1;
|
||||||
for(i = 0; i< N4-overlap/2; i++)
|
for(i = 0; i< N4-overlap/2; i++)
|
||||||
{
|
{
|
||||||
*xp1 = *xp1;
|
*xp2 = *fp2;
|
||||||
*xp2 = *xp2;
|
|
||||||
xp1--;
|
|
||||||
xp2++;
|
xp2++;
|
||||||
|
fp2++;
|
||||||
}
|
}
|
||||||
for(; i < N4; i++)
|
for(; i < N4; i++)
|
||||||
{
|
{
|
||||||
kiss_fft_scalar x1, x2;
|
kiss_fft_scalar x2;
|
||||||
x1 = *xp1;
|
x2 = *fp2++;
|
||||||
x2 = *xp2;
|
*yp2-- = MULT16_32_Q15(*wp1, x2);
|
||||||
*yp1++ =-MULT16_32_Q15(*wp1, x1);
|
*xp2++ = MULT16_32_Q15(*wp2, x2);
|
||||||
*yp2-- = MULT16_32_Q15(*wp1, x2);
|
|
||||||
*xp1-- = MULT16_32_Q15(*wp2, x1);
|
|
||||||
*xp2++ = MULT16_32_Q15(*wp2, x2);
|
|
||||||
wp1++;
|
wp1++;
|
||||||
wp2--;
|
wp2--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ void mdct_clear(mdct_lookup *l);
|
||||||
/** Compute a forward MDCT and scale by 2/N */
|
/** Compute a forward MDCT and scale by 2/N */
|
||||||
void mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out, const celt_word16_t *window, int overlap);
|
void mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out, const celt_word16_t *window, int overlap);
|
||||||
|
|
||||||
/** Compute a backward MDCT (no scaling) */
|
/** Compute a backward MDCT (no scaling) and performs weighted overlap-add */
|
||||||
void mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out, const celt_word16_t * restrict window, int overlap);
|
void mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out, const celt_word16_t * restrict window, int overlap);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue