ref: 268575766d838498e36e33ae27f35abf34f0215a
parent: abbb80c6226e0dcca8c3b3e96d2180c25385c569
author: Jean-Marc Valin <jeanmarcv@google.com>
date: Wed Jul 16 10:21:35 EDT 2025
dred_compare: add feature comparison
--- a/dnn/dred_compare.c
+++ b/dnn/dred_compare.c
@@ -81,6 +81,18 @@
}
}
+static void buf_to_float(const unsigned char *buf, float *x, int len) {
+ float_bits s;
+ int i;
+ for (i=0;i<len;i++) {
+ s.i=(unsigned)buf[4*i+3]<<24
+ |buf[4*i+2]<<16
+ |buf[4*i+1]<<8
+ |buf[4*i];
+ x[i] = s.f;
+ }
+}
+
static size_t read_pcm(float **_samples,FILE *_fin,int _nchannels,
int format){
unsigned char buf[1024];
@@ -204,8 +216,13 @@
void usage(const char *_argv0) {
- fprintf(stderr,"Usage: %s [-s16|-s24|-f32] [-thresholds err4 err16]"
- " <file1.sw> <file2.sw>\n", _argv0);
+ fprintf(stderr,"Usage: %s -audio [-s16|-s24|-f32]"
+ " [-thresholds err4 err16 pitch]"
+ " <file1> <file2>\n", _argv0);
+ fprintf(stderr," %s -features"
+ " [-thresholds tot max pitch]"
+ " <file1.f32> <file2.f32>\n", _argv0);
+
}
/* Taken from ancient CELT code */
@@ -262,7 +279,7 @@
}
#define LOUDNESS 0.2f
-int main(int _argc,const char **_argv){
+int compare_audio(int _argc,const char **_argv, const char *argv0){
FILE *fin1;
FILE *fin2;
float *x;
@@ -290,7 +307,6 @@
int max_compare;
int format;
int skip=0;
- const char *argv0 = _argv[0];
double err4_threshold=-1, err16_threshold=-1, pitch_threshold=-1;
int compare_thresholds=0;
float decayL[NFREQS], decayR[NFREQS];
@@ -528,9 +544,111 @@
fprintf(stderr, "Comparison PASSED\n");
} else {
fprintf(stderr, "*** Comparison FAILED ***"
- " (thresholds were %f %f)\n", err4_threshold, err16_threshold);
+ " (thresholds were %f %f %f)\n", err4_threshold, err16_threshold, pitch_threshold);
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
+}
+
+#define NB_FEATURES 20
+
+int compare_features(int _argc,const char **_argv, const char *argv0){
+ FILE *fin1=NULL;
+ FILE *fin2=NULL;
+ int i;
+ float mse[NB_FEATURES]={0};
+ int count=0;
+ int pitch_count=0;
+ float pitch_error=0;
+ float tot_error=0, max_error=0;
+ float tot_threshold=-1, max_threshold=-1, pitch_threshold=-1;
+ int compare_thresholds=0;
+ if(strcmp(_argv[1],"-thresholds")==0){
+ if (_argc < 7) {
+ usage(argv0);
+ return EXIT_FAILURE;
+ }
+ tot_threshold=atof(_argv[2]);
+ max_threshold=atof(_argv[3]);
+ pitch_threshold=atof(_argv[4]);
+ compare_thresholds=1;
+ _argv+=4;
+ _argc-=4;
+ }
+ if(_argc!=3) {
+ usage(argv0);
+ return EXIT_FAILURE;
+ }
+ 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;
+ }
+ while (1) {
+ int ret;
+ float x[NB_FEATURES], y[NB_FEATURES];
+ unsigned char buf[NB_FEATURES*4];
+ ret = fread(buf, NB_FEATURES*4, 1, fin1);
+ if (ret != 1) break;
+ buf_to_float(buf, x, NB_FEATURES);
+ ret = fread(buf, NB_FEATURES*4, 1, fin2);
+ if (ret != 1) {
+ fprintf(stderr, "Error: truncated test file\n");
+ return EXIT_FAILURE;
+ }
+ buf_to_float(buf, y, NB_FEATURES);
+ for (i=0;i<NB_FEATURES;i++) {
+ float e = (x[i]-y[i]);
+ mse[i] += e*e;
+ }
+ if (x[NB_FEATURES-1] > .2) {
+ pitch_error += fabs(x[NB_FEATURES-2]-y[NB_FEATURES-2]);
+ pitch_count++;
+ }
+ count++;
+ }
+ pitch_error /= pitch_count;
+ for(i=0;i<NB_FEATURES;i++) {
+ mse[i] /= count;
+ if (i != NB_FEATURES-2) {
+ tot_error += mse[i];
+ max_error = MAX(max_error, mse[i]);
+ }
+ }
+ tot_error = sqrt(tot_error);
+ max_error = sqrt(max_error);
+ fprintf(stderr, "total = %f, max = %f, pitch = %f\n", tot_error, max_error, pitch_error);
+ if (compare_thresholds) {
+ if (tot_error <= tot_threshold && max_error <= max_threshold && pitch_error <= pitch_threshold) {
+ fprintf(stderr, "Comparison PASSED\n");
+ } else {
+ fprintf(stderr, "*** Comparison FAILED ***"
+ " (thresholds were %f %f %f)\n", tot_threshold, max_threshold, pitch_threshold);
+ return EXIT_FAILURE;
+ }
+ }
+ if (fin1) fclose(fin1);
+ if (fin2) fclose(fin2);
+ return EXIT_SUCCESS;
+}
+
+int main(int _argc,const char **_argv){
+ if (_argc<3) {
+ usage(_argv[0]);
+ } else if (strcmp(_argv[1], "-audio")==0) {
+ return compare_audio(_argc-1, _argv+1, _argv[0]);
+ } else if (strcmp(_argv[1], "-features")==0) {
+ return compare_features(_argc-1, _argv+1, _argv[0]);
+ } else {
+ fprintf(stderr, "%s: First argument must be either -audio or -features\n\n", _argv[0]);
+ usage(_argv[0]);
+ }
+ return EXIT_FAILURE;
}
--
⑨