summaryrefslogtreecommitdiff
path: root/thirdparty/opus/opus_compare.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/opus/opus_compare.c')
-rw-r--r--thirdparty/opus/opus_compare.c379
1 files changed, 0 insertions, 379 deletions
diff --git a/thirdparty/opus/opus_compare.c b/thirdparty/opus/opus_compare.c
deleted file mode 100644
index 06c67d752f..0000000000
--- a/thirdparty/opus/opus_compare.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/* Copyright (c) 2011-2012 Xiph.Org Foundation, Mozilla Corporation
- Written by Jean-Marc Valin and Timothy B. Terriberry */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-#define OPUS_PI (3.14159265F)
-
-#define OPUS_COSF(_x) ((float)cos(_x))
-#define OPUS_SINF(_x) ((float)sin(_x))
-
-static void *check_alloc(void *_ptr){
- if(_ptr==NULL){
- fprintf(stderr,"Out of memory.\n");
- exit(EXIT_FAILURE);
- }
- return _ptr;
-}
-
-static void *opus_malloc(size_t _size){
- return check_alloc(malloc(_size));
-}
-
-static void *opus_realloc(void *_ptr,size_t _size){
- return check_alloc(realloc(_ptr,_size));
-}
-
-static size_t read_pcm16(float **_samples,FILE *_fin,int _nchannels){
- unsigned char buf[1024];
- float *samples;
- size_t nsamples;
- size_t csamples;
- size_t xi;
- size_t nread;
- samples=NULL;
- nsamples=csamples=0;
- for(;;){
- nread=fread(buf,2*_nchannels,1024/(2*_nchannels),_fin);
- if(nread<=0)break;
- if(nsamples+nread>csamples){
- do csamples=csamples<<1|1;
- while(nsamples+nread>csamples);
- samples=(float *)opus_realloc(samples,
- _nchannels*csamples*sizeof(*samples));
- }
- for(xi=0;xi<nread;xi++){
- int ci;
- for(ci=0;ci<_nchannels;ci++){
- int s;
- s=buf[2*(xi*_nchannels+ci)+1]<<8|buf[2*(xi*_nchannels+ci)];
- s=((s&0xFFFF)^0x8000)-0x8000;
- samples[(nsamples+xi)*_nchannels+ci]=s;
- }
- }
- nsamples+=nread;
- }
- *_samples=(float *)opus_realloc(samples,
- _nchannels*nsamples*sizeof(*samples));
- return nsamples;
-}
-
-static void band_energy(float *_out,float *_ps,const int *_bands,int _nbands,
- const float *_in,int _nchannels,size_t _nframes,int _window_sz,
- int _step,int _downsample){
- float *window;
- float *x;
- float *c;
- float *s;
- size_t xi;
- int xj;
- int ps_sz;
- window=(float *)opus_malloc((3+_nchannels)*_window_sz*sizeof(*window));
- c=window+_window_sz;
- s=c+_window_sz;
- x=s+_window_sz;
- ps_sz=_window_sz/2;
- for(xj=0;xj<_window_sz;xj++){
- window[xj]=0.5F-0.5F*OPUS_COSF((2*OPUS_PI/(_window_sz-1))*xj);
- }
- for(xj=0;xj<_window_sz;xj++){
- c[xj]=OPUS_COSF((2*OPUS_PI/_window_sz)*xj);
- }
- for(xj=0;xj<_window_sz;xj++){
- s[xj]=OPUS_SINF((2*OPUS_PI/_window_sz)*xj);
- }
- for(xi=0;xi<_nframes;xi++){
- int ci;
- int xk;
- int bi;
- for(ci=0;ci<_nchannels;ci++){
- for(xk=0;xk<_window_sz;xk++){
- x[ci*_window_sz+xk]=window[xk]*_in[(xi*_step+xk)*_nchannels+ci];
- }
- }
- for(bi=xj=0;bi<_nbands;bi++){
- float p[2]={0};
- for(;xj<_bands[bi+1];xj++){
- for(ci=0;ci<_nchannels;ci++){
- float re;
- float im;
- int ti;
- ti=0;
- re=im=0;
- for(xk=0;xk<_window_sz;xk++){
- re+=c[ti]*x[ci*_window_sz+xk];
- im-=s[ti]*x[ci*_window_sz+xk];
- ti+=xj;
- if(ti>=_window_sz)ti-=_window_sz;
- }
- re*=_downsample;
- im*=_downsample;
- _ps[(xi*ps_sz+xj)*_nchannels+ci]=re*re+im*im+100000;
- p[ci]+=_ps[(xi*ps_sz+xj)*_nchannels+ci];
- }
- }
- if(_out){
- _out[(xi*_nbands+bi)*_nchannels]=p[0]/(_bands[bi+1]-_bands[bi]);
- if(_nchannels==2){
- _out[(xi*_nbands+bi)*_nchannels+1]=p[1]/(_bands[bi+1]-_bands[bi]);
- }
- }
- }
- }
- free(window);
-}
-
-#define NBANDS (21)
-#define NFREQS (240)
-
-/*Bands on which we compute the pseudo-NMR (Bark-derived
- CELT bands).*/
-static const int BANDS[NBANDS+1]={
- 0,2,4,6,8,10,12,14,16,20,24,28,32,40,48,56,68,80,96,120,156,200
-};
-
-#define TEST_WIN_SIZE (480)
-#define TEST_WIN_STEP (120)
-
-int main(int _argc,const char **_argv){
- FILE *fin1;
- FILE *fin2;
- float *x;
- float *y;
- float *xb;
- float *X;
- float *Y;
- double err;
- float Q;
- size_t xlength;
- size_t ylength;
- size_t nframes;
- size_t xi;
- int ci;
- int xj;
- int bi;
- int nchannels;
- unsigned rate;
- int downsample;
- int ybands;
- int yfreqs;
- int max_compare;
- if(_argc<3||_argc>6){
- fprintf(stderr,"Usage: %s [-s] [-r rate2] <file1.sw> <file2.sw>\n",
- _argv[0]);
- return EXIT_FAILURE;
- }
- nchannels=1;
- if(strcmp(_argv[1],"-s")==0){
- nchannels=2;
- _argv++;
- }
- rate=48000;
- ybands=NBANDS;
- yfreqs=NFREQS;
- downsample=1;
- if(strcmp(_argv[1],"-r")==0){
- rate=atoi(_argv[2]);
- if(rate!=8000&&rate!=12000&&rate!=16000&&rate!=24000&&rate!=48000){
- fprintf(stderr,
- "Sampling rate must be 8000, 12000, 16000, 24000, or 48000\n");
- return EXIT_FAILURE;
- }
- downsample=48000/rate;
- switch(rate){
- case 8000:ybands=13;break;
- case 12000:ybands=15;break;
- case 16000:ybands=17;break;
- case 24000:ybands=19;break;
- }
- yfreqs=NFREQS/downsample;
- _argv+=2;
- }
- fin1=fopen(_argv[1],"rb");
- if(fin1==NULL){
- fprintf(stderr,"Error opening '%s'.\n",_argv[1]);
- return EXIT_FAILURE;
- }
- fin2=fopen(_argv[2],"rb");
- if(fin2==NULL){
- fprintf(stderr,"Error opening '%s'.\n",_argv[2]);
- fclose(fin1);
- return EXIT_FAILURE;
- }
- /*Read in the data and allocate scratch space.*/
- xlength=read_pcm16(&x,fin1,2);
- if(nchannels==1){
- for(xi=0;xi<xlength;xi++)x[xi]=.5*(x[2*xi]+x[2*xi+1]);
- }
- fclose(fin1);
- ylength=read_pcm16(&y,fin2,nchannels);
- fclose(fin2);
- if(xlength!=ylength*downsample){
- fprintf(stderr,"Sample counts do not match (%lu!=%lu).\n",
- (unsigned long)xlength,(unsigned long)ylength*downsample);
- return EXIT_FAILURE;
- }
- if(xlength<TEST_WIN_SIZE){
- fprintf(stderr,"Insufficient sample data (%lu<%i).\n",
- (unsigned long)xlength,TEST_WIN_SIZE);
- return EXIT_FAILURE;
- }
- nframes=(xlength-TEST_WIN_SIZE+TEST_WIN_STEP)/TEST_WIN_STEP;
- xb=(float *)opus_malloc(nframes*NBANDS*nchannels*sizeof(*xb));
- X=(float *)opus_malloc(nframes*NFREQS*nchannels*sizeof(*X));
- Y=(float *)opus_malloc(nframes*yfreqs*nchannels*sizeof(*Y));
- /*Compute the per-band spectral energy of the original signal
- and the error.*/
- band_energy(xb,X,BANDS,NBANDS,x,nchannels,nframes,
- TEST_WIN_SIZE,TEST_WIN_STEP,1);
- free(x);
- band_energy(NULL,Y,BANDS,ybands,y,nchannels,nframes,
- TEST_WIN_SIZE/downsample,TEST_WIN_STEP/downsample,downsample);
- free(y);
- for(xi=0;xi<nframes;xi++){
- /*Frequency masking (low to high): 10 dB/Bark slope.*/
- for(bi=1;bi<NBANDS;bi++){
- for(ci=0;ci<nchannels;ci++){
- xb[(xi*NBANDS+bi)*nchannels+ci]+=
- 0.1F*xb[(xi*NBANDS+bi-1)*nchannels+ci];
- }
- }
- /*Frequency masking (high to low): 15 dB/Bark slope.*/
- for(bi=NBANDS-1;bi-->0;){
- for(ci=0;ci<nchannels;ci++){
- xb[(xi*NBANDS+bi)*nchannels+ci]+=
- 0.03F*xb[(xi*NBANDS+bi+1)*nchannels+ci];
- }
- }
- if(xi>0){
- /*Temporal masking: -3 dB/2.5ms slope.*/
- for(bi=0;bi<NBANDS;bi++){
- for(ci=0;ci<nchannels;ci++){
- xb[(xi*NBANDS+bi)*nchannels+ci]+=
- 0.5F*xb[((xi-1)*NBANDS+bi)*nchannels+ci];
- }
- }
- }
- /* Allowing some cross-talk */
- if(nchannels==2){
- for(bi=0;bi<NBANDS;bi++){
- float l,r;
- l=xb[(xi*NBANDS+bi)*nchannels+0];
- r=xb[(xi*NBANDS+bi)*nchannels+1];
- xb[(xi*NBANDS+bi)*nchannels+0]+=0.01F*r;
- xb[(xi*NBANDS+bi)*nchannels+1]+=0.01F*l;
- }
- }
-
- /* Apply masking */
- for(bi=0;bi<ybands;bi++){
- for(xj=BANDS[bi];xj<BANDS[bi+1];xj++){
- for(ci=0;ci<nchannels;ci++){
- X[(xi*NFREQS+xj)*nchannels+ci]+=
- 0.1F*xb[(xi*NBANDS+bi)*nchannels+ci];
- Y[(xi*yfreqs+xj)*nchannels+ci]+=
- 0.1F*xb[(xi*NBANDS+bi)*nchannels+ci];
- }
- }
- }
- }
-
- /* Average of consecutive frames to make comparison slightly less sensitive */
- for(bi=0;bi<ybands;bi++){
- for(xj=BANDS[bi];xj<BANDS[bi+1];xj++){
- for(ci=0;ci<nchannels;ci++){
- float xtmp;
- float ytmp;
- xtmp = X[xj*nchannels+ci];
- ytmp = Y[xj*nchannels+ci];
- for(xi=1;xi<nframes;xi++){
- float xtmp2;
- float ytmp2;
- xtmp2 = X[(xi*NFREQS+xj)*nchannels+ci];
- ytmp2 = Y[(xi*yfreqs+xj)*nchannels+ci];
- X[(xi*NFREQS+xj)*nchannels+ci] += xtmp;
- Y[(xi*yfreqs+xj)*nchannels+ci] += ytmp;
- xtmp = xtmp2;
- ytmp = ytmp2;
- }
- }
- }
- }
-
- /*If working at a lower sampling rate, don't take into account the last
- 300 Hz to allow for different transition bands.
- For 12 kHz, we don't skip anything, because the last band already skips
- 400 Hz.*/
- if(rate==48000)max_compare=BANDS[NBANDS];
- else if(rate==12000)max_compare=BANDS[ybands];
- else max_compare=BANDS[ybands]-3;
- err=0;
- for(xi=0;xi<nframes;xi++){
- double Ef;
- Ef=0;
- for(bi=0;bi<ybands;bi++){
- double Eb;
- Eb=0;
- for(xj=BANDS[bi];xj<BANDS[bi+1]&&xj<max_compare;xj++){
- for(ci=0;ci<nchannels;ci++){
- float re;
- float im;
- re=Y[(xi*yfreqs+xj)*nchannels+ci]/X[(xi*NFREQS+xj)*nchannels+ci];
- im=re-log(re)-1;
- /*Make comparison less sensitive around the SILK/CELT cross-over to
- allow for mode freedom in the filters.*/
- if(xj>=79&&xj<=81)im*=0.1F;
- if(xj==80)im*=0.1F;
- Eb+=im;
- }
- }
- Eb /= (BANDS[bi+1]-BANDS[bi])*nchannels;
- Ef += Eb*Eb;
- }
- /*Using a fixed normalization value means we're willing to accept slightly
- lower quality for lower sampling rates.*/
- Ef/=NBANDS;
- Ef*=Ef;
- err+=Ef*Ef;
- }
- err=pow(err/nframes,1.0/16);
- Q=100*(1-0.5*log(1+err)/log(1.13));
- if(Q<0){
- fprintf(stderr,"Test vector FAILS\n");
- fprintf(stderr,"Internal weighted error is %f\n",err);
- return EXIT_FAILURE;
- }
- else{
- fprintf(stderr,"Test vector PASSES\n");
- fprintf(stderr,
- "Opus quality metric: %.1f %% (internal weighted error is %f)\n",Q,err);
- return EXIT_SUCCESS;
- }
-}