anafeadist.c

来自「speech signal process tools」· C语言 代码 · 共 816 行 · 第 1/2 页

C
816
字号
/* anafea_distort - compute distortion measures between two ESPS FEA_ANA 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:  ana_distort *  * Written By:  Ajaipal S. Virdy * * * Purpose:  compute distortion measures between two ESPS FEA_ANA files *	     for comparing speech processes * * */#ifdef SCCS	static char *sccs_id = "@(#)anafeadist.c	3.3	1/27/93	ESI";#endif#include <stdio.h>#include <esps/esps.h>#include <esps/anafea.h>#include <esps/fea.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 ana_distort and print_distort. * */float	*ref_coeff1;	/* reflection coefficients for first file */float	*ref_coeff2;	/* reflection coefficients for second file */char	**frame;	/* string for "Voiced" or "Unvoiced" frames */int	*ref_c_len;	/* length of array ref_coeff for each record */int	*pitch_len;	/* length of array p_pulse_len for each " */int	*raw_len;	/* length of array raw_power for each record */int	*lpc_len;	/* length of array lpc_power for each record */float	**diff_ref_c;	/* difference between ref_coeff vector */float	**diff_pitch;	/* difference between p_pulse_len vector */float	**diff_raw;	/* difference between raw_power vector */float	**diff_lpc;	/* difference between lpc_power vector */double	*IS_dist;	/* Itakura-Saito (IS) distortion measure vector */double	*GNIS_dist;	/* Gain-Normalized IS distortion measure vector */double	*GOIS_dist;	/* Gain-Optimized IS distortion measure vector */float	tot_ref_c;	/* variable to sum all ref_coeff */float	tot_pitch;	/* variable to sum all p_pulse_len */float	tot_raw;	/* variable to sum all raw_power */float	tot_lpc;	/* variable to sum all lpc_power */int	maxorder;int	maxpulses;int	maxraw;int	maxlpc;long	order_vcd;long	order_unvcd;int	i_rec;		/* current record */int	rec_num;	/* current record number */int	ele_num;	/* current element number *//* * U N I X *  F U N C T I O N S *   R E F E R E N C E D *//* done via <esps/unix.h>/* * E S P S *  F U N C T I O N S *   R E F E R E N C E D */char	*get_genhd();short	get_rec_len();int	get_anafea_rec();/* * L O C A L *  F U N C T I O N S *   R E F E R E N C E D */void	allo_memory();int	array_len();void	check_anafea_arrays();char	*check_frames();void	convert_to_rc();void	compute_is_dist();void	gen_distort();int	reps_rc();void	type_conflict();/* * B E G I N *  P R O G R A M */voidanafea_distort(){   struct anafea	*anafea_rec1;	/* data structure for file1 */   struct anafea 	*anafea_rec2;	/* data structure for file2 */   int	rows;		/* size of row to allocate */   int	j;		/* temporary indices *//* *  If the -e option was given then treat the FEA_ANA file as *  "generic" file. * */   if ( eflag ) {      (void) gen_distort ();      return;   }   if ( debug_level > 3)      (void) fprintf (stderr, "\n");   if ( get_rec_len (f1h) != get_rec_len (f2h) ) {      (void) fprintf (stderr,      "anafea_distort: warning, elements per record not equal in both files.\n");    } else 	if (debug_level > 4)	   (void) fprintf (stderr,	   "anafea_distort: same number of elements in these FEA_ANA files.\n");   /* skip appropiate number of records (as specified by the -f option) */   anafea_rec1 = allo_anafea_rec (f1h);   anafea_rec2 = allo_anafea_rec (f2h);   if (debug_level > 1)      (void) fprintf (stderr,      "anafea_distort: skipping %d records.\n", s_rec - 1);/* We've 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_anafea_rec (anafea_rec1, f1h, f1p) == EOF ) { *	  (void) fprintf (stderr, *	  "anafea_distort: not enough records in %s.\n", f1str); *	  exit (1); *       } *       if ( get_anafea_rec (anafea_rec2, f2h, f2p) == EOF ) { *	  (void) fprintf (stderr, *	  "anafea_distort: not enough records in %s.\n", f2str); *	  exit (1); *       } * *   } \* end for *\ */   if ((order_vcd = *(long *) get_genhd ("order_vcd", f1h)) !=		*(long *) get_genhd ("order_vcd", f2h)) {	(void) fprintf (stderr,	"anafea_distort: order_vcd not equal in %s and %s.\n",	f1str, f2str);	exit (1);   }   if ((order_unvcd = *(long *) get_genhd ("order_unvcd", f1h)) !=		*(long *) get_genhd ("order_unvcd", f2h)) {	(void) fprintf (stderr,	"anafea_distort: order_unvcd not equal in %s and %s.\n",	f1str, f2str);	exit (1);   }   (void) fflush (stderr);/* * The following variables are used to compute the size of  * our multi-dimensional arrays */     maxorder = MAX (order_vcd, order_unvcd);    maxpulses = MAX (*(long *) get_genhd ("maxpulses", f1h),		     *(long *) get_genhd ("maxpulses", f2h));       maxraw = MAX (*(long *) get_genhd ("maxraw", f1h),		     *(long *) get_genhd ("maxraw", f2h));       maxlpc = MAX (*(long *) get_genhd ("maxlpc", f1h),		     *(long *) get_genhd ("maxlpc", f2h));    if (debug_level > 5) {	Fprintf (stderr,	"anafea_distort: order_vcd = %ld, order_unvcd = %ld\n",	order_vcd, order_unvcd);	Fprintf (stderr,	"anafea_distort: maxpulses = %ld, maxraw = %ld, maxlpc = %ld\n",	maxpulses, maxraw, maxlpc);	(void) fflush (stderr);    }/* * Now allocate: * *   number of records [rows] * 	    by  *   MAX(order_vcd, order_unvcd) + maxpulses + maxraw + maxlpc * * 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 */   /* allocate memory for all arrays */   (void) allo_memory (rows, maxorder, maxpulses, maxraw, maxlpc);/* * Here is the big loop for ESPS FEA_ANA files. * Note: we have to check for consistency *       each time through the loop.   */   if (debug_level > 4)      (void) fprintf (stderr,      "anafea_distort: for (rec_num = %d; rec_num <= %d; rec_num++) {\n",      s_rec, e_rec);   (void) fflush (stderr);    tot_ref_c = 0.0;	/* variable to sum all ref_coeff */    tot_pitch = 0.0;	/* variable to sum all p_pulse_len */    tot_raw = 0.0;	/* variable to sum all raw_power */    tot_lpc = 0.0;	/* variable to sum all lpc_power *//* * *  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  anafea_distort: getting record no. %d.\n", rec_num);     if( get_anafea_rec (anafea_rec1, f1h, f1p) == EOF){	 Fprintf(stderr, 	    "distort: anafeadist: Hit end of file in input file 1\n");	exit(1);     }     if( get_anafea_rec (anafea_rec2, f2h, f2p) == EOF){	 Fprintf(stderr, 	    "distort: anafeadist: Hit end of file in input file 2\n");	exit(1);   }     /* check for consistency in file1 and file2 */     if (debug_level > 4)	(void) fprintf (stderr,	"  anafea_distort: checking for consistency in this record.\n");     frame[i_rec] = check_frames (anafea_rec1, anafea_rec2);/* * Compare the lengths of all the arrays in anafea data structure * (i.e. the following arrays must be of the same size in each record, *       although the lengths can vary among different records). * */      check_anafea_arrays (f1h, anafea_rec1, f2h, anafea_rec2);/* * Determine the maximum element number for this record *  */	if ( strcmp (frame[i_rec], " Voiced ") == 0 ) {	   e_ele = MAX (order_vcd, pitch_len[i_rec]);	   e_ele = MAX (e_ele, raw_len[i_rec]);	   e_ele = MAX (e_ele, lpc_len[i_rec]);   /* save the length of ref_coeff array for computing the average */	   ref_c_len[i_rec] = order_vcd;	}	else if ( strcmp (frame[i_rec], "Unvoiced") == 0 ) {	   /* Unvoiced frame */	   e_ele = MAX (order_unvcd, pitch_len[i_rec]);	   e_ele = MAX (e_ele, raw_len[i_rec]);	   e_ele = MAX (e_ele, lpc_len[i_rec]);   /* save the length of ref_coeff array for computing the average */	   ref_c_len[i_rec] = order_unvcd;	}     if (debug_level > 2) {	(void) fprintf (stderr,	"  anafea_distort: ref_c_len[%d] = %d, pitch_len[%d] = %d\n",	i_rec, ref_c_len[i_rec], i_rec, pitch_len[i_rec]);	(void) fprintf (stderr,	"                 raw_len[%d] = %d,   lpc_len[%d] = %d\n",	i_rec, raw_len[i_rec], i_rec, lpc_len[i_rec]);     }   (void) fflush (stderr);     if ((ref_coeff1 = (float *) calloc ((unsigned) ref_c_len[i_rec],				         sizeof (float))) == NULL ) {	(void) fprintf (stderr,	"anafea_distort: calloc: could not allocate memory for ref_coeff1.\n");	exit (1);     }     if ((ref_coeff2 = (float *) calloc ((unsigned) ref_c_len[i_rec],					 sizeof (float))) == NULL ) {	(void) fprintf (stderr,	"anafea_distort: calloc: could not allocate memory for ref_coeff2.\n");	exit (1);     }/*  * Convert spectral representation to reflection coefficients, * then compute the Itakura-Saito Distortion measures for this frame. */     (void) convert_to_rc (anafea_rec1->spec_param,			   anafea_rec2->spec_param, ref_c_len[i_rec]);     (void) compute_is_dist (ref_coeff1, anafea_rec1->lpc_power[0],			     ref_coeff2, anafea_rec2->lpc_power[0],			     ref_c_len[i_rec]);/* * Now begin to compute: *   Difference, Difference Magnitude, and Difference Magnitude Squared. */		if (debug_level > 4) {	   (void) fprintf (stderr,	   "  anafea_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 > 4)	      (void) fprintf (stderr,	      "    anafea_distort: ele_num = %d, j = %d\n", ele_num, j);	   diff_ref_c[i_rec][j] = ref_coeff1[ele_num] -			   		ref_coeff2[ele_num];	   tot_ref_c += diff_ref_c[i_rec][j];	   if ( ele_num > pitch_len[i_rec] - 1 ) {	       if (debug_level > 4)		  (void) fprintf (stderr,	       "    anafea_distort: not enough elements in p_pulse_len array.\n");	   } else {		diff_pitch[i_rec][j] = anafea_rec1->p_pulse_len[ele_num] -					anafea_rec2->p_pulse_len[ele_num];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?