melp_sub.c
资源名称:melp.rar [点击查看]
上传用户:csczyc
上传日期:2021-02-19
资源大小:1051k
文件大小:31k
源码类别:
语音压缩
开发平台:
C/C++
- /*
- melp_sub.c: MELP-specific subroutines
- */
- #include <stdio.h>
- #include <math.h>
- #include "spbstd.h"
- #include "mathhalf.h"
- #include "wmops.h"
- #include "math_lib.h"
- #include "mat.h"
- #include "dsp_sub.h"
- #include "melp_sub.h"
- #include "pit.h"
- #include "constant.h"
- /*
- Name: bpvc_ana.c
- Description: Bandpass voicing analysis
- Inputs:
- speech[] - input speech signal
- fpitch[] - initial (floating point) pitch estimates
- Outputs:
- bpvc[] - bandpass voicing decisions
- pitch[] - frame pitch estimates
- Returns: void
- Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
- */
- /* Q values
- --------
- speech - Q0
- fpitch - Q7
- bpvc - Q14
- pitch - Q7
- */
- /* Filter orders */
- #define ENV_ORD 2
- #define BPF_ORD 6
- static Shortword PITCHMAX;
- static Shortword PITCHMIN;
- static Shortword PITCHMAX_Q7;
- static Shortword PITCHMIN_Q7;
- static Shortword FRAME;
- static Shortword NUM_BANDS;
- static Shortword PIT_BEG;
- static Shortword PIT_P_FR;
- static Shortword PIT_FR_BEG;
- static Shortword FIRST_CNTR;
- static Shortword BPF_BEG;
- static Shortword NUM_PITCHES;
- static Shortword LMIN;
- /* Static memory */
- static Shortword **bpfsp;
- static Shortword **bpfdelin;
- static Shortword **bpfdelout;
- static Shortword **envdel;
- static Shortword *envdel2;
- static Shortword *sigbuf;
- /* External variables */
- extern Shortword bpf_num[], bpf_den[];
- void bpvc_ana(Shortword speech[], Shortword fpitch[], Shortword bpvc[],
- Shortword pitch[])
- {
- Shortword pcorr, temp, scale;
- Shortword j,section;
- Shortword filt_index;
- /* Filter lowest band and estimate pitch */
- v_equ(&sigbuf[PIT_BEG],&bpfsp[0][0],(Shortword)(PIT_P_FR-FRAME));
- v_equ(&sigbuf[PIT_BEG+PIT_P_FR-FRAME],
- &speech[PIT_FR_BEG+PIT_P_FR-FRAME],FRAME);
- for (section=0; section<BPF_ORD/2; section++) {
- iir_2nd_s(&sigbuf[PIT_BEG+PIT_P_FR-FRAME],
- &bpf_den[section*3],&bpf_num[section*3],
- &sigbuf[PIT_BEG+PIT_P_FR-FRAME],&bpfdelin[0][section*2],
- &bpfdelout[0][section*2],FRAME);
- }
- v_equ(&bpfsp[0][0],&sigbuf[PIT_BEG+FRAME],(Shortword)(PIT_P_FR-FRAME));
- /* Scale signal for pitch correlations */
- f_pitch_scale(&sigbuf[PIT_BEG],&sigbuf[PIT_BEG],PIT_P_FR);
- *pitch = frac_pch(&sigbuf[FIRST_CNTR],&bpvc[0],fpitch[0],5,
- PITCHMIN,PITCHMAX,PITCHMIN_Q7,PITCHMAX_Q7,LMIN);
- for (j = 1; j < NUM_PITCHES; j++) {
- temp = frac_pch(&sigbuf[FIRST_CNTR],&pcorr,fpitch[j],5,
- PITCHMIN,PITCHMAX,PITCHMIN_Q7,PITCHMAX_Q7,LMIN);
- /* choose largest correlation value */
- if (pcorr > bpvc[0]) {
- *pitch = temp;
- bpvc[0] = pcorr;
- }
- }
- /* Calculate bandpass voicing for frames */
- for (j = 1; j < NUM_BANDS; j++) {
- /* Bandpass filter input speech */
- v_equ(&sigbuf[PIT_BEG],&bpfsp[j][0],(Shortword)(PIT_P_FR-FRAME));
- v_equ(&sigbuf[PIT_BEG+PIT_P_FR-FRAME],
- &speech[PIT_FR_BEG+PIT_P_FR-FRAME],FRAME);
- for (section=0; section<BPF_ORD/2; section++) {
- filt_index = j*(BPF_ORD/2)*3 + section*3;
- iir_2nd_s(&sigbuf[PIT_BEG+PIT_P_FR-FRAME],
- &bpf_den[filt_index],&bpf_num[filt_index],
- &sigbuf[PIT_BEG+PIT_P_FR-FRAME],&bpfdelin[j][section*2],
- &bpfdelout[j][section*2],FRAME);
- }
- v_equ(&bpfsp[j][0],&sigbuf[PIT_BEG+FRAME],(Shortword)(PIT_P_FR-FRAME));
- /* Scale signal for pitch correlations */
- scale = f_pitch_scale(&sigbuf[PIT_BEG],&sigbuf[PIT_BEG],PIT_P_FR);
- /* Check correlations for each frame */
- temp = frac_pch(&sigbuf[FIRST_CNTR],&bpvc[j],*pitch,0,
- PITCHMIN,PITCHMAX,PITCHMIN_Q7,PITCHMAX_Q7,LMIN);
- /* Calculate envelope of bandpass filtered input speech */
- /* update delay buffers without scaling */
- temp = shr(envdel2[j],scale);
- envdel2[j] = shr(sigbuf[PIT_BEG+FRAME-1],(Shortword)(-scale));
- v_equ_shr(&sigbuf[PIT_BEG-ENV_ORD],&envdel[j][0],scale,ENV_ORD);
- envelope(&sigbuf[PIT_BEG],temp,&sigbuf[PIT_BEG],PIT_P_FR);
- v_equ_shr(&envdel[j][0],&sigbuf[PIT_BEG+FRAME-ENV_ORD],
- (Shortword)(-scale),ENV_ORD);
- /* Scale signal for pitch correlations */
- f_pitch_scale(&sigbuf[PIT_BEG],&sigbuf[PIT_BEG],PIT_P_FR);
- /* Check correlations for each frame */
- temp = frac_pch(&sigbuf[FIRST_CNTR],&pcorr,*pitch,0,
- PITCHMIN,PITCHMAX,PITCHMIN_Q7,PITCHMAX_Q7,LMIN);
- /* reduce envelope correlation */
- pcorr = sub(pcorr,(Shortword)X01_Q14);
- if (pcorr > bpvc[j])
- bpvc[j] = pcorr;
- }
- } /* bpvc_ana */
- void bpvc_ana_init(Shortword fr, Shortword pmin, Shortword pmax,
- Shortword nbands, Shortword num_p, Shortword lmin)
- {
- /* Initialize constants */
- FRAME = fr;
- PITCHMIN = pmin;
- PITCHMAX = pmax;
- PITCHMIN_Q7 = shl_a(pmin,7);
- PITCHMAX_Q7 = shl_a(pmax,7);
- NUM_BANDS = nbands;
- NUM_PITCHES = num_p;
- LMIN = lmin;
- PIT_BEG = BPF_ORD;
- PIT_P_FR = ((2*PITCHMAX)+1);
- PIT_FR_BEG = (-PITCHMAX);
- FIRST_CNTR = (PIT_BEG+PITCHMAX);
- BPF_BEG = (PIT_BEG+PIT_P_FR-FRAME);
- /* Allocate memory */
- MEM_2ALLOC(malloc,bpfdelin,NUM_BANDS,BPF_ORD,Shortword);
- v_zap(&bpfdelin[0][0],(Shortword)(NUM_BANDS*BPF_ORD));
- MEM_2ALLOC(malloc,bpfdelout,NUM_BANDS,BPF_ORD,Shortword);
- v_zap(&bpfdelout[0][0],(Shortword)(NUM_BANDS*BPF_ORD));
- MEM_2ALLOC(malloc,bpfsp,NUM_BANDS,PIT_P_FR-FRAME,Shortword);
- v_zap(&bpfsp[0][0],(Shortword)(NUM_BANDS*(PIT_P_FR-FRAME)));
- MEM_2ALLOC(malloc,envdel,NUM_BANDS,ENV_ORD,Shortword);
- v_zap(&envdel[0][0],(Shortword)(NUM_BANDS*ENV_ORD));
- MEM_ALLOC(malloc,envdel2,NUM_BANDS,Shortword);
- v_zap(envdel2,NUM_BANDS);
- /* Allocate scratch buffer */
- MEM_ALLOC(malloc,sigbuf,PIT_BEG+PIT_P_FR,Shortword);
- }
- /*
- Name: dc_rmv.c
- Description: remove DC from input signal
- Inputs:
- sigin[] - input signal
- dcdel[] - filter delay history (size DC_ORD)
- frame - number of samples to filter
- Outputs:
- sigout[] - output signal
- dcdel[] - updated filter delay history
- Returns: void
- See_Also:
- Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
- */
- /* Filter order */
- #define DC_ORD 4
- /* DC removal filter */
- /* 4th order Chebychev Type II 60 Hz removal filter */
- /* cutoff=60 Hz, stop=-30 dB */
- /* matlab commands: [z,p,k]=cheby2(4,30,0.015,'high'); */
- /* sos=zp2sos(z,p,k); */
- /* order of sections swapped */
- /* Q13 */
- static Shortword dc_num[(DC_ORD/2)*3] = {
- 7769, -15534, 7769,
- 8007, -15999, 8007};
- /* sign of coefficients for dc_den is reversed */
- static Shortword dc_den[(DC_ORD/2)*3] = {
- -8192, 15521, -7358,
- -8192, 15986, -7836};
- void dc_rmv(Shortword sigin[],Shortword sigout[],Shortword delin[],
- Shortword delout_hi[],Shortword delout_lo[],
- Shortword frame)
- {
- Shortword section;
- /* Remove DC from input speech */
- v_equ(sigout,sigin,frame);
- for (section=0; section<DC_ORD/2; section++) {
- /* for (i=0; i<frame; i++){ */
- /* printf("%dn",sigout[i]); */
- /* } */
- iir_2nd_d(sigout,&dc_den[section*3],&dc_num[section*3],sigout,
- &delin[section*2],&delout_hi[section*2],&delout_lo[section*2],
- frame);
- /* for (i=0; i<frame; i++){ */
- /* printf("%dn",sigout[i]); */
- /* } */
- }
- }
- /*
- Name: gain_ana.c
- Description: analyze gain level for input signal
- Inputs:
- sigin[] - input signal
- pitch - pitch value (for pitch synchronous window)
- minlength - minimum window length
- maxlength - maximum window length
- Outputs:
- Returns: log gain in dB
- See_Also:
- Copyright (c) 1997 by Texas Instruments, Inc. All rights reserved.
- Q values
- --------
- pitch - Q7
- sigin (speech) - Q0
- */
- #define CONSTANT_SCALE 0
- #define MINGAIN 0
- #define LOG10OF2X2 1233 /* 2*log10(2) in Q11 */
- Shortword gain_ana(Shortword sigin[], Shortword pitch,
- Shortword minlength, Shortword maxlength)
- {
- Shortword length; /* Q0 */
- Shortword flength; /* Q6 */
- Shortword gain; /* Q8 */
- Shortword pitch_Q6; /* Q6 */
- Shortword scale;
- Shortword tmp_minlength;
- Shortword sigbegin;
- Shortword *temp_buf, *tmp_sig;
- Shortword S_temp1, S_temp2;
- Longword L_temp;
- Longword L_temp1,L_temp2;
- /* initialize scaled pitch and minlength */
- /* pitch_Q6 = shr(pitch,1); Q7->Q6 data_move();mark del */
- /* */
- /* tmp_minlength = shl(minlength,6); // data_move();mark del */
- L_temp1 = _shr2((Longword)pitch,1);
- pitch_Q6 = (Shortword) (0x0000ffffL & L_temp1);
- tmp_minlength = shl_a(minlength,6);
- /* Find shortest pitch multiple window length (floating point) */
- flength = pitch_Q6; // data_move();mark del
- while (flength < tmp_minlength) {
- /* increment complexity for while statement */
- // compare_nonzero();mark del
- /* flength = add(flength,pitch_Q6); // data_move();mark del */
- L_temp1 = _sadd2((Longword)flength,(Longword)pitch_Q6);
- flength = (Shortword) (0x0000ffffL & L_temp1);
- }
- /* Convert window length to integer and check against maximum */
- /* length = shr(add(flength, (Shortword)X05_Q6), 6); // data_move();mark del */
- L_temp1 = _sadd2((Longword)flength, (Longword)X05_Q6);
- L_temp1 = _shr2(L_temp1,6);
- length = (Shortword) (0x0000ffffL & L_temp1);
- /* increment complexity for if statement */
- // compare_nonzero();mark del
- if (length > maxlength) {
- /* divide by 2 */
- /* length = shr(length,1); // data_move();mark del */
- L_temp1 = _shr2((Longword)length,1);
- length = (Shortword) (0x0000ffffL & L_temp1);
- }
- /* Calculate RMS gain in dB */
- /*gain = 10.0*log10(0.01+(v_magsq(&sigin[-(length/2)],length)/length));*/
- /* use this adaptive scaling if more precision needed at low
- levels. Seemed like it wasn't worth the mips */
- /* sigbegin = negate(shr(length,1)); */
- L_temp2 = _shr2((Longword)length,1);
- sigbegin = (Shortword) (0x0000ffffL & L_temp2);
- sigbegin = negate(sigbegin);
- /* Right shift input signal and put in temp buffer */
- MEM_ALLOC(MALLOC,temp_buf,length,Shortword);
- #if(CONSTANT_SCALE)
- scale=3;
- #else
- scale = 3;
- v_equ_shr(temp_buf,&sigin[sigbegin],scale,length);
- L_temp = L_v_magsq(temp_buf,length,0,1);
- // compare_zero();mark del
- if (L_temp) {
- /* S_temp1 = norm_l(L_temp); */
- L_temp1 = _norm(L_temp);
- if (L_temp == 0){
- L_temp1 = (Longword)0;
- }
- S_temp1 = (Shortword) (0x0000ffffL & L_temp1);
- scale = sub(scale,shr_a(S_temp1,1));
- if (scale < 0)
- scale = 0;
- }
- else
- scale = 0;
- #endif
- if (scale)
- v_equ_shr(temp_buf,&sigin[sigbegin],scale,length);
- else
- v_equ(temp_buf,&sigin[sigbegin],length);
- tmp_sig = temp_buf - sigbegin;
- /* increment complexity for if statement */
- // compare_zero();mark del
- if (scale) {
- L_temp = L_v_magsq(&tmp_sig[sigbegin],length,0,0);
- S_temp1 = L_log10_fxp(L_temp,0);
- S_temp2 = L_log10_fxp(L_deposit_l(length),0);
- S_temp1 = sub(S_temp1,S_temp2);
- /* shift right to counter-act for the shift in L_mult */
- /* S_temp2 = extract_l(L_shr(L_mult(scale,LOG10OF2X2),1)); */
- /* S_temp1 = add(S_temp1,S_temp2); */
- /* S_temp1 = mult(TEN_Q11,S_temp1); */
- /* gain = shl(S_temp1,1); // data_move();mark del */
- L_temp2 = _sshvr(_smpy(scale,LOG10OF2X2),1);
- S_temp2 = (Shortword) (0x0000ffffL & L_temp2);
- L_temp1 = _sadd2((Longword)S_temp1,(Longword)S_temp2);
- S_temp1 = (Shortword) (0x0000ffffL & L_temp1);
- L_temp2 = _smpy(TEN_Q11,S_temp1);
- S_temp1 = (Shortword) (0x0000ffffL & (L_temp2 >> 16));
- gain = shl_a(S_temp1,1);
- }
- else {
- L_temp = L_v_magsq(&tmp_sig[sigbegin],length,0,0);
- /* Add one to avoid log of a zero value */
- if (L_temp == 0)
- S_temp1 = N2_Q11;
- else
- S_temp1 = L_log10_fxp(L_temp,0);
- S_temp2 = L_log10_fxp(L_deposit_l(length),0);
- S_temp1 = sub(S_temp1,S_temp2);
- /* S_temp1 = mult(TEN_Q11,S_temp1); */
- L_temp1 = _smpy(TEN_Q11,S_temp1);
- S_temp1 = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- gain = shl_a(S_temp1,1); // data_move();mark del
- }
- /* increment complexity for if statement */
- // compare_nonzero();mark del
- if (gain < MINGAIN) {
- gain = MINGAIN; // data_move();mark del
- }
- MEM_FREE(FREE,temp_buf);
- return(gain);
- } /* gain_ana */
- /*
- Name: lin_int_bnd.c
- Description: Linear interpolation within bounds
- Inputs:
- x - input X value
- xmin - minimum X value
- xmax - maximum X value
- ymin - minimum Y value
- ymax - maximum Y value
- Returns: y - interpolated and bounded y value
- Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
- Q values:
- x,xmin,xmax - Q8
- y,ymin,ymax - Q15
- */
- Shortword lin_int_bnd(Shortword x,Shortword xmin,Shortword xmax,
- Shortword ymin,Shortword ymax)
- {
- Shortword y;
- Shortword temp1,temp2;
- Longword L_temp,L_y;
- if (x <= xmin)
- y = ymin;
- else if (x >= xmax)
- y = ymax;
- else {
- /* y = ymin + (x-xmin)*(ymax-ymin)/(xmax-xmin); */
- temp1 = sub(x,xmin);
- temp2 = sub(ymax,ymin);
- /* temp1 = mult(temp1,temp2); temp1 in Q8 */
- L_temp = _smpy(temp1,temp2);
- temp1 = (Shortword) (0x0000ffffL & (L_temp >> 16));
- temp2 = sub(xmax,xmin);
- /* temp1 always smaller than temp2 */
- temp1 = divide_s(temp1,temp2); /* temp1 in Q15 */
- /* y = add(ymin,temp1); */
- L_y = _sadd2((Longword)ymin,(Longword)temp1);
- y = (Shortword) (0x0000ffffL & L_y);
- }
- return(y);
- }
- /*
- Name: noise_est.c
- Description: Estimate long-term noise floor
- Inputs:
- gain - input gain (in dB)
- noise_gain - current noise gain estimate
- up - maximum up stepsize
- down - maximum down stepsize
- min - minimum allowed gain
- max - maximum allowed gain
- Outputs:
- noise_gain - updated noise gain estimate
- Returns: void
- Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
- Q values:
- gain - Q8
- *noise_gain - Q8
- up - Q19
- down - Q17
- min - Q8
- max - Q8
- */
- void noise_est(Shortword gain,Shortword *noise_gain,Shortword up,
- Shortword down,Shortword min,Shortword max)
- {
- Shortword temp1,temp2;
- Longword L_noise_gain,L_temp;
- Longword L_Prod;
- /* Update noise_gain */
- /* temp1 = add(*noise_gain,up);
- temp2 = add(*noise_gain,down); */
- /* L_noise_gain = L_deposit_h(*noise_gain); L_noise_gain in Q24 */
- /* L_temp = L_shl(L_deposit_l(up),5); */
- /* L_temp = L_add(L_noise_gain,L_temp); */
- /* temp1 = round(L_temp); */
- L_noise_gain = (Longword) (*noise_gain) << 16;
- L_temp = _sshl((Longword)up,5);
- L_temp = _sadd(L_noise_gain,L_temp);
- L_Prod = _sadd(L_temp, 0x00008000L); /* round MSP */
- temp1 = (Shortword)(0x0000ffffL & (L_Prod >> 16));
- /* L_temp = L_shl(L_deposit_l(down),7); */
- /* L_temp = L_add(L_noise_gain,L_temp); */
- /* temp2 = round(L_temp); */
- L_temp = _sshl((Longword)down,7);
- L_temp = _sadd(L_noise_gain,L_temp);
- L_Prod = _sadd(L_temp, 0x00008000L); /* round MSP */
- temp2 = (Shortword)(0x0000ffffL & (L_Prod >> 16));
- // compare_nonzero();mark del
- if (gain > temp1)
- *noise_gain = temp1;
- else if (gain < temp2)
- *noise_gain = temp2;
- else
- *noise_gain = gain;
- /* Constrain total range of noise_gain */
- // compare_nonzero();mark del
- if (*noise_gain < min)
- *noise_gain = min;
- // compare_nonzero();mark del
- if (*noise_gain > max)
- *noise_gain = max;
- }
- /*
- Name: noise_sup.c
- Description: Perform noise suppression on speech gain
- Inputs: (all in dB)
- gain - input gain (in dB)
- noise_gain - current noise gain estimate (in dB)
- max_noise - maximum allowed noise gain
- max_atten - maximum allowed attenuation
- nfact - noise floor boost
- Outputs:
- gain - updated gain
- Returns: void
- Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
- Q values:
- *gain - Q8
- noise_gain - Q8
- max_noise - Q8
- max_atten - Q8
- nfact - Q8
- */
- void noise_sup(Shortword *gain,Shortword noise_gain,Shortword max_noise,
- Shortword max_atten,Shortword nfact)
- {
- Shortword gain_lev,suppress;
- Shortword temp;
- Longword L_temp;
- Longword L_temp1;
- Shortword temp1;
- /* Reduce effect for louder background noise */
- if (noise_gain > max_noise)
- noise_gain = max_noise;
- /* Calculate suppression factor */
- /* gain_lev = sub(*gain,add(noise_gain,nfact)); */
- L_temp1 = _sadd2((Longword)noise_gain,(Longword)nfact);
- temp1 = (Shortword) (0x0000ffffL & L_temp1);
- gain_lev = sub(*gain,temp1);
- // compare_nonzero();mark del
- if (gain_lev > X0001_Q8) {
- /* suppress = -10.0*log10(1.0 - pow(10.0,-0.1*gain_lev)); */
- /* L_temp = L_mult((Shortword)M01_Q15,gain_lev); L_temp in Q24 */
- /* temp = extract_h(L_shl(L_temp,4)); temp in Q12 */
- L_temp = _smpy((Shortword)M01_Q15,gain_lev);
- L_temp = _sshl(L_temp,4);
- temp = (Shortword) (0x0000ffffL & (L_temp >> 16));
- temp = pow10_fxp(temp,14);
- temp = sub(ONE_Q14,temp);
- /* suppress = mult(M10_Q11,log10_fxp(temp,14)); log returns Q12 */
- L_temp1 = _smpy(M10_Q11,log10_fxp(temp,14));
- suppress = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- // compare_nonzero();mark del
- if (suppress > max_atten)
- suppress = max_atten;
- }
- else
- suppress = max_atten;
- /* Apply suppression to input gain */
- *gain = sub(*gain,suppress);
- } /* noise_sup */
- /*
- Name: q_bpvc.c, q_bpvc_dec.c
- Description: Quantize/decode bandpass voicing
- Inputs:
- bpvc, bpvc_index
- bpthresh - threshold
- NUM_BANDS - number of bands
- Outputs:
- bpvc, bpvc_index
- Returns: uv_flag - flag if unvoiced
- Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
- Q values:
- *bpvc - Q14
- bpthresh - Q14
- */
- /* Compile constants */
- #define INVALID_BPVC 0001
- Shortword q_bpvc(Shortword *bpvc,Shortword *bpvc_index,Shortword bpthresh,
- Shortword NUM_BANDS)
- {
- Shortword j, uv_flag;
- uv_flag = 1; // data_move();mark del
- if (bpvc[0] > bpthresh) {
- /* Voiced: pack bandpass voicing */
- uv_flag = 0; // data_move();mark del
- *bpvc_index = 0; // data_move();mark del
- bpvc[0] = ONE_Q14; // data_move();mark del
- for (j = 1; j < NUM_BANDS; j++) {
- *bpvc_index = shl(*bpvc_index,1); /* left shift one bit */
- if (bpvc[j] > bpthresh) {
- bpvc[j] = ONE_Q14; // data_move();mark del
- *bpvc_index |= 1; // logic();mark del
- }
- else {
- bpvc[j] = 0; // data_move();mark del
- *bpvc_index |= 0; // logic();mark del
- }
- }
- /* Don't use invalid code (only top band voiced) */
- if (*bpvc_index == INVALID_BPVC) {
- bpvc[(NUM_BANDS-1)] = 0;
- *bpvc_index = 0;
- }
- }
- else {
- /* Unvoiced: force all bands unvoiced */
- *bpvc_index = 0;
- for (j = 0; j < NUM_BANDS; j++)
- bpvc[j] = 0;
- }
- return(uv_flag);
- } /* q_bpvc */
- void q_bpvc_dec(Shortword *bpvc,Shortword *bpvc_index,Shortword uv_flag,
- Shortword NUM_BANDS)
- {
- Shortword j;
- if (uv_flag) {
- /* Unvoiced: set all bpvc to 0 */
- *bpvc_index = 0;
- bpvc[0] = 0;
- }
- else {
- /* Voiced: set bpvc[0] to 1.0 */
- bpvc[0] = ONE_Q14;
- }
- if (*bpvc_index == INVALID_BPVC) {
- /* Invalid code received: set higher band voicing to zero */
- *bpvc_index = 0;
- }
- /* Decode remaining bands */
- for (j = NUM_BANDS-1; j > 0; j--) {
- // compare_nonzero();mark del
- // logic();mark del
- if ((*bpvc_index & 1) == 1)
- bpvc[j] = ONE_Q14;
- else
- bpvc[j] = 0;
- *bpvc_index = shr_a(*bpvc_index,1);
- }
- } /* q_bpvc_dec */
- /*
- Name: q_gain.c, q_gain_dec.c
- Description: Quantize/decode two gain terms using quasi-differential coding
- Inputs:
- gain[2],gain_index[2]
- GN_QLO,GN_QUP,GN_QLEV for second gain term
- Outputs:
- gain[2],gain_index[2]
- Returns: void
- Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
- Q values:
- *gain - Q8
- GN_QLO - Q8
- GN_QUP - Q8
- GN_QLEV_Q - Q10
- */
- /* Compile constants */
- #define GAIN_INT_DB_Q8 1280 /* (5*(1<<8)) */
- void q_gain(Shortword *gain,Shortword *gain_index,Shortword GN_QLO,
- Shortword GN_QUP,Shortword GN_QLEV,Shortword GN_QLEV_Q,
- Shortword double_flag,Shortword scale)
- {
- static Shortword prev_gain = 0;
- Shortword temp,temp2;
- /* Quantize second gain term with uniform quantizer */
- quant_u(&gain[1],&gain_index[1],GN_QLO,GN_QUP,GN_QLEV,GN_QLEV_Q,
- double_flag,scale);
- /* Check for intermediate gain interpolation */
- if (gain[0] < GN_QLO) {
- gain[0] = GN_QLO; // data_move();mark del
- }
- if (gain[0] > GN_QUP) {
- gain[0] = GN_QUP; // data_move();mark del
- }
- /* if (fabs(gain[1] - prev_gain) < GAIN_INT_DB &&
- fabs(gain[0] - 0.5*(gain[1]+prev_gain)) < 3.0) */
- temp = add(shr(gain[1],1),shr(prev_gain,1));
- if (abs_s(sub(gain[1],prev_gain)) < GAIN_INT_DB_Q8 &&
- abs_s(sub(gain[0],temp)) < THREE_Q8) {
- /* interpolate and set special code */
- /* gain[0] = 0.5*(gain[1]+prev_gain); */
- gain[0] = temp;
- gain_index[0] = 0;
- }
- else {
- /* Code intermediate gain with 7-levels */
- if (prev_gain < gain[1]) {
- temp = prev_gain; // data_move();mark del
- temp2 = gain[1]; // data_move();mark del
- }
- else {
- temp = gain[1]; // data_move();mark del
- temp2 = prev_gain; // data_move();mark del
- }
- temp = sub(temp,SIX_Q8);
- temp2 = add(temp2,SIX_Q8);
- if (temp < GN_QLO) {
- temp = GN_QLO; // data_move();mark del
- }
- if (temp2 > GN_QUP) {
- temp2 = GN_QUP; // data_move();mark del
- }
- quant_u(&gain[0],&gain_index[0],temp,temp2,6,SIX_Q12,0,3);
- /* Skip all-zero code */
- gain_index[0] = add(gain_index[0],1);
- }
- /* Update previous gain for next time */
- prev_gain = gain[1]; // data_move();mark del
- } /* q_gain */
- void q_gain_dec(Shortword *gain,Shortword *gain_index,Shortword GN_QLO,
- Shortword GN_QUP,Shortword GN_QLEV_Q,Shortword scale)
- {
- static Shortword prev_gain = 0;
- static Shortword prev_gain_err = 0;
- Shortword temp,temp2;
- Longword L_temp,L_temp1;
- /* Decode second gain term */
- quant_u_dec(gain_index[1],&gain[1],GN_QLO,GN_QUP,GN_QLEV_Q,scale);
- if (gain_index[0] == 0) {
- /* interpolation bit code for intermediate gain */
- temp = sub(gain[1],prev_gain);
- /* temp = abs_s(temp); */
- L_temp = _abs2((Longword)temp);
- temp = (Shortword) (0x0000ffffL & L_temp);
- // compare_nonzero();mark del
- if (temp > GAIN_INT_DB_Q8) {
- /* Invalid received data (bit error) */
- if (prev_gain_err == 0) {
- /* First time: don't allow gain excursion */
- gain[1] = prev_gain;
- }
- prev_gain_err = 1;
- }
- else
- prev_gain_err = 0;
- /* Use interpolated gain value */
- /* gain[0] = 0.5*(gain[1]+prev_gain); */
- /* gain[0] = add(shr(gain[1],1),shr(prev_gain,1)); */
- L_temp = _shr2((Longword)(gain[1]),1);
- L_temp1 = _shr2((Longword)prev_gain,1);
- L_temp = _sadd2(L_temp,L_temp1);
- gain[0] = (Shortword) (0x0000ffffL & L_temp);
- }
- else {
- /* Decode 7-bit quantizer for first gain term */
- prev_gain_err = 0;
- gain_index[0] = sub(gain_index[0],1);
- // compare_nonzero();mark del
- if (prev_gain < gain[1]) {
- temp = prev_gain;
- temp2 = gain[1];
- }
- else {
- temp = gain[1];
- temp2 = prev_gain;
- }
- temp = sub(temp,SIX_Q8);
- /* temp2 = add(temp2,SIX_Q8); */
- L_temp = _sadd2((Longword)temp2,(Longword)SIX_Q8);
- temp2 = (Shortword) (0x0000ffffL & L_temp);
- // compare_nonzero();mark del
- if (temp < GN_QLO)
- temp = GN_QLO;
- // compare_nonzero();mark del
- if (temp2 > GN_QUP)
- temp2 = GN_QUP;
- quant_u_dec(gain_index[0],&gain[0],temp,temp2,SIX_Q12,3);
- }
- /* Update previous gain for next time */
- prev_gain = gain[1]; // data_move();mark del
- } /* q_gain_dec */
- /*
- Name: scale_adj.c
- Description: Adjust scaling of output speech signal.
- Inputs:
- speech - speech signal
- gain - desired RMS gain (log gain)
- prev_scale - previous scale factor
- length - number of samples in signal
- SCALEOVER - number of points to interpolate scale factor
- Warning: SCALEOVER is assumed to be less than length.
- Outputs:
- speech - scaled speech signal
- prev_scale - updated previous scale factor
- Returns: void
- Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
- Q values:
- *speech - Q0
- gain - Q12
- *prev_scale - Q13
- */
- void scale_adj(Shortword *speech, Shortword gain, Shortword *prev_scale,
- Shortword length, Shortword SCALEOVER,
- Shortword INV_SCALEOVER_Q18)
- {
- Shortword i;
- Shortword scale;
- Shortword shift,log_magsq,log_length;
- Shortword temp;
- Shortword *tempbuf;
- Longword L_magsq,L_length,interp1,interp2;
- Longword L_temp;
- Longword L_temp1;
- /* Calculate desired scaling factor to match gain level */
- /* scale = gain / (sqrt(v_magsq(&speech[0],length) / length) + .01); */
- /* find normalization factor for buffer */
- MEM_ALLOC(MALLOC,tempbuf,length,Shortword);
- shift = 4;
- v_equ_shr(tempbuf,speech,shift,length);
- L_magsq = L_v_magsq(tempbuf,length,0,1);
- // compare_zero();mark del
- if (L_magsq) {
- /* normalize with 1 bit of headroom */
- /* temp = norm_l(L_magsq); */
- L_temp1 = _norm(L_magsq);
- if (L_magsq == 0){
- L_temp1 = (Longword)0;
- }
- temp = (Shortword) (0x0000ffffL & L_temp1);
- temp = sub(temp,1);
- shift = sub(shift,shr_a(temp,1));
- }
- else
- shift = 0;
- v_equ_shr(tempbuf,speech,shift,length);
- /* exp = log(2^shift) */
- shift = shl_a(shift,1); /* total compensation = shift*2 */
- temp = shl(ONE_Q8,shift);
- shift = log10_fxp(temp,8); /* shift in Q12 */
- L_magsq = L_v_magsq(tempbuf,length,0,0);
- /* L_magsq = L_add(L_magsq,1); ensure L_magsq is not zero */
- L_magsq = _sadd(L_magsq,1);
- log_magsq = L_log10_fxp(L_magsq,0); /* log_magsq in Q11 */
- /* L_magsq = log_magsq in Q12 */
- /* L_magsq = L_deposit_l(log_magsq); */
- /* L_magsq = L_shl(L_magsq,1); */
- L_magsq = (Longword)log_magsq;
- L_magsq = _sshl(L_magsq,1);
- /* compensate for normalization */
- /* L_magsq = log magnitude/2 in Q13 */
- /* L_temp = L_deposit_l(shift); */
- /* L_magsq = L_add(L_magsq,L_temp); */
- L_temp = (Longword)shift;
- L_magsq = _sadd(L_magsq,L_temp);
- temp = shl_a(length,7);
- log_length = log10_fxp(temp,7); /* log_length in Q12 */
- /* L_length = log_length/2 in Q13 */
- /* L_length = L_deposit_l(log_length); */
- L_length = (Longword)log_length;
- /* L_temp = L_deposit_l(gain); */
- /* L_temp = L_shl(L_temp,1); L_temp in Q13 */
- /* L_temp = L_sub(L_temp,L_magsq); */
- /* L_temp = L_add(L_temp,L_length); */
- /* L_temp = L_shr(L_temp,1); Q13 -> Q12 */
- /* temp = extract_l(L_temp); temp in Q12 */
- L_temp = (Longword)gain;
- L_temp = _sshl(L_temp,1); /* L_temp in Q13 */
- L_temp = _ssub(L_temp,L_magsq);
- L_temp = _sadd(L_temp,L_length);
- L_temp = _sshvr(L_temp,1); /* Q13 -> Q12 */
- temp = (Shortword)(0x0000ffffL & L_temp); /* temp in Q12 */
- scale = pow10_fxp(temp,13);
- /* interpolate scale factors for first SCALEOVER points */
- for (i = 1; i < SCALEOVER; i++) {
- /* speech[i-1] *= ((scale*i + *prev_scale*(SCALEOVER-i))
- * (1.0/SCALEOVER) ); */
- temp = sub(SCALEOVER,i);
- temp = shl_a(temp,11);
- /* L_temp = L_mult(temp,INV_SCALEOVER_Q18); L_temp in Q30 */
- /* L_temp = L_shl(L_temp,1); L_temp in Q31 */
- /* temp = extract_h(L_temp); temp in Q15 */
- /* interp1 = L_mult(*prev_scale,temp); interp1 in Q29 */
- L_temp = _smpy(temp,INV_SCALEOVER_Q18); /* L_temp in Q30 */
- L_temp = _sshl(L_temp,1); /* L_temp in Q31 */
- temp = (Shortword) (0x0000ffffL & (L_temp >> 16)); /* temp in Q15 */
- interp1 = _smpy(*prev_scale,temp); /* interp1 in Q29 */
- temp = shl_a(i,11);
- /* L_temp = L_mult(temp,INV_SCALEOVER_Q18); L_temp in Q30 */
- /* L_temp = L_shl(L_temp,1); L_temp in Q31 */
- /* temp = extract_h(L_temp); temp in Q15 */
- /* interp2 = L_mult(scale,temp); interp2 in Q29 */
- /* L_temp = L_add(interp1,interp2); */
- /* interp1 = extract_h(L_temp); interp1 in Q13 */
- L_temp = _smpy(temp,INV_SCALEOVER_Q18); /* L_temp in Q30 */
- L_temp = _sshl(L_temp,1); /* L_temp in Q31 */
- temp = (Shortword) (0x0000ffffL & (L_temp >> 16)); /* temp in Q15 */
- interp2 = _smpy(scale,temp); /* interp2 in Q29 */
- L_temp = _sadd(interp1,interp2);
- interp1 = (Shortword) (0x0000ffffL & (L_temp >> 16)); /* interp1 in Q13 */
- /* L_temp = L_mult(speech[i-1],(Shortword)interp1); */
- /* L_temp = L_shl(L_temp,2); */
- /* speech[i-1] = extract_h(L_temp); */
- L_temp = _smpy(speech[i-1],(Shortword)interp1);
- L_temp = _sshl(L_temp,2);
- speech[i-1] = (Shortword) (0x0000ffffL & (L_temp >> 16));
- }
- /* Scale rest of signal */
- v_scale_shl(&speech[SCALEOVER-1],scale,(Shortword)(length-SCALEOVER+1),2);
- /* Update previous scale factor for next call */
- *prev_scale = scale; // data_move();mark del
- MEM_FREE(FREE,tempbuf);
- } /* scale_adj */