📄 specdi~0
字号:
/* spec_distort - compute distortion measures between two ESPS SPEC files * * This material contains proprietary software of Entropic Speech, Inc. * Any reproduction, distribution, or publication without the prior * written permission of Entropic Speech, Inc. is strictly prohibited. * Any public distribution of copies of this work authorized in writing by * Entropic Speech, Inc. must bear the notice * * "Copyright (c) 1987 Entropic Speech, Inc.; All rights reserved" * * Module Name: spec_distort * * Written By: Ajaipal S. Virdy * * * Purpose: compute distortion measure for speech processes * * */#ifdef SCCS static char *sccs_id = "@(#)specdistort. 3.1 11/3/87 ESI";#endif#include <stdio.h>#include <esps/esps.h>#include <esps/spec.h>#include <math.h>#include <esps/unix.h>/* declare external variables for modules in distort */#include "distort.h"/* * G L O B A L V A R I A B L E S * * used in spec_distort and print_distort. * */char **frame; /* string for "Voiced" or "Unvoiced" frames */int *freq_len; /* length of array re_spec_val, im_spec_val, * and frqs_len for each record */double *SpecPower1; /* Spectral Powers */double *SpecPower2; /* Spectral Powers */float **diff_real; /* difference between real part of spectral value */float **diff_imag; /* difference between imag. part of spectral value */float **diff_frqs; /* difference between frequencies of spectral value */float tot_real = 0.0; /* variable to sum all re_spec_val */float tot_imag = 0.0; /* variable to sum all im_spec_val */float tot_frqs = 0.0; /* variable to sum all frqs */double *IS_dist; /* Itakura-Saito (IS) distortion measure vector */double *PNIS_dist; /* Power-Normalized IS distortion measure vector */#define ERROR 1.0e-05 /* anything less than this is zero */int freq_format;int spec_type;int num_of_freqs;int i_rec; /* current record */int rec_num; /* current record number */int ele_num; /* current element number */#define MAG(A,B) ( sqrt ((A)*(A) + (B)*(B)) )/* * U N I X * R O U T I N E S * R E F E R E N C E D */double log();double pow();double sqrt();/* * E S P S * R O U T I N E S * R E F E R E N C E D */short get_rec_len();/* * L O C A L * R O U T I N E S * R E F E R E N C E D */void gen_distort();void spec_distort(){ struct spec_data *spec_rec1; /* data structure for file1 */ struct spec_data *spec_rec2; /* data structure for file2 */ struct spec_header *spec1 = f1h->hd.spec; /* temporary pointers */ struct spec_header *spec2 = f2h->hd.spec; /* temporary pointers */ int rows; /* size of row to allocate */ int columns; /* size of column to allocate */ int j; /* temporary indices */ static char *check_frames(); static void allo_memory();/* * Accessed: char *spec_type_codes[]; from <esps/spec.h> * *//* * If the -e option was given then treat the SPEC file as a * "generic" file. * */ if ( eflag ) { (void) gen_distort(); return; }/* * Save freq_format and spec_type of the spectral record file. * The following should be the same in both files; they have already * been checked in check_spec (); * */ freq_format = spec1->freq_format; spec_type = spec1->spec_type; num_of_freqs = spec1->num_freqs - 1; /* maximum number of freqs */ if ( debug_level > 3) (void) fprintf (stderr, "\n"); if ( get_rec_len (f1h) != get_rec_len (f2h) ) { (void) fprintf (stderr, "spec_distort: warning, elements per record not equal in both files.\n"); } else if (debug_level > 4) (void) fprintf (stderr, "spec_distort: same number of elements in these SPEC files.\n"); /* skip appropiate number of records (as specified by the -f option) */ spec_rec1 = allo_spec_rec (f1h); spec_rec2 = allo_spec_rec (f2h); if (debug_level > 1) (void) fprintf (stderr, "spec_distort: skipping %d records.\n", s_rec - 1);/* already skipped appropriate number of records *//* * This is the way I originally skipped records: * * for ( rec_num = 1; rec_num < s_rec; rec_num++ ) { * * if ( get_spec_rec (spec_rec1, f1h, f1p) == EOF ) { * (void) fprintf (stderr, * "spec_distort: not enough records in %s.\n", f1str); * exit (1); * } * if ( get_spec_rec (spec_rec2, f2h, f2p) == EOF ) { * (void) fprintf (stderr, * "spec_distort: not enough records in %s.\n", f2str); * exit (1); * } * * } \* end for *\ */ if (spec1->order_vcd != spec2->order_vcd) if ( f1h->hd.spec->order_vcd != f2h->hd.spec->order_vcd ) { (void) fprintf (stderr, "spec_distort: warning, order_vcd not equal in %s and %s.\n", f1str, f2str); } if ( spec1->order_unvcd != spec2->order_unvcd ) { (void) fprintf (stderr, "spec_distort: warning, order_unvcd not equal in %s and %s.\n", f1str, f2str); } (void)fflush (stderr);/* * The following variables are used to compute the size of * our multi-dimensional arrays *//* * Now allocate: * * number of records (rows) * by * number of frequencies (num_of_freqs) [columns] * * memory space to store all * differences between elements in each record for computing the Element * Average, Record Average, and File Average. * */ rows = (e_rec - s_rec + 1); /* number of rows to allocate */ columns = num_of_freqs; (void) allo_memory (rows, columns); /* allocate memory for all arrays *//* * Here is the big loop for ESPS SPEC files. * Note: we have to check for consistency * each time through the loop. */ if (debug_level > 4) (void) fprintf (stderr, "spec_distort: for (rec_num = %d; rec_num <= %d; rec_num++) {\n", s_rec, e_rec); (void)fflush (stderr);/* * * M A I N L O O P: * */ for ( rec_num = s_rec, i_rec = 0; rec_num <= e_rec; rec_num++, i_rec++ ) { if (debug_level > 4) (void) fprintf (stderr, "\n spec_distort: getting record no. %d.\n", rec_num); if( get_spec_rec (spec_rec1, f1h, f1p) == EOF){ Fprintf(stderr, "distort: specdistort: Hit end of file in input file 1\n"); } if( get_spec_rec (spec_rec2, f2h, f2p) == EOF){ Fprintf(stderr, "distort: specdistort: Hit end of file in input file 2\n"); } /* check for consistency in file1 and file2 */ if (debug_level > 4) (void) fprintf (stderr, " spec_distort: checking for consistency in this record.\n"); frame[i_rec] = check_frames (spec_rec1, spec_rec2);/* * Compare the lengths of all the arrays in spec_data data structure * (i.e. the following arrays must be of the same size in each record, * although the lengths can vary among different records). * */ if (freq_format == ARB_VAR) { if (spec_rec1->n_frqs != spec_rec2->n_frqs) { (void) fprintf (stderr, "spec_dist: num of freqs in record number %d not equal\n", rec_num); exit (1); } else num_of_freqs = spec_rec1->n_frqs; } num_of_freqs = spec1->num_freqs;/* * Determine the maximum element number for this record * */ e_ele = freq_len[i_rec] = num_of_freqs;/* * Now begin to compute: * Difference, Difference Magnitude, and Difference Magnitude Squared. */ if (debug_level > 4) { (void) fprintf (stderr, "\n\n E L E M E N T L O O P :\n\n"); (void) fprintf (stderr, " spec_distort: for (ele_num = %d, j = 0;\n", s_ele - 1); (void) fprintf (stderr, " ele_num < %d; ele_num++,j++) {\n", e_ele); } (void)fflush (stderr);/* * * E L E M E N T L O O P: * */ for (ele_num = s_ele - 1, j = 0; ele_num < e_ele; ele_num++, j++) { if (debug_level > 5) { (void) fprintf (stderr, "\n spec_distort: ele_num = %d, j = %d\n", ele_num, j); (void) fprintf (stderr, " spec_distort: spec_rec: real1 = %f, real2 = %f\n", spec_rec1->re_spec_val[ele_num], spec_rec2->re_spec_val[ele_num]); (void) fprintf (stderr, " spec_distort: spec_rec: imag1 = %f, imag2 = %f\n", spec_rec1->im_spec_val[ele_num], spec_rec2->im_spec_val[ele_num]); (void) fprintf (stderr, " spec_distort: spec_rec: frqs1 = %f, frqs2 = %f\n", spec_rec1->frqs[ele_num], spec_rec2->frqs[ele_num]); (void) fflush (stderr); } diff_real[i_rec][j] = spec_rec1->re_spec_val[ele_num] - spec_rec2->re_spec_val[ele_num]; tot_real += diff_real[i_rec][j]; diff_imag[i_rec][j] = spec_rec1->im_spec_val[ele_num] - spec_rec2->im_spec_val[ele_num]; tot_imag += diff_imag[i_rec][j]; diff_frqs[i_rec][j] = spec_rec1->frqs[ele_num] - spec_rec2->frqs[ele_num]; tot_frqs += diff_frqs[i_rec][j]; if (debug_level > 4) { (void) fprintf (stderr, " spec_distort: tot_diff: real = %f, imag = %f, frqs = %f\n", tot_real, tot_imag, tot_frqs); (void) fflush (stderr); } switch (spec_type) { case ST_PWR: case ST_DB: case ST_REAL: SpecPower1[j] = (double) spec_rec1->re_spec_val[ele_num]; SpecPower2[j] = (double) spec_rec2->re_spec_val[ele_num]; break; case ST_CPLX: SpecPower1[j] = MAG (spec_rec1->re_spec_val[ele_num], spec_rec1->im_spec_val[ele_num]); SpecPower2[j] = MAG (spec_rec2->re_spec_val[ele_num], spec_rec2->im_spec_val[ele_num]); break; default: (void) fprintf (stderr, "spec_dist: unknown spectral type.\n"); exit (1); break; } if (debug_level > 3) { (void) fprintf (stderr, " spec_distort: SpecPower1 = %g, SpecPower2 = %g\n", SpecPower1[ele_num], SpecPower2[ele_num]); (void) fflush (stderr); } } /* end for */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -