Home | History | Annotate | Download | only in tests
      1 /* Copyright (c) 2008-2011 Xiph.Org Foundation
      2    Written by Jean-Marc Valin */
      3 /*
      4    Redistribution and use in source and binary forms, with or without
      5    modification, are permitted provided that the following conditions
      6    are met:
      7 
      8    - Redistributions of source code must retain the above copyright
      9    notice, this list of conditions and the following disclaimer.
     10 
     11    - Redistributions in binary form must reproduce the above copyright
     12    notice, this list of conditions and the following disclaimer in the
     13    documentation and/or other materials provided with the distribution.
     14 
     15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     18    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     19    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     20    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     22    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     23    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     24    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     25    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 */
     27 
     28 #ifdef HAVE_CONFIG_H
     29 #include "config.h"
     30 #endif
     31 
     32 #define SKIP_CONFIG_H
     33 
     34 #ifndef CUSTOM_MODES
     35 #define CUSTOM_MODES
     36 #endif
     37 
     38 #include <stdio.h>
     39 
     40 #define CELT_C
     41 #include "mdct.h"
     42 #include "stack_alloc.h"
     43 
     44 #include "kiss_fft.c"
     45 #include "mdct.c"
     46 #include "mathops.c"
     47 #include "entcode.c"
     48 
     49 #if defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
     50 # include "x86/x86cpu.c"
     51 #elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
     52 # include "arm/armcpu.c"
     53 # include "pitch.c"
     54 # include "celt_lpc.c"
     55 # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
     56 #  include "arm/celt_neon_intr.c"
     57 #  if defined(HAVE_ARM_NE10)
     58 #   include "arm/celt_ne10_fft.c"
     59 #   include "arm/celt_ne10_mdct.c"
     60 #  endif
     61 # endif
     62 # include "arm/arm_celt_map.c"
     63 #endif
     64 
     65 #ifndef M_PI
     66 #define M_PI 3.141592653
     67 #endif
     68 
     69 int ret = 0;
     70 void check(kiss_fft_scalar  * in,kiss_fft_scalar  * out,int nfft,int isinverse)
     71 {
     72     int bin,k;
     73     double errpow=0,sigpow=0;
     74     double snr;
     75     for (bin=0;bin<nfft/2;++bin) {
     76         double ansr = 0;
     77         double difr;
     78 
     79         for (k=0;k<nfft;++k) {
     80            double phase = 2*M_PI*(k+.5+.25*nfft)*(bin+.5)/nfft;
     81            double re = cos(phase);
     82 
     83            re /= nfft/4;
     84 
     85            ansr += in[k] * re;
     86         }
     87         /*printf ("%f %f\n", ansr, out[bin]);*/
     88         difr = ansr - out[bin];
     89         errpow += difr*difr;
     90         sigpow += ansr*ansr;
     91     }
     92     snr = 10*log10(sigpow/errpow);
     93     printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
     94     if (snr<60) {
     95        printf( "** poor snr: %f **\n", snr);
     96        ret = 1;
     97     }
     98 }
     99 
    100 void check_inv(kiss_fft_scalar  * in,kiss_fft_scalar  * out,int nfft,int isinverse)
    101 {
    102    int bin,k;
    103    double errpow=0,sigpow=0;
    104    double snr;
    105    for (bin=0;bin<nfft;++bin) {
    106       double ansr = 0;
    107       double difr;
    108 
    109       for (k=0;k<nfft/2;++k) {
    110          double phase = 2*M_PI*(bin+.5+.25*nfft)*(k+.5)/nfft;
    111          double re = cos(phase);
    112 
    113          /*re *= 2;*/
    114 
    115          ansr += in[k] * re;
    116       }
    117       /*printf ("%f %f\n", ansr, out[bin]);*/
    118       difr = ansr - out[bin];
    119       errpow += difr*difr;
    120       sigpow += ansr*ansr;
    121    }
    122    snr = 10*log10(sigpow/errpow);
    123    printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
    124    if (snr<60) {
    125       printf( "** poor snr: %f **\n", snr);
    126       ret = 1;
    127    }
    128 }
    129 
    130 
    131 void test1d(int nfft,int isinverse,int arch)
    132 {
    133     mdct_lookup cfg;
    134     size_t buflen = sizeof(kiss_fft_scalar)*nfft;
    135 
    136     kiss_fft_scalar  * in = (kiss_fft_scalar*)malloc(buflen);
    137     kiss_fft_scalar  * in_copy = (kiss_fft_scalar*)malloc(buflen);
    138     kiss_fft_scalar  * out= (kiss_fft_scalar*)malloc(buflen);
    139     opus_val16  * window= (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
    140     int k;
    141 
    142     clt_mdct_init(&cfg, nfft, 0, arch);
    143     for (k=0;k<nfft;++k) {
    144         in[k] = (rand() % 32768) - 16384;
    145     }
    146 
    147     for (k=0;k<nfft/2;++k) {
    148        window[k] = Q15ONE;
    149     }
    150     for (k=0;k<nfft;++k) {
    151        in[k] *= 32768;
    152     }
    153 
    154     if (isinverse)
    155     {
    156        for (k=0;k<nfft;++k) {
    157           in[k] /= nfft;
    158        }
    159     }
    160 
    161     for (k=0;k<nfft;++k)
    162        in_copy[k] = in[k];
    163     /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
    164 
    165     if (isinverse)
    166     {
    167        for (k=0;k<nfft;++k)
    168           out[k] = 0;
    169        clt_mdct_backward(&cfg,in,out, window, nfft/2, 0, 1, arch);
    170        /* apply TDAC because clt_mdct_backward() no longer does that */
    171        for (k=0;k<nfft/4;++k)
    172           out[nfft-k-1] = out[nfft/2+k];
    173        check_inv(in,out,nfft,isinverse);
    174     } else {
    175        clt_mdct_forward(&cfg,in,out,window, nfft/2, 0, 1, arch);
    176        check(in_copy,out,nfft,isinverse);
    177     }
    178     /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
    179 
    180 
    181     free(in);
    182     free(in_copy);
    183     free(out);
    184     free(window);
    185     clt_mdct_clear(&cfg, arch);
    186 }
    187 
    188 int main(int argc,char ** argv)
    189 {
    190     ALLOC_STACK;
    191     int arch = opus_select_arch();
    192 
    193     if (argc>1) {
    194         int k;
    195         for (k=1;k<argc;++k) {
    196             test1d(atoi(argv[k]),0,arch);
    197             test1d(atoi(argv[k]),1,arch);
    198         }
    199     }else{
    200         test1d(32,0,arch);
    201         test1d(32,1,arch);
    202         test1d(256,0,arch);
    203         test1d(256,1,arch);
    204         test1d(512,0,arch);
    205         test1d(512,1,arch);
    206         test1d(1024,0,arch);
    207         test1d(1024,1,arch);
    208         test1d(2048,0,arch);
    209         test1d(2048,1,arch);
    210 #ifndef RADIX_TWO_ONLY
    211         test1d(36,0,arch);
    212         test1d(36,1,arch);
    213         test1d(40,0,arch);
    214         test1d(40,1,arch);
    215         test1d(60,0,arch);
    216         test1d(60,1,arch);
    217         test1d(120,0,arch);
    218         test1d(120,1,arch);
    219         test1d(240,0,arch);
    220         test1d(240,1,arch);
    221         test1d(480,0,arch);
    222         test1d(480,1,arch);
    223         test1d(960,0,arch);
    224         test1d(960,1,arch);
    225         test1d(1920,0,arch);
    226         test1d(1920,1,arch);
    227 #endif
    228     }
    229     return ret;
    230 }
    231