Fix --enable-fixed-point-debug.
[opus.git] / celt / tests / test_unit_mdct.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #define SKIP_CONFIG_H
6
7 #ifndef CUSTOM_MODES
8 #define CUSTOM_MODES
9 #endif
10
11 #include <stdio.h>
12
13 #define CELT_C
14 #include "mdct.h"
15 #include "stack_alloc.h"
16
17 #include "kiss_fft.c"
18 #include "mdct.c"
19 #include "mathops.c"
20 #include "entcode.c"
21
22 #ifndef M_PI
23 #define M_PI 3.141592653
24 #endif
25
26 int ret = 0;
27 void check(kiss_fft_scalar  * in,kiss_fft_scalar  * out,int nfft,int isinverse)
28 {
29     int bin,k;
30     double errpow=0,sigpow=0;
31     double snr;
32     for (bin=0;bin<nfft/2;++bin) {
33         double ansr = 0;
34         double difr;
35
36         for (k=0;k<nfft;++k) {
37            double phase = 2*M_PI*(k+.5+.25*nfft)*(bin+.5)/nfft;
38            double re = cos(phase);
39
40            re /= nfft/4;
41
42            ansr += in[k] * re;
43         }
44         /*printf ("%f %f\n", ansr, out[bin]);*/
45         difr = ansr - out[bin];
46         errpow += difr*difr;
47         sigpow += ansr*ansr;
48     }
49     snr = 10*log10(sigpow/errpow);
50     printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
51     if (snr<60) {
52        printf( "** poor snr: %f **\n", snr);
53        ret = 1;
54     }
55 }
56
57 void check_inv(kiss_fft_scalar  * in,kiss_fft_scalar  * out,int nfft,int isinverse)
58 {
59    int bin,k;
60    double errpow=0,sigpow=0;
61    double snr;
62    for (bin=0;bin<nfft;++bin) {
63       double ansr = 0;
64       double difr;
65
66       for (k=0;k<nfft/2;++k) {
67          double phase = 2*M_PI*(bin+.5+.25*nfft)*(k+.5)/nfft;
68          double re = cos(phase);
69
70          /*re *= 2;*/
71
72          ansr += in[k] * re;
73       }
74       /*printf ("%f %f\n", ansr, out[bin]);*/
75       difr = ansr - out[bin];
76       errpow += difr*difr;
77       sigpow += ansr*ansr;
78    }
79    snr = 10*log10(sigpow/errpow);
80    printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
81    if (snr<60) {
82       printf( "** poor snr: %f **\n", snr);
83       ret = 1;
84    }
85 }
86
87
88 void test1d(int nfft,int isinverse)
89 {
90     mdct_lookup cfg;
91     size_t buflen = sizeof(kiss_fft_scalar)*nfft;
92
93     kiss_fft_scalar  * in = (kiss_fft_scalar*)malloc(buflen);
94     kiss_fft_scalar  * in_copy = (kiss_fft_scalar*)malloc(buflen);
95     kiss_fft_scalar  * out= (kiss_fft_scalar*)malloc(buflen);
96     opus_val16  * window= (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
97     int k;
98
99     clt_mdct_init(&cfg, nfft, 0);
100     for (k=0;k<nfft;++k) {
101         in[k] = (rand() % 32768) - 16384;
102     }
103
104     for (k=0;k<nfft/2;++k) {
105        window[k] = Q15ONE;
106     }
107     for (k=0;k<nfft;++k) {
108        in[k] *= 32768;
109     }
110
111     if (isinverse)
112     {
113        for (k=0;k<nfft;++k) {
114           in[k] /= nfft;
115        }
116     }
117
118     for (k=0;k<nfft;++k)
119        in_copy[k] = in[k];
120     /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
121
122     if (isinverse)
123     {
124        for (k=0;k<nfft;++k)
125           out[k] = 0;
126        clt_mdct_backward(&cfg,in,out, window, nfft/2, 0, 1);
127        check_inv(in,out,nfft,isinverse);
128     } else {
129        clt_mdct_forward(&cfg,in,out,window, nfft/2, 0, 1);
130        check(in_copy,out,nfft,isinverse);
131     }
132     /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
133
134
135     free(in);
136     free(out);
137     clt_mdct_clear(&cfg);
138 }
139
140 int main(int argc,char ** argv)
141 {
142     ALLOC_STACK;
143     if (argc>1) {
144         int k;
145         for (k=1;k<argc;++k) {
146             test1d(atoi(argv[k]),0);
147             test1d(atoi(argv[k]),1);
148         }
149     }else{
150         test1d(32,0);
151         test1d(32,1);
152         test1d(256,0);
153         test1d(256,1);
154         test1d(512,0);
155         test1d(512,1);
156 #ifndef RADIX_TWO_ONLY
157         test1d(40,0);
158         test1d(40,1);
159         test1d(120,0);
160         test1d(120,1);
161         test1d(240,0);
162         test1d(240,1);
163         test1d(480,0);
164         test1d(480,1);
165 #endif
166     }
167     return ret;
168 }