📄 qlsf.c
字号:
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; } } while ( i < maxraw ) { auxana_rec->raw_power_idx[i] = 0; i++; } } /* * Quantize pulse lengths. */ if ( strcmp( duration_quant, "exact" ) == 0 && *anafea_rec->frame_type == VOICED ) { for ( i = 0; i < maxpulses; i++ ) { if ( i < *anafea_rec->num_pulses ) auxana_rec->pulse_len_idx[i] = anafea_rec->p_pulse_len[i]; else auxana_rec->pulse_len_idx[i] = 0; } } else if ( strcmp( duration_quant, "2_sample" ) == 0 ) { if ( debug_level >= 1 && frame_cnt == 1 ) { Fprintf( stderr, "QLSF: Using 2_sample method for pulse duration quantization\n\n" ); } if ( *anafea_rec->frame_type == UNVOICED && transition == YES ) { if ( debug_level >= 1 ) { Fprintf( stderr, "QLSF: Unvoiced transition frame\n" ); Fprintf(stderr, "\nQLSF: Total Voiced Quantization Error = %d\n", duration_err ); } *anafea_rec->frame_len += duration_err; transition = NO; duration_err = 0; } else if ( *anafea_rec->frame_type == VOICED ) { transition = YES; qframe_length = 0; if ( debug_level >= 1 ) Fprintf( stderr, "QLSF: VOICED Frame; %ld pulses\n\n", *anafea_rec->num_pulses ); for ( i = 0; i < maxpulses; i++ ) { if ( ( length = anafea_rec->p_pulse_len[i] ) != 0 ) { quant_pit( length, &qlength, FINE, &index ); duration_err += length - qlength; qframe_length += qlength; anafea_rec->p_pulse_len[i] = qlength; auxana_rec->pulse_len_idx[i] = index; if ( debug_level >= 1 ) { Fprintf( stderr, "QLSF: Input pulse duration = %f, ", length ); Fprintf( stderr, "QLSF: Quantized pulse duration = %f\n", qlength ); Fprintf( stderr, "QLSF: Coded index = %d\n", index ); } } else auxana_rec->pulse_len_idx[i] = 0; } *anafea_rec->frame_len = qframe_length; } } put_anafea_rec( anafea_rec, oh, ofp ); } exit( 0 );}/* ******************************************************************************** * Subroutine to perform LSF quantization. ******************************************************************************** */qlsfs( lsf, index, method, order, nsteps )char *method;float lsf[];int order;short index[], nsteps;{ static float tbl[67]; static int N; int i, j, ok=YES; static short prevn=0;/* * If the step size has changed, load the quantized LSF values into * the table. */ if ( nsteps != prevn ) { if(debug_level > 4){ Fprintf(stderr, "qlsf: qlsfs: current number of steps = %d, previous number of steps = %d\n" , nsteps, prevn); } tbl[0] = 300.0; tbl[1] = 350.0; i = 0; j = 1; while (tbl[j] <= 4000.){ tbl[j+1] = exp( log(400.0) + (double) i * log(2.0) / (double) nsteps ); tbl[j+1] = ROUND( tbl[j+1]); i++; j++; } N = j; if(debug_level >4){ Fprintf(stderr, "qlsf: qlsfs: order = %d\n", order); for(j=0;j<N; j++) Fprintf(stderr, "qlsf: qlsfs: LSF table value #%d = %f\n", j, tbl[j]); } } prevn = nsteps;/* * Now do either DIRECT or CTR_OFF method of quantization*/ /* * FIRST DO DIRECT */ if((strcmp(method, "direct")) == 0) /* do direct coding of LSFs*/ { /* * Assign indices for nearest line spectrum values. */ for ( i = 0; i < order; i++ ) { if ( lsf[i] <= tbl[0] ) index[i] = 0; else if ( lsf[i] >= tbl[N-1] ) index[i] = N - 1; else { j = 1; while ( lsf[i] > tbl[j] ) j++; if ( lsf[i] < 0.5 * ( tbl[j-1] + tbl[j] ) ) index[i] = j - 1; else index[i] = j; } } /* * Now look through the index array and separate any adjacent ones * which are equal. */ for ( i = 1; i < order; i++ ) { if ( index[i] != index[i-1] ) continue; /* * Handle cases on either end of the spectrum. */ if ( index[i] == 0 ) { index[i] = 1; continue; } if ( index[i] == N - 1 ) { index[i-i] = N - 2; continue; } /* * Handle cases in between. */ if ( lsf[i-1] < tbl[ index[i-1] ] && lsf[i] <= tbl[ index[i] ] ) index[i-1]--; else if ( lsf[i-1] >= tbl[ index[i-1] ] && lsf[i] > tbl[ index[i] ] ) index[i]++; else { if ( tbl[ index[i-1] ] - lsf[i-1] >= lsf[i] - tbl[ index[i] ] ) index[i-1]--; else index[i]++; } } /* * Now assign quantized values from table, checking that all values * are distinct. */ for ( i = 0; i < order; i++ ) { lsf[i] = tbl[ index[i] ]; if ( i > 0 && index[i] == index[i-1] ) ok = NO; } return( ok ); } /* * OR DO CENTER/OFFSET QUANTIZATION */ else if ((strcmp(method, "ctr_off")) == 0) { /* minimum center frequecy indices*/ static int imin[5] = { 0, 0, 0, 0, 0 }; /* possible offset indices - one row for each offset*/ static int dix[10][67]; static Nprev = 0; static prev_order = 0; float cf, of; static frame_cnt = 0; /* fill in table indices, if needed*/ if(Nprev != N || prev_order != order){ for(i=0;i<order/2;i++) for(j=0;j<N;j++) dix[i][j] = 0; for(i=0;i<order/2;i++) for(j=0;j<N-1;j++) dix[i][j] = j+1; Nprev = N; prev_order = order; if(debug_level > 0) Fprintf(stderr, "Current N is %d, current order is %d\n", N, order); } /* * Assign indices for center and offset frequencies of line spectral pair. */ if(debug_level >2){ for(i=0;i<order;i++) Fprintf(stderr, "LSF[%d] = %f\n", i, lsf[i]); } frame_cnt++; for ( i = 0; i < order/2; i++ ) { cf = ( lsf[2*i+1] + lsf[2*i] ) / 2.0; of = ( lsf[2*i+1] - lsf[2*i] ) / 2.0; if(debug_level >3){ Fprintf(stderr, "center[%d] = %f, offset[%d] = %f\n", i, cf, i, of); } /* First center frequencies */ if ( cf <= tbl[ imin[i] ] ) index[2*i] = imin[i]; else if ( cf >= tbl[ N-1 ] ) index[2*i] = N-1; else { j = imin[i] + 1; while ( cf > tbl[j] ) j++; if ( cf < 0.5 * ( tbl[j-1] + tbl[j] ) ) index[2*i] = j - 1; else index[2*i] = j; } if(debug_level >3){ Fprintf(stderr, "cf[%d] index = %d\n", i, index[2*i]); } /* Now offset frequencies */ of += tbl[ index[2*i] ]; j = 0; while ( of > tbl[ index[2*i] + dix[i][j] ] ) { j++; if ( dix[i][j] == 0 ) break; } if ( j == 0 ) index[2*i+1] = dix[i][0]; else if ( dix[i][j] == 0 ) index[2*i+1] = dix[i][j-1]; else { if ( of < 0.5 * ( tbl[ index[2*i] + dix[i][j-1] ] + tbl[ index[2*i] + dix[i][j] ] ) ) index[2*i+1] = dix[i][j-1]; else index[2*i+1] = dix[i][j]; } if(debug_level >3){ Fprintf(stderr, "of[%d] index = %d\n", i, index[2*i+1]); } }/* * Now assign quantized values from table. */ for ( i = 0; i < order/2; i++ ) { of = tbl[ index[2*i] + index[2*i+1] ] - tbl[ index[2*i] ]; lsf[2*i] = tbl[ index[2*i] ] - of; if ( lsf[2*i] <= tbl[ imin[i] ] ) lsf[2*i] = tbl[ imin[i] ]; else if ( lsf[2*i] >= tbl[ N-1 ] ) lsf[2*i] = tbl[ N-1 ]; else { j = imin[i] + 1; while ( lsf[2*i] > tbl[j] ) j++; if ( lsf[2*i] < 0.5 * ( tbl[j-1] + tbl[j] ) ) lsf[2*i] = tbl[j-1]; else lsf[2*i] = tbl[j]; } if(debug_level >2){ Fprintf(stderr, "Quantized LSF[%d] = %f\n", 2*i, lsf[2*i]); } lsf[2*i+1] = tbl[ index[2*i] ] + of; if(debug_level >2){ Fprintf(stderr, "Quantized LSF[%d] = %f\n", 2*i+1, lsf[2*i+1]); } } for ( i = 1; i < order; i++ ) { if ( lsf[i] < lsf[i-1] ){ float tmp; Fprintf( stderr, "*** LSF reversal at frame %d: %d %d\n", frame_cnt, i-1, i ); Fprintf( stderr, "Attempting to fix by Inverting LSFs %d and %d\n", i-1, i); tmp = lsf[i-1]; lsf[i-1] = lsf[i]; lsf[i] = tmp; } if ( lsf[i] == lsf[i-1] ){ Fprintf(stderr, "*** LSFs equal at frame %d: %d %d\n", frame_cnt, i-1, i); Fprintf(stderr, "lsf[%d] = %f, lsf[%d] = %f\n", i-1, lsf[i-1], i, lsf[i]); Fprintf(stderr, "bumping higher LSF up one\n"); for(j=1;j<N;j++){ if(lsf[i] == tbl[j]) break; } lsf[i] = tbl[j+1]; } } return( ok ); } else ERROR_EXIT("Invalid spectral quantization method (-m option) specified");}/* ******************************************************************************** * Subroutine to perform power quantization. ******************************************************************************** */voidquant_pwr( in, out, table_index, code )double in, *out;int *code, table_index;{ double temp; temp = sqrt( in ); temp = ROUND( temp ); *out = tabquant( temp, table_index, pwrqtable, code ); *out = (*out) * (*out);}/* ******************************************************************************** * Subroutine to perform pitch quantization. ******************************************************************************** */voidquant_pit( in, out, table_index, code )float in, *out;int *code, table_index;{ float temp; temp = ROUND( in ); *out = (float) tabquant( (double)temp, table_index, pitqtable, code ); }/* ******************************************************************************** * Subroutine to perform quantization table lookup. ******************************************************************************** */doubletabquant (val, index, table, code)double val;int index;struct quantable *table;int *code;/* * Quantizes val according to the LPC10 quantization table qtable[index]. * Original version of this routine by Joe Buck. Lifted for purposes of * the tape from ros1c.c. */{ register struct qtable *qt; register int mid, lo = 0, hi; hi = table[index].nval - 1; qt = table[index].rcq; while ( hi > lo ) { mid = (hi + lo) / 2; /* The assymmetry here is because the "enc" value represents the maximum * for which a particular "dec" value will be returned. */ if ( qt[mid].enc < val ) lo = mid + 1; else hi = mid; } mid = (hi + lo) / 2; *code = qt[mid].code; return (double) qt[mid].dec;}/* ******************************************************************************** * Subroutine to perform inverse quantization table lookup. ******************************************************************************** */doubletabdec(code, index, rctable)int code; /*encoded parameter*/int index; /*index of quantization table*/struct quantable *rctable; /*set of quantization tables*//*Tabdec is the "inverse" of the routine tabquant() It decodes a quantized parameter by using the same table that was used to encode it. If the code isn't in the table, a -1 is returned; otherwise the return value is the requested value.*/{ register int i, hi; struct qtable *qt; if (debug_level > 4) Fprintf (stderr, "tabdec: code = 0x%x, index = %d\n", code, index); qt = rctable[index].rcq; /*pointer to specific quantization table*/ hi = rctable[index].nval; /*number of entries in table*/ for (i=0; (i < hi); i++) if (qt[i].code == code) { if (debug_level > 4) Fprintf(stderr, "tabdec: finds value %g\n", qt[i].dec); return (qt[i].dec); } /*get here only if code not found in table*/ return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -