Commit 2c1d2f5b authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

MDCT now scales down by N/2 instead of N/4. The factor two is moved to the

overlap-add during synthesis.
parent b8e5c4c6
......@@ -210,9 +210,9 @@ static void compute_inv_mdcts(mdct_lookup *mdct_lookup, float *window, celt_sig_
for (j=0;j<2*N;j++)
x[j] = window[j]*x[j];
for (j=0;j<overlap;j++)
out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = x[N4+j]+mdct_overlap[C*j+c];
out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = 2*(x[N4+j]+mdct_overlap[C*j+c]);
for (j=0;j<2*N4;j++)
out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = x[j+N4+overlap];
out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = 2*x[j+N4+overlap];
for (j=0;j<overlap;j++)
mdct_overlap[C*j+c] = x[N+N4+j];
}
......
......@@ -93,8 +93,8 @@ void mdct_forward(mdct_lookup *l, celt_sig_t *in, celt_sig_t *out)
{
float re, im;
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
re = -in[N2+N4+2*i] - in[N2+N4-2*i-1];
im = -in[N4+2*i] + in[N4-2*i-1];
re = -.5*(in[N2+N4+2*i] + in[N2+N4-2*i-1]);
im = -.5*(in[N4+2*i] - in[N4-2*i-1]);
out[2*i] = re*l->trig[i] - im*l->trig[i+N4];
out[2*i+1] = im*l->trig[i] + re*l->trig[i+N4];
}
......@@ -102,8 +102,8 @@ void mdct_forward(mdct_lookup *l, celt_sig_t *in, celt_sig_t *out)
{
float re, im;
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
re = in[2*i-N4] - in[N2+N4-2*i-1];
im = -(in[N4+2*i] + in[N+N4-2*i-1]);
re = .5*(in[2*i-N4] - in[N2+N4-2*i-1]);
im = -.5*(in[N4+2*i] + in[N+N4-2*i-1]);
out[2*i] = re*l->trig[i] - im*l->trig[i+N4];
out[2*i+1] = im*l->trig[i] + re*l->trig[i+N4];
}
......@@ -147,6 +147,7 @@ void mdct_backward(mdct_lookup *l, celt_sig_t *in, celt_sig_t *out)
float re, im;
re = f[2*i];
im = f[2*i+1];
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
f[2*i] = re*l->trig[i] + im*l->trig[i+N4];
f[2*i+1] = im*l->trig[i] - re*l->trig[i+N4];
}
......
......@@ -5,11 +5,12 @@
#include <stdio.h>
#include "kiss_fft.h"
int ret = 0;
void check(kiss_fft_cpx * in,kiss_fft_cpx * out,int nfft,int isinverse)
{
int bin,k;
double errpow=0,sigpow=0;
double errpow=0,sigpow=0, snr;
for (bin=0;bin<nfft;++bin) {
double ansr = 0;
......@@ -41,7 +42,12 @@ void check(kiss_fft_cpx * in,kiss_fft_cpx * out,int nfft,int isinverse)
errpow += difr*difr + difi*difi;
sigpow += ansr*ansr+ansi*ansi;
}
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,10*log10(sigpow/errpow) );
snr = 10*log10(sigpow/errpow);
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
if (snr<60) {
printf( "** poor snr: %f ** \n", snr);
ret = 1;
}
}
void test1d(int nfft,int isinverse)
......@@ -109,5 +115,5 @@ int main(int argc,char ** argv)
test1d(105,0);
test1d(105,1);
}
return 0;
return ret;
}
......@@ -5,12 +5,12 @@
#include <stdio.h>
#include "mdct.h"
int ret = 0;
void check(float * in,float * out,int nfft,int isinverse)
{
int bin,k;
double errpow=0,sigpow=0;
double snr;
for (bin=0;bin<nfft/2;++bin) {
double ansr = 0;
double difr;
......@@ -19,7 +19,7 @@ void check(float * in,float * out,int nfft,int isinverse)
double phase = 2*M_PI*(k+.5+.25*nfft)*(bin+.5)/nfft;
double re = cos(phase);
re /= nfft/4;
re /= nfft/2;
ansr += in[k] * re;
}
......@@ -28,14 +28,19 @@ void check(float * in,float * out,int nfft,int isinverse)
errpow += difr*difr;
sigpow += ansr*ansr;
}
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,10*log10(sigpow/errpow) );
snr = 10*log10(sigpow/errpow);
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
if (snr<60) {
printf( "** poor snr: %f **\n", snr);
ret = 1;
}
}
void check_inv(float * in,float * out,int nfft,int isinverse)
{
int bin,k;
double errpow=0,sigpow=0;
double snr;
for (bin=0;bin<nfft;++bin) {
double ansr = 0;
double difr;
......@@ -43,7 +48,9 @@ void check_inv(float * in,float * out,int nfft,int isinverse)
for (k=0;k<nfft/2;++k) {
double phase = 2*M_PI*(bin+.5+.25*nfft)*(k+.5)/nfft;
double re = cos(phase);
//re *= 2;
ansr += in[k] * re;
}
/*printf ("%f %f\n", ansr, out[bin]);*/
......@@ -51,7 +58,12 @@ void check_inv(float * in,float * out,int nfft,int isinverse)
errpow += difr*difr;
sigpow += ansr*ansr;
}
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,10*log10(sigpow/errpow) );
snr = 10*log10(sigpow/errpow);
printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
if (snr<60) {
printf( "** poor snr: %f **\n", snr);
ret = 1;
}
}
......@@ -112,13 +124,20 @@ int main(int argc,char ** argv)
}else{
test1d(32,0);
test1d(32,1);
exit(0);
test1d(36,0);
test1d(36,1);
test1d(50,0);
test1d(50,1);
test1d(40,0);
test1d(40,1);
test1d(56,0);
test1d(56,1);
test1d(120,0);
test1d(120,1);
test1d(240,0);
test1d(240,1);
test1d(256,0);
test1d(256,1);
test1d(480,0);
test1d(480,1);
test1d(512,0);
test1d(512,1);
}
return 0;
return ret;
}
......@@ -10,6 +10,8 @@
#include <stdio.h>
#include <string.h>
int ret=0;
static double cputime(void)
{
struct tms t;
......@@ -44,9 +46,9 @@ double snr_compare( kiss_fft_cpx * vec1,kiss_fft_scalar * vec2, int n)
}
snr = 10*log10( sigpow / noisepow );
if (snr<10) {
printf( "\npoor snr: %f\n", snr);
exit(1);
if (snr<60) {
printf( "** poor snr: %f **\n", snr);
ret = 1;
}
return snr;
}
......@@ -63,9 +65,9 @@ double snr_compare_scal( kiss_fft_scalar * vec1,kiss_fft_scalar * vec2, int n)
noisepow += err * err;
}
snr = 10*log10( sigpow / noisepow );
if (snr<10) {
if (snr<60) {
printf( "\npoor snr: %f\n", snr);
exit(1);
ret = 1;
}
return snr;
}
......@@ -184,5 +186,5 @@ int main(void)
free(kiss_fft_state);
free(kiss_fftr_state);
return 0;
return ret;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment