📄 qlsf.c
字号:
/* ******************************************************************************** * * This material contains proprietary software of Entropic Speech, Inc. * Any reproduction, distribution, or publication without the 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" * * Program: qlsf * * Written by: David Burton and Jim Elliott * * Quantizes LSFs, power, and pulse lengths for coding at 2400 bps. * ******************************************************************************** *//* * SCCS program and date keywords. */#ifndef lintstatic char *sccs_id = "@(#)qlsf.c 1.10 11/24/87 ESI";#endif/* * System include files. */#include <stdio.h>#include <math.h>/* * ESPS include files. */ #include <esps/esps.h> #include <esps/fea.h>#include <esps/anafea.h>#include <esps/feaquant.h>#include "table.h"/* * Defines. */#define ERROR_EXIT( text ) { Fprintf( stderr, "qlsf: %s - exiting\n", text ); exit( 1 ); }#define SYNTAX USAGE ( "qlsf -x debug_level -P params_file -m spectral_quant\ -p power_quant -l max_steps -d duration_quant -v voiced_steps -u unvoiced_steps\ input.fea output.fea" )#define SIX 6#define TWELVE 12#define TWENTY 20#define FINE 0#define COARSE 1/* * System functions and variables. */char *strcpy();int atoi(), getopt(), strcmp();void exit(), perror();extern optind;extern char *optarg;/* * ESPS functions and variables. */char *get_cmd_line();/* * Global variables. */int debug_level = 0;/* ******************************************************************************** * Main program. ******************************************************************************** */main (argc, argv)char *argv[];int argc;{ char *cmd_line, /* String for command line */ *date = "11/24/87", *duration_quant = "exact", /* Pulse duration quantization method */ *ifn = NULL, /* Input file name */ *ofn = NULL, /* Output file name */ *pfn = "params", /* Parameter file name */ *power_quant = "6-bit", /* Power quantization method */ *spectral_quant, /* Spectral quantization method */ *version = "1.10"; double pwr, /* Power */ qpwr, /* Quantized power */ tabdec(), /* Inverse quantization table lookup */ tabquant(); /* Quantization table lookup */ FILE *ifp = stdin, /* Input file pointer */ *ofp = stdout; /* Output file pointer */ float length, /* Pulse length */ qlength; /* Quantized pulse length */ int c, /* For getopt() return */ dflag = 0, /* Option flag for pulse quantization */ diff = 0, /* Power index difference */ duration_err = 0, /* Pulse length quantization error */ first = YES, frame_cnt = 0, /* Frame counter */ i, /* Loop variable */ index, /* Quantization index */ lflag = 0, /* Option flag for power clipping */ max_steps = 8, /* Maximum change in power quantization table */ mflag = 0, /* Option flag for spectral quantization */ np, /* Number of pulses in frame */ nsteps = 0, /* Number of quantization steps */ oldidx = 0, /* Previous power index */ order = 0, /* Current analysis order */ pflag = 0, /* Option flag for power quantization */ qframe_length = 0, /* Length of quantized voiced frame */ transition = NO, /* Flag for voicing transition */ tries, /* Number of tries at LSF quantization */ uflag = 0, /* Option flag for unvoiced_steps */ vflag = 0; /* Option flag for voiced_steps */ long maxpulses, /* Maximum number of pulses per record */ maxraw, /* Maximum number of pulse powers per record */ order_unvcd = 0, /* Unvoiced analysis order */ order_vcd = 0, /* Voiced analysis order */ uvced_frmlen; /* Standard unvoiced frame length */ short voiced_steps = 12, /* Steps per LSF octave - voiced */ unvoiced_steps = 12; /* Steps per LSF octave - unvoiced */ struct anafea *anafea_rec; /* FEA_ANA file record */ struct auxana *auxana_rec; /* Auxiliary index data record */ struct header *ih = NULL, /* Input file header */ *oh = NULL; /* Output file header */ void quant_pit(), /* Pitch quantization routine */ quant_pwr(); /* Power quantization routine *//* * Read command line and process command line options. */ cmd_line = get_cmd_line( argc, argv ); while ( ( c = getopt( argc, argv, "P:d:l:m:p:u:v:x:" ) ) != EOF ) { switch ( c ) { case 'P': pfn = optarg; break; case 'd': duration_quant = optarg; if ( strcmp( duration_quant, "2_sample" ) != 0 ) ERROR_EXIT( "For -d option, only 2_sample is supported" ); dflag++; break; case 'l': max_steps = atoi( optarg ); if ( max_steps < 1 ) ERROR_EXIT( "Max_steps must be greater than 0" ); lflag++; break; case 'm': spectral_quant = optarg; mflag++; break; case 'p': power_quant = optarg; if ( strcmp( power_quant, "1.5_dB" ) != 0 ) ERROR_EXIT( "For -p option, only 1.5_dB is supported" ); pflag++; break; case 'u': unvoiced_steps = atoi( optarg ); uflag++; if ( unvoiced_steps < SIX || unvoiced_steps > TWENTY ) ERROR_EXIT( "Number of unvoiced steps/octave is out of range [6, 20]" ); break; case 'v': voiced_steps = atoi( optarg ); vflag++; if ( voiced_steps < SIX || voiced_steps > TWENTY ) ERROR_EXIT( "Number of voiced steps/octave is out of range [6, 20]" ); break; case 'x': debug_level = atoi( optarg ); break; default: SYNTAX; } }/* * Process file arguments. */ if ( optind < argc ) { ifn = argv[ optind++ ]; if ( strcmp( ifn, "-" ) == 0 ) ifn = "<stdin>"; else TRYOPEN( argv[0], ifn, "r", ifp ); } else { Fprintf( stderr, "qlsf: no input file specified\n" ); SYNTAX; } if ( optind < argc ) { ofn = argv[ optind++ ]; if ( strcmp( ofn, "-" ) == 0 ) ofn = "<stdout>"; else TRYOPEN( argv[0], ofn, "w", ofp ); } else { Fprintf( stderr, "qlsf: no output file specified\n" ); SYNTAX; }/* * Read and check values from header of input file. */ if ( ( ih = read_header( ifp ) ) == NULL ) NOTSPS( argv[0], ifn ); if ( ih->common.type != FT_FEA ) ERROR_EXIT( "Input file is not a FEA file" ); if ( ih->hd.fea->fea_type != FEA_ANA ) ERROR_EXIT( "Input file is not FEA_ANA type" ); order_vcd = *(long *) get_genhd( "order_vcd", ih ); order_unvcd = *(long *) get_genhd( "order_unvcd", ih ); if ( MAX( order_vcd, order_unvcd ) > TWENTY ) ERROR_EXIT( "LSF orders > 20 not supported" ); maxpulses = *(long *) get_genhd( "maxpulses", ih ); maxraw = *(long *) get_genhd( "maxraw", ih );/* * Check input spectral representation - abort, if not LSF. */ if ( ( *(short *) get_genhd( "spec_rep", ih ) ) != LSF ) ERROR_EXIT( "Input spectral type is not LSF" );/* * Get input from parameter file. */ if ( fopen( pfn, "r" ) != NULL ) if ( read_params( pfn, SC_NOCOMMON, (char *) NULL ) != 0 ) ERROR_EXIT( "Error reading parameter file" ); if ( uflag == 0 ) { if ( symtype( "unvoiced_steps" ) == ST_UNDEF ) unvoiced_steps = TWELVE; else unvoiced_steps = getsym_i( "unvoiced_steps" ); if ( unvoiced_steps < SIX || unvoiced_steps > TWENTY ) ERROR_EXIT( "Number of unvoiced steps/octave is out of range [6, 20]" ); } if ( vflag == 0 ) { if ( symtype( "voiced_steps" ) == ST_UNDEF ) voiced_steps = TWELVE; else voiced_steps = getsym_i( "voiced_steps" ); if ( voiced_steps < SIX || voiced_steps > TWENTY ) ERROR_EXIT( "Number of voiced steps/octave is out of range [6, 20]" ); } if ( mflag == 0 ) { if ( symtype( "spectral_quant" ) == ST_UNDEF ) ERROR_EXIT( "No spectral quantization method was specified (-m option)" ) else spectral_quant = getsym_s( "spectral_quant" ); } if ( dflag == 0 ) { if ( symtype( "duration_quant" ) != ST_UNDEF ) { duration_quant = getsym_s( "duration_quant" ); if ( ( strcmp( duration_quant, "2_sample" ) ) != 0 ) ERROR_EXIT( "For -d option, only 2_sample is supported" ); } } if ( pflag == 0 ) { if ( symtype( "power_quant" ) != ST_UNDEF ) { power_quant = getsym_s( "power_quant" ); if ( ( strcmp( power_quant, "1.5_dB" ) ) != 0 ) ERROR_EXIT( "For -p option, only 1.5_dB is supported" ); } } if ( lflag == 0 ) { if ( symtype( "max_steps" ) != ST_UNDEF ) { max_steps = getsym_i( "max_steps" ); if ( max_steps < 1 ) ERROR_EXIT( "Max_steps must be greater than 0" ); } } uvced_frmlen = (long) getsym_i( "uvced_frmlen" ); symerr_exit();/* * Write debug output. */ if ( debug_level > 0 ) { Fprintf( stderr, "qlsf: %s\n", cmd_line ); Fprintf( stderr, "qlsf: version %s, %s\n", version, date ); Fprintf( stderr, "qlsf: Debug level = %d\n", debug_level ); Fprintf( stderr, "qlsf: order_vcd = %d, order_unvcd = %d\n", order_vcd, order_unvcd ); Fprintf( stderr, "qlsf: spectral quantization method is %s\n", spectral_quant ); Fprintf( stderr, "qlsf: power quantization method is %s\n", power_quant ); Fprintf( stderr, "qlsf: duration quantization method is %s\n", duration_quant ); Fprintf( stderr, "qlsf: number of voiced steps = %d, number of unvoiced steps = %d\n", voiced_steps, unvoiced_steps ); Fprintf( stderr, "qlsf: maxpulses = %ld, maxraw = %ld\n", maxpulses, maxraw ); }/* * Create header for output file. */ oh = copy_header( ih ); add_source_file( oh, ofn, ih ); (void) strcpy( oh->common.prog, "qlsf" ); (void) strcpy( oh->common.vers, version ); (void) strcpy( oh->common.progdate, date ); (void) add_comment( oh, cmd_line );/* * Add generic header items and auxiliary record fields, and write output * file header. */ (void) add_genhd_c( "lsf_quant", spectral_quant, (int) 0, oh ); (void) add_genhd_c( "pitch_quant", duration_quant, (int) 0, oh ); (void) add_genhd_c( "power_quant", power_quant, (int) 0, oh ); if ( strcmp( power_quant, "1.5_dB" ) == 0 ) { short mx_steps = max_steps; (void) add_genhd_s( "max_steps", &mx_steps, 1, oh ); } (void) add_genhd_s( "unvoiced_steps", &unvoiced_steps, 1, oh ); (void) add_genhd_l( "uvced_frmlen", &uvced_frmlen, 1, oh ); (void) add_genhd_s( "voiced_steps", &voiced_steps, 1, oh ); if ( init_auxana_hd( oh, order_vcd, order_unvcd, maxpulses, maxraw ) != 0 ) ERROR_EXIT( "Error filling auxiliary FEA_ANA header" ); write_header( oh, ofp );/* * Allocate storage. */ anafea_rec = allo_anafea_rec( oh ); auxana_rec = allo_auxana_rec( oh, anafea_rec );/* * Main program loop. */ while ( get_anafea_rec( anafea_rec, ih, ifp ) != EOF ) { frame_cnt++; if ( *anafea_rec->frame_type != VOICED ) { np = 1; nsteps = unvoiced_steps; order = order_unvcd; } else { np = *anafea_rec->num_pulses; nsteps = voiced_steps; order = order_vcd; } tries = 1; /* * Quantize LSFs. */ while ( qlsfs( anafea_rec->spec_param, auxana_rec->spec_param_idx, spectral_quant, order, nsteps ) == NO ) { Fprintf( stderr, "Failed try #%1d at tag %d\n", tries, *anafea_rec->tag ); tries++; if ( tries == 10 ) break; } if ( order < MAX( order_unvcd, order_vcd ) ) for ( i = order; i < MAX( order_unvcd, order_vcd ); i++ ) auxana_rec->spec_param_idx[i] = 0; /* * Quantize pulse powers, using 1 dB table, or the coarser 1.5 dB table. */ if ( strcmp( power_quant, "6-bit" ) == 0 ) { for ( i = 0; i < np; i++ ) { pwr = anafea_rec->raw_power[i]; quant_pwr( (double) pwr, &qpwr, FINE, &index ); anafea_rec->raw_power[i] = (float) qpwr; auxana_rec->raw_power_idx[i] = index; } while ( i < maxraw ) { auxana_rec->raw_power_idx[i] = 0; i++; } } else { for ( i = 0; i < np; i++ ) { pwr = anafea_rec->raw_power[i]; quant_pwr( (double) pwr, &qpwr, COARSE, &index ); diff = index - oldidx; if ( debug_level > 2 ) { Fprintf( stderr, "frame %d; pulse %d\n", frame_cnt, i ); Fprintf( stderr, "first = %d, index = %d, diff = %d, qpwr = %lf\n", first, index, diff, qpwr ); } /* * Power is not clipped: */ if ( first == YES || ( diff <= max_steps && diff >= -max_steps ) ) { anafea_rec->raw_power[i] = (float) qpwr; auxana_rec->raw_power_idx[i] = index; first = NO; oldidx = index; } /* * Clip power drops: */ else if ( diff < -max_steps ) { if ( debug_level > 2 ) Fprintf( stderr, "diff < -8\n" ); index = oldidx - max_steps; oldidx = index; qpwr = tabdec( index, COARSE, pwrqtable ); qpwr = qpwr * qpwr; if ( debug_level > 2 ) Fprintf( stderr, "\tindex = %d, qpwr = %lf\n", index, qpwr ); anafea_rec->raw_power[i] = (float) qpwr; auxana_rec->raw_power_idx[i] = index; } else { if ( debug_level > 2 ) Fprintf( stderr, "diff > 8\n" ); index = oldidx + max_steps;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -