📄 decode.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: decode * * Written by: Jim Elliott * * Decodes a FEA_2KB bitstream file to produce an augmented FEA_ANA file * with reconstructed quantization indices and frame parameters. * ******************************************************************************** *//* * SCCS program and date keywords. */#ifndef lintstatic char *sccs_id = "@(#)decode.c 1.2 11/25/87 ESI";#endif/* * System include files. */#include <stdio.h>/* * ESPS include files. */#include <esps/esps.h>#include <esps/anafea.h>#include <esps/encode.h>#include <esps/fea.h>#include <esps/fea2kb.h>#include <esps/feahuff.h>#include <esps/feaqhist.h>#include <esps/feaquant.h>/* * Defines. */#define ERROR_EXIT( text ) \{ \ Fprintf( stderr, "decode: %s - exiting\n", text ); \ exit( 1 ); \}#define SYNTAX USAGE \( \ "decode -D debug_file -d -h hist_file -x debug_level infile.fea huffile.fea outfile.fea" \)/* * 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();struct zfunc *get_genzfunc();void add_genzfunc();/* * Internal functions and variables. */struct tbl_entry huff_tbl[ MAX_TBL*MAX_TBLSIZ ]; /* Concatenated Huffman tables */struct key key_tbl[ MAX_TBL ]; /* Table of offsets in big table *//* ******************************************************************************** * Main program. ******************************************************************************** */main( argc, argv )char *argv[];int argc;{ char *cmd_line, /* String for command line */ *date = "11/25/87", *dfn = NULL, /* Debug file name */ dump = NO, /* Flag to dump frame statistics */ *hfn = "decode.his", /* History file name */ *ifn = NULL, /* Input file name */ *lsf_quant, /* LSF quantization method */ *ofn = NULL, /* Output file name */ *pitch_quant, /* Pitch quantization method */ *power_quant, /* Power quantization method */ *tfn = NULL, /* Huffman table file name */ *version = "1.2"; FILE *dfp = stderr, /* Debug file pointer */ *hfp = NULL, /* History file pointer */ *ifp = stdin, /* Input file pointer */ *ofp = stdout, /* Output file pointer */ *tfp = NULL; /* Huffman table file pointer */ float chan_rate; /* Channel rate */ int c, /* For getopt() return */ debug = 0, /* Flag to control debug output */ diff_avg, /* Flag for inconsistent LSF averages */ ext, /* Extension field */ frm_cnt = 0, /* Frame counter */ i, /* Loop variable */ j, /* Loop variable */ re_sync, /* Frame re-synchronization flag */ sync_cnt = 1, /* Sync down-counter */ sync_intv, /* Frame-sync interval */ sync_len, /* Sync length: 0111...10 */ type = NONE, /* Type of Huffman table; also, type field */ uvced_frmlen; /* Standard unvoiced frame length */ long order_vcd, /* Voiced filter order */ order_unvcd; /* Unvoiced filter order */ short *avg, /* Pointer to LSF average in header */ comb_frq, /* Flag for combined frequency tables */ comb_vcg, /* Flag for combined voicing tables */ cont_pwr, /* Flag for continuous coding of power */ cont_spc, /* Flag for continuous coding of spectrum */ max_steps, /* Clipping range in 1.5 dB power table */ prev_type = NONE, /* Previous frame type */ u_avg[ MAX_ORD ], /* Unvoiced LSF averages */ unvoiced_steps, /* Steps per LSF octave (unvoiced) */ v_avg[ MAX_ORD ], /* Voiced LSF averages */ voiced_steps; /* Steps per LSF octave (voiced) */ struct anafea *anafea_rec; /* FEA_ANA record */ struct auxana *auxana_rec; /* Auxiliary FEA_ANA record */ struct auxqhist *auxqhist_rec; /* Auxiliary FEA_QHIST record */ struct fea2kb *fea2kb_rec; /* FEA_2KB record */ struct feaqhist *feaqhist_rec; /* FEA_QHIST record */ struct header *ih, /* Input file header */ *oh; /* Output file header */ static struct bit_stats bs; /* Bit statistics: static => {0,...} */ static int u_vect[ MAX_ORD ], /* Array for unvoiced spectral breakdown */ v_vect[ MAX_ORD ]; /* Array for voiced spectral breakdown *//* * Read command line and process command line options. */ cmd_line = get_cmd_line( argc, argv ); while ( ( c = getopt( argc, argv, "D:dh:x:" ) ) != EOF ) { switch ( c ) { case 'D': dfn = optarg; break; case 'd': dump = YES; break; case 'h': hfn = optarg; break; case 'x': debug = 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, "decode: No input file specified\n" ); SYNTAX; } if ( optind < argc ) { tfn = argv[ optind++ ]; if ( strcmp( tfn, "-" ) == 0 ) { ERROR_EXIT( "<stdin> not allowed for Huffman table file" ); } else TRYOPEN( argv[0], tfn, "r", tfp ); } else { Fprintf( stderr, "decode: No Huffman table 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, "decode: No output file specified\n" ); SYNTAX; } if ( dfn ) TRYOPEN( argv[0], dfn, "w", dfp ); TRYOPEN( argv[0], hfn, "w", hfp );/* * Read and check header of Huffman table file, allocate storage for FEA_QHIST * and auxiliary records, and read in Huffman code tables. */ if ( ( ih = read_header( tfp ) ) == NULL ) NOTSPS( argv[0], tfn ); if ( ih->common.type != FT_FEA ) ERROR_EXIT( "Huffman table file is not a FEA file" ); if ( ih->hd.fea->fea_type != FEA_QHIST ) ERROR_EXIT( "Huffman table file is not FEA_QHIST type" ); comb_vcg = *(short *) get_genhd( "comb_vcg", ih ); comb_frq = *(short *) get_genhd( "comb_frq", ih ); cont_pwr = *(short *) get_genhd( "cont_pwr", ih ); cont_spc = *(short *) get_genhd( "cont_spc", ih ); lsf_quant = get_genhd( "lsf_quant", ih ); max_steps = *(short *) get_genhd( "max_steps", ih ); pitch_quant = get_genhd( "pitch_quant", ih ); power_quant = get_genhd( "power_quant", ih ); unvoiced_steps = *(short *) get_genhd( "unvoiced_steps", ih ); voiced_steps = *(short *) get_genhd( "voiced_steps", ih ); avg = (short *) get_genhd( "u_avg", ih ); for ( i = 0; i < MAX_ORD; i++ ) u_avg[i] = avg[i]; avg = (short *) get_genhd( "v_avg", ih ); for ( i = 0; i < MAX_ORD; i++ ) v_avg[i] = avg[i]; feaqhist_rec = allo_feaqhist_rec( ih ); auxqhist_rec = allo_auxqhist_rec( ih, feaqhist_rec ); i = 0; j = 0; while ( get_feaqhist_rec( feaqhist_rec, ih, tfp ) != EOF ) { if ( type != *feaqhist_rec->hist_type ) { key_tbl[j].type = *feaqhist_rec->hist_type; key_tbl[j].offset = i; j++; } type = *feaqhist_rec->hist_type; huff_tbl[i].type = *feaqhist_rec->data_type; huff_tbl[i].code = *auxqhist_rec->code; huff_tbl[i].length = *auxqhist_rec->length; i++; }/* * Read and check values from header of FEA_2KB 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_2KB ) ERROR_EXIT( "Input file is not FEA_2KB type" ); if ( strcmp( lsf_quant, get_genhd( "lsf_quant", ih ) ) || strcmp( pitch_quant, get_genhd( "pitch_quant", ih ) ) || strcmp( power_quant, get_genhd( "power_quant", ih ) ) || unvoiced_steps != *(short *) get_genhd( "unvoiced_steps", ih ) || voiced_steps != *(short *) get_genhd( "voiced_steps", ih ) ) ERROR_EXIT( "Inconsistent quantization: infile.fea, huffile.fea" ); if ( strcmp( power_quant, "1.5_dB" ) == 0 && max_steps != *(short *) get_genhd( "max_steps", ih ) ) ERROR_EXIT( "Inconsistent power quantization: infile.fea, huffile.fea" ); diff_avg = 0; avg = (short *) get_genhd( "u_avg", ih ); for ( i = 0; i < MAX_ORD; i++ ) diff_avg += ( avg[i] != u_avg[i] ); avg = (short *) get_genhd( "v_avg", ih ); for ( i = 0; i < MAX_ORD; i++ ) diff_avg += ( avg[i] != v_avg[i] ); if ( *(short *) get_genhd( "comb_vcg", ih ) != comb_vcg || *(short *) get_genhd( "comb_frq", ih ) != comb_frq || *(short *) get_genhd( "cont_pwr", ih ) != cont_pwr || *(short *) get_genhd( "cont_spc", ih ) != cont_spc || diff_avg ) ERROR_EXIT( "Inconsistent coding parameters: infile.fea, huffile.fea" ); chan_rate = *(float *) get_genhd( "chan_rate", ih ); order_unvcd = *(long *) get_genhd( "order_unvcd", ih ); order_vcd = *(long *) get_genhd( "order_vcd", ih ); sync_intv = *(short *) get_genhd( "sync_intv", ih ); sync_len = *(short *) get_genhd( "sync_len", ih ); uvced_frmlen = *(long *) get_genhd( "uvced_frmlen", ih );/* * Create header for output file. */ oh = new_header( FT_FEA ); add_source_file( oh, ifn, ih ); (void) strcpy( oh->common.prog, "decode" ); (void) strcpy( oh->common.vers, version ); (void) strcpy( oh->common.progdate, date ); add_comment( oh, cmd_line ); oh->common.tag = YES; oh->variable.refer = ifn;/* * Allocate FEA_ANA and auxiliary record fields, add generic header items, and * write output file header. */ if ( init_anafea_hd( oh, order_vcd, order_unvcd, *(long *) get_genhd( "maxpulses", ih ), *(long *) get_genhd( "maxraw", ih ), *(long *) get_genhd( "maxlpc", ih ), 0, 0 ) ) ERROR_EXIT( "Error filling FEA_ANA header" ); if ( init_auxana_hd( oh, order_vcd, order_unvcd, *(long *) get_genhd( "maxpulses", ih ), *(long *) get_genhd( "maxraw", ih ) ) ) ERROR_EXIT( "Error filling auxiliary FEA_ANA header" ); (void) add_genhd_c( "avg_pitch", get_genhd( "avg_pitch", ih ), 0, oh ); (void) add_genhd_c( "avg_power", get_genhd( "avg_power", ih ), 0, oh ); (void) add_genhd_f( "chan_rate", &chan_rate, 1, oh ); *(short *) get_genhd( "frmlen", oh ) = *(short *) get_genhd( "frmlen", ih ); (void) add_genhd_c( "lsf_quant", get_genhd( "lsf_quant", ih ), 0, oh ); (void) add_genhd_s( "n_uv_pieces", (short *) get_genhd( "n_uv_pieces", ih ), 1, oh ); *(long *) get_genhd( "nan", oh ) = *(long *) get_genhd( "nan", ih ); (void) add_genhd_c( "pitch_quant", get_genhd( "pitch_quant", ih ), 0, oh ); (void) add_genhd_c( "power_quant", get_genhd( "power_quant", ih ), 0, oh ); (void) add_genzfunc( "pre", (struct zfunc *) get_genzfunc( "pre", ih ), oh ); (void) add_genhd_c( "preemp_uv", get_genhd( "preemp_uv", ih ), 0, oh ); (void) add_genhd_s( "psynch", (short *) get_genhd( "psynch", ih ), 1, oh ); (void) add_genhd_s( "sinc_flg", (short *) get_genhd( "sinc_flg", ih ), 1, oh ); *(short *) get_genhd( "spec_rep", oh ) = *(short *) get_genhd( "spec_rep", ih ); *(float *) get_genhd( "src_sf", oh ) = *(float *) get_genhd( "src_sf", ih ); *(long *) get_genhd( "start", oh ) = *(long *) get_genhd( "start", ih ); (void) add_genhd_s( "unvoiced_steps", &unvoiced_steps, 1, oh ); (void) add_genhd_s( "voiced_steps", &voiced_steps, 1, oh ); write_header( oh, ofp );/* * Allocate storage for input and output data records. */ fea2kb_rec = allo_fea2kb_rec( ih ); anafea_rec = allo_anafea_rec( oh ); auxana_rec = allo_auxana_rec( oh, anafea_rec );/* * Main program loop. */ print_header( dump, hfp, ifn, tfn, ofn, version, date, chan_rate, comb_frq, comb_vcg, cont_pwr, cont_spc, sync_intv, sync_len ); for (;;) { if ( sync_intv ) sync_cnt--; if ( sync_cnt == 0 ) { sync_cnt = sync_intv; get_sync( sync_len, debug, dfp, &bs, fea2kb_rec, ih, ifp ); bs.frm_bits = sync_len; re_sync = YES; } else { bs.frm_bits = 0; re_sync = NO; } if ( reconst_type_ext( prev_type, fea2kb_rec, ih, ifp, debug, dfp, &anafea_rec, &type, &ext, &bs ) == EOF ) break; reconst_pwr( cont_pwr, prev_type, fea2kb_rec, ih, ifp, re_sync, debug, dfp, &anafea_rec, &auxana_rec, &bs ); reconst_len( prev_type, uvced_frmlen, fea2kb_rec, ih, ifp, re_sync, debug, dfp, type, ext, &anafea_rec, &auxana_rec, &bs ); reconst_spec( order_unvcd, order_vcd, comb_frq, comb_vcg, cont_spc, prev_type, u_avg, v_avg, u_vect, v_vect, fea2kb_rec, ih, ifp, re_sync, debug, dfp, &anafea_rec, &auxana_rec, &bs ); put_anafea_rec( anafea_rec, oh, ofp ); bs.tot += bs.frm_bits; if ( debug >= 1 ) { frm_cnt++; Fprintf( dfp, "Frame = %d; Type = %s\n", frm_cnt, frame_types[ *anafea_rec->frame_type ] ); Fprintf( dfp, "Bits this frame = %d; Cumulative bits = %d\n\n", bs.frm_bits, bs.tot ); } if ( dump ) print_frm_stats( bs, anafea_rec, prev_type, hfp ); prev_type = *anafea_rec->frame_type; } print_cum_stats( bs, u_vect, v_vect, order_unvcd, order_vcd, hfp ); exit( 0 );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -