📄 specdi~0
字号:
/* * Compute the Itakura-Saito Distortion measures for this frame * */ (void) ComputeSpec_IS_dist (); } /* end big for loop */ if ( Eflag ) /* then print results for each element */ pr_spec_ele(); if ( rflag && !Eflag ) { /* print only Record and File Averages */ pr_spec_rec_avg(); /* print Record Average */ pr_spec_file_avg(); /* print File Average */ return; } if (!nflag) pr_spec_ele_avg(); /* print Element Average */ if ( rflag ) pr_spec_rec_avg(); /* print Record Average */ pr_spec_file_avg(); /* print File Average */ pr_spec_is_dist(); /* print Spectral Distortions */ pr_spec_tot_is_dist(); /* print TOTAL Spectral Distortions */} /* end spec_distort() */staticvoidallo_memory (rows, columns) /* allocate memory for all arrays */int rows;int columns;{ double **d_mat_alloc(); /* memory allocator */ char *calloc(); if (debug_level > 4) (void) fprintf (stderr, "allo_memory: rows = %d, columns = %d\n", rows, columns); if ( (diff_real = (float **) d_mat_alloc (rows, columns)) == NULL ) { (void) fprintf (stderr, "spec_distort: d_mat_alloc: diff_real: could not allocate memory.\n"); exit (1); } if ( (diff_imag = (float **) d_mat_alloc (rows, columns)) == NULL ) { (void) fprintf (stderr, "spec_distort: d_mat_alloc: diff_imag: could not allocate memory.\n"); exit (1); } if ( (diff_frqs = (float **) d_mat_alloc (rows, columns)) == NULL ) { (void) fprintf (stderr, "spec_distort: d_mat_alloc: diff_frqs: could not allocate memory.\n"); exit (1); } if ( (frame = (char **) d_mat_alloc (rows, 9)) == NULL ) { (void) fprintf (stderr, "spec_distort: d_mat_alloc: frame: could not allocate memory.\n"); exit (1); } if ( (freq_len = (int *) calloc ((unsigned int) rows, sizeof (int))) == NULL ) { (void) fprintf (stderr, "spec_distort: calloc: freq_len: could not allocate memory.\n"); exit (1); } if ( (IS_dist = (double *) calloc ((unsigned int) rows, sizeof (double))) == NULL ) { (void) fprintf (stderr, "spec_distort: calloc: IS_dist: could not allocate memory.\n"); exit (1); } if ( (PNIS_dist = (double *) calloc ((unsigned int) rows, sizeof (double))) == NULL ) { (void) fprintf (stderr, "spec_distort: calloc: PNIS_dist: could not allocate memory.\n"); exit (1); } if ((SpecPower1 = (double *) calloc ((unsigned int) columns, sizeof (double))) == NULL) { (void) fprintf (stderr, "spec_distort: calloc: SpecPower1: could not allocate memory.\n"); exit (1); } if ((SpecPower2 = (double *) calloc ((unsigned int) columns, sizeof (double))) == NULL) { (void) fprintf (stderr, "spec_distort: calloc: SpecPower2: could not allocate memory.\n"); exit (1); }}static char *check_frames (spec_rec1, spec_rec2)struct spec_data *spec_rec1;struct spec_data *spec_rec2;{/* * This module checks if two frames are compatible * (i.e. both frames must be either "Voiced" for "Unvoiced") * if one is "Voiced" and the other "Unvoiced", then * check_frames prints a message on stderr and exits with exit (1) * otherwise it returns a string of type of frame (" Voiced " or "Unvoiced"). * */ static char *Voiced = " Voiced "; static char *Unvoiced = "Unvoiced";/* * External Variable Used: * * int debug_level; print messages for debugging purpose * */ if (debug_level > 0) (void) fprintf (stderr, "\n"); if ( (spec_rec1->voiced == YES) && (spec_rec2->voiced == YES) ) { if (debug_level > 3) (void) fprintf (stderr, "check_frames: voiced frame\n"); return (Voiced); } else if ( (spec_rec1->voiced == NO) && (spec_rec2->voiced == NO) ) { if (debug_level > 3) (void) fprintf (stderr, "check_frames: unvoiced frame\n"); return (Unvoiced); } else { /* inconsistent frames */ (void) fprintf (stderr, "check_spec: fatal error, one voiced frame other unvoiced frame.\n"); exit (1); }} ComputeSpec_IS_dist (){ double *Fi; double *PNFi; double PF1 = 0.0; double PF2 = 0.0; double *ratio; double PFratio; int N; /* number of frequencies minus one */ int i; /* temporary variables */ int loop;/* * External Variable Used: * * int debug_level; print messages for debugging * int num_of_freqs; * int freq_format; * int spec_type; * * double *SpecPower1; Spectral Powers * double *SpecPower2; Spectral Powers * */ /* * allocate memory for: Fi, ratio, and PNFi * */ N = num_of_freqs - 1; if ((Fi = (double *) calloc((unsigned int)N + 1, sizeof(double))) == NULL ) { (void) fprintf (stderr, "compute_is_dist: calloc: could not allocate memory for Fi.\n"); exit (1); } if ((PNFi = (double *) calloc((unsigned int)N + 1, sizeof(double))) == NULL ) { (void) fprintf (stderr, "compute_is_dist: calloc: could not allocate memory for PNFi.\n"); exit (1); } if ((ratio = (double *) calloc((unsigned int)N + 1, sizeof(double))) == NULL ) { (void) fprintf (stderr, "compute_is_dist: calloc: could not allocate memory for ratio.\n"); exit (1); } if (debug_level > 2) (void) fprintf (stderr, "compute_is_dist: memory allocated, now do proper conversions.\n"); if (sflag) loop = 2; else loop = 1; while (loop--) { if (debug_level > 2) { (void) fprintf (stderr, "ComputeSpec_IS_dist: %s time around loop:", (sflag && (loop == 1)) ? "first" : "second"); if (sflag) (void) fprintf (stderr, " computing Symmetric distortion\n"); else (void) fprintf (stderr, " do not compute Symmetric distortion\n"); } for (i = 0; i < N + 1; i++) { switch (spec_type) { case ST_DB: ratio[i] = pow ((double) 10, SpecPower1[i]/10) / pow ((double) 10, SpecPower2[i]/10); break; case ST_PWR: case ST_REAL: case ST_CPLX: ratio[i] = SpecPower1[i] / SpecPower2[i]; break; default: (void) fprintf (stderr, "spec_dist: spectral type not implemented yet.\n"); exit (1); break; } if (sflag && (loop == 0)) /* second time around */ ratio[i] = 1 / ratio[i]; Fi[i] = ratio[i] + log ( 1 / ratio[i] ) - 1.0; switch (freq_format) { case SYM_CTR: case ASYM_CEN: PF1 += SpecPower1[i] / (N + 1); PF2 += SpecPower2[i] / (N + 1); break; case SYM_EDGE: case ASYM_EDGE: if (i != N) { PF1 += (0.5 / N) * (SpecPower1[i] + SpecPower1[i+1]); PF2 += (0.5 / N) * (SpecPower2[i] + SpecPower2[i+1]); } break; default: (void) fprintf (stderr, "ComputeSpec_IS_dist: frequency type not supported yet.\n"); break; } } /* end for (i = 0; i < N + 1; i++) */ if (debug_level > 5) for (i = 0; i < num_of_freqs; i++) (void) fprintf (stderr, "Fi[%d] = %f\n", i, Fi[i]); if (sflag && (loop == 0)) /* second time around */ PFratio = PF1 / PF2; else PFratio = PF2 / PF1; for (i = 0; i < N + 1; i++) { PNFi[i] = ratio[i] * PFratio - log ( ratio[i] * PFratio ) - 1.0; } switch (freq_format) { case SYM_CTR: for (i = 0; i < N + 1; i++) { IS_dist[i_rec] += (1 / (N + 1)) * Fi[i]; PNIS_dist[i_rec] += PNFi[i] / (N + 1); } break; case SYM_EDGE: for (i = 0; i < N; i++) { IS_dist[i_rec] += (0.5 / N) * (Fi[i] + Fi[i+1]); PNIS_dist[i_rec] += (0.5 / N) * (PNFi[i] + PNFi[i+1]); } break; case ASYM_CEN: for (i = 0; i < N + 1; i++) { IS_dist[i_rec] += (1 / (N + 1)) * Fi[i]; PNIS_dist[i_rec] += PNFi[i] / (N + 1); } break; case ASYM_EDGE: for (i = 0; i < N; i++) { IS_dist[i_rec] += (0.5 / N) * (Fi[i] + Fi[i+1]); PNIS_dist[i_rec] += (0.5 / N) * (PNFi[i] + PNFi[i+1]); } break; case ARB_VAR: (void) fprintf (stderr, "ComputeSpec_IS_dist: frequency format not supported yet.\n"); exit (1); break; case ARB_FIXED: (void) fprintf (stderr, "ComputeSpec_IS_dist: frequency format not supported yet.\n"); exit (1); break; default: (void) fprintf (stderr, "ComputeSpec_IS_dist: unknown frequency format.\n"); exit (1); break; } if (debug_level > 2) { (void) fprintf (stderr, "ComputeSpec_IS_dist: i_rec = %d, IS_dist = %g, PNIS_dist = %g\n", i_rec, IS_dist[i_rec], PNIS_dist[i_rec]); } } /* end while (loop--) loop */ /* * If the -s option was given, then compute the symmetric version of the * Itakura-Saito distortion measure. * */ if (sflag) { if (debug_level > 3) (void) fprintf (stderr, "compute_is_distort: now computing symmetric IS distortions.\n"); IS_dist[i_rec] /= 2; PNIS_dist[i_rec] /= 2; } if (ABS (IS_dist[i_rec]) <= ERROR) { IS_dist[i_rec] = 0.0; PNIS_dist[i_rec] = 0.0; } free ((char *) Fi); free ((char *) PNFi); free ((char *) ratio);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -