3030#include <math.h>
3131#include <string.h>
3232
33+ #define MAX (a ,b ) ((a)>(b) ? (a) : (b))
3334#define OPUS_PI (3.14159265F)
3435
3536#define OPUS_COSF (_x ) ((float)cos(_x))
@@ -171,7 +172,7 @@ static void band_energy(float *_out,float *_ps,const int *_bands,int _nbands,
171172 }
172173 re *=_downsample ;
173174 im *=_downsample ;
174- _ps [(xi * ps_sz + xj )* _nchannels + ci ]= re * re + im * im + 100000 ;
175+ _ps [(xi * ps_sz + xj )* _nchannels + ci ]= re * re + im * im + .1 ;
175176 p [ci ]+= _ps [(xi * ps_sz + xj )* _nchannels + ci ];
176177 }
177178 }
@@ -211,8 +212,8 @@ int main(int _argc,const char **_argv){
211212 float * xb ;
212213 float * X ;
213214 float * Y ;
214- double err ;
215- float Q ;
215+ double err4 ;
216+ double err16 ;
216217 size_t xlength ;
217218 size_t ylength ;
218219 size_t nframes ;
@@ -347,6 +348,19 @@ int main(int _argc,const char **_argv){
347348 test_win_size /downsample ,test_win_step /downsample ,downsample );
348349 free (y );
349350 for (xi = 0 ;xi < nframes ;xi ++ ){
351+ float maxE [2 ]= {0 };
352+ for (bi = 0 ;bi < nbands ;bi ++ ){
353+ for (ci = 0 ;ci < nchannels ;ci ++ ){
354+ maxE [ci ] = MAX (maxE [ci ], xb [(xi * nbands + bi )* nchannels + ci ]);
355+ }
356+ }
357+ /* Allow for up to 105 dB instantaneous dynamic range (95dB here + 10dB in mask application). */
358+ for (bi = 0 ;bi < nbands ;bi ++ ){
359+ for (ci = 0 ;ci < nchannels ;ci ++ ){
360+ xb [(xi * nbands + bi )* nchannels + ci ] = MAX (3.16e-10 * maxE [ci ], xb [(xi * nbands + bi )* nchannels + ci ]);
361+ }
362+ }
363+
350364 /*Frequency masking (low to high): 10 dB/Bark slope.*/
351365 for (bi = 1 ;bi < nbands ;bi ++ ){
352366 for (ci = 0 ;ci < nchannels ;ci ++ ){
@@ -355,29 +369,40 @@ int main(int _argc,const char **_argv){
355369 }
356370 }
357371 /*Frequency masking (high to low): 15 dB/Bark slope.*/
358- for (bi = nbands - 1 ;bi -- > 0 ;){
372+ for (bi = nbands - 2 ;bi -- > 0 ;){
359373 for (ci = 0 ;ci < nchannels ;ci ++ ){
360374 xb [(xi * nbands + bi )* nchannels + ci ]+=
361375 0.03F * xb [(xi * nbands + bi + 1 )* nchannels + ci ];
362376 }
363377 }
364378 if (xi > 0 ){
365- /*Temporal masking: -3 dB/2.5ms slope.*/
379+ /* Forward temporal masking: -3 dB/2.5ms slope.*/
366380 for (bi = 0 ;bi < nbands ;bi ++ ){
367381 for (ci = 0 ;ci < nchannels ;ci ++ ){
368382 xb [(xi * nbands + bi )* nchannels + ci ]+=
369383 0.5F * xb [((xi - 1 )* nbands + bi )* nchannels + ci ];
370384 }
371385 }
372386 }
387+ }
388+ /*Backward temporal masking: -10 dB/2.5ms slope.*/
389+ for (xi = nframes - 2 ;xi -- > 0 ;){
390+ for (bi = 0 ;bi < nbands ;bi ++ ){
391+ for (ci = 0 ;ci < nchannels ;ci ++ ){
392+ xb [(xi * nbands + bi )* nchannels + ci ]+=
393+ 0.1F * xb [((xi + 1 )* nbands + bi )* nchannels + ci ];
394+ }
395+ }
396+ }
397+ for (xi = 0 ;xi < nframes ;xi ++ ){
373398 /* Allowing some cross-talk */
374399 if (nchannels == 2 ){
375400 for (bi = 0 ;bi < nbands ;bi ++ ){
376401 float l ,r ;
377402 l = xb [(xi * nbands + bi )* nchannels + 0 ];
378403 r = xb [(xi * nbands + bi )* nchannels + 1 ];
379- xb [(xi * nbands + bi )* nchannels + 0 ]+= 0.01F * r ;
380- xb [(xi * nbands + bi )* nchannels + 1 ]+= 0.01F * l ;
404+ xb [(xi * nbands + bi )* nchannels + 0 ]+= 0.000001F * r ;
405+ xb [(xi * nbands + bi )* nchannels + 1 ]+= 0.000001F * l ;
381406 }
382407 }
383408
@@ -423,10 +448,12 @@ int main(int _argc,const char **_argv){
423448 if (rate == base_rate )max_compare = BANDS [nbands ];
424449 else if (rate == 12000 )max_compare = BANDS [ybands ];
425450 else max_compare = BANDS [ybands ]- 3 ;
426- err = 0 ;
451+ err4 = 0 ;
452+ err16 = 0 ;
427453 for (xi = 0 ;xi < nframes ;xi ++ ){
428- double Ef ;
429- Ef = 0 ;
454+ double Ef2 , Ef4 ;
455+ Ef2 = 0 ;
456+ Ef4 = 0 ;
430457 for (bi = 0 ;bi < ybands ;bi ++ ){
431458 double Eb ;
432459 Eb = 0 ;
@@ -440,28 +467,22 @@ int main(int _argc,const char **_argv){
440467 }
441468 }
442469 Eb /= (BANDS [bi + 1 ]- BANDS [bi ])* nchannels ;
443- Ef += Eb * Eb ;
470+ Ef2 += Eb ;
471+ Ef4 += Eb * Eb ;
444472 }
445473 /*Using a fixed normalization value means we're willing to accept slightly
446474 lower quality for lower sampling rates.*/
447- Ef /=nbands ;
448- Ef *=Ef ;
449- err += Ef * Ef ;
475+ Ef2 /=nbands ;
476+ Ef4 /=nbands ;
477+ Ef4 *=Ef4 ;
478+ err4 += Ef2 * Ef2 ;
479+ err16 += Ef4 * Ef4 ;
450480 }
451481 free (xb );
452482 free (X );
453483 free (Y );
454- err = pow (err /nframes ,1.0 /16 );
455- Q = 100 * (1 - 0.5 * log (1 + err )/log (1.13 ));
456- if (Q < 0 ){
457- fprintf (stderr ,"Test vector FAILS\n" );
458- fprintf (stderr ,"Internal weighted error is %f\n" ,err );
459- return EXIT_FAILURE ;
460- }
461- else {
462- fprintf (stderr ,"Test vector PASSES\n" );
463- fprintf (stderr ,
464- "Opus quality metric: %.1f %% (internal weighted error is %f)\n" ,Q ,err );
465- return EXIT_SUCCESS ;
466- }
484+ err4 = pow (err4 /nframes ,1.0 /4 );
485+ err16 = pow (err16 /nframes ,1.0 /16 );
486+ fprintf (stderr , "err4 = %f, err16 = %f\n" , err4 , err16 );
487+ return EXIT_SUCCESS ;
467488}
0 commit comments