melp_sub.c
上传用户:csczyc
上传日期:2021-02-19
资源大小:1051k
文件大小:31k
源码类别:

语音压缩

开发平台:

C/C++

  1. /*
  2.   melp_sub.c: MELP-specific subroutines
  3. */
  4. #include <stdio.h>
  5. #include <math.h>
  6. #include "spbstd.h"
  7. #include "mathhalf.h"
  8. #include "wmops.h"
  9. #include "math_lib.h"
  10. #include "mat.h"
  11. #include "dsp_sub.h"
  12. #include "melp_sub.h"
  13. #include "pit.h"
  14. #include "constant.h"
  15. /*
  16.     Name: bpvc_ana.c
  17.     Description: Bandpass voicing analysis
  18.     Inputs:
  19.       speech[] - input speech signal
  20.       fpitch[] - initial (floating point) pitch estimates
  21.     Outputs: 
  22.       bpvc[] - bandpass voicing decisions
  23.       pitch[] - frame pitch estimates
  24.     Returns: void 
  25.     Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.
  26. */
  27. /* Q values
  28.    --------
  29.    speech - Q0
  30.    fpitch - Q7
  31.    bpvc - Q14
  32.    pitch - Q7
  33. */
  34. /* Filter orders */
  35. #define ENV_ORD 2
  36. #define BPF_ORD 6
  37. static Shortword PITCHMAX;
  38. static Shortword PITCHMIN;
  39. static Shortword PITCHMAX_Q7;
  40. static Shortword PITCHMIN_Q7;
  41. static Shortword FRAME;
  42. static Shortword NUM_BANDS;
  43. static Shortword PIT_BEG;
  44. static Shortword PIT_P_FR;
  45. static Shortword PIT_FR_BEG;
  46. static Shortword FIRST_CNTR;
  47. static Shortword BPF_BEG;      
  48. static Shortword NUM_PITCHES;
  49. static Shortword LMIN;
  50. /* Static memory */
  51. static Shortword **bpfsp;
  52. static Shortword **bpfdelin;
  53. static Shortword **bpfdelout;
  54. static Shortword **envdel;
  55. static Shortword *envdel2;
  56. static Shortword *sigbuf;
  57. /* External variables */
  58. extern Shortword bpf_num[], bpf_den[];
  59. void bpvc_ana(Shortword speech[], Shortword fpitch[], Shortword bpvc[], 
  60.       Shortword pitch[])
  61. {
  62.     Shortword pcorr, temp, scale;
  63.     Shortword j,section;
  64.     Shortword filt_index;
  65.     /* Filter lowest band and estimate pitch */
  66.     v_equ(&sigbuf[PIT_BEG],&bpfsp[0][0],(Shortword)(PIT_P_FR-FRAME));
  67.     v_equ(&sigbuf[PIT_BEG+PIT_P_FR-FRAME],
  68.   &speech[PIT_FR_BEG+PIT_P_FR-FRAME],FRAME);
  69.     for (section=0; section<BPF_ORD/2; section++) {
  70.       iir_2nd_s(&sigbuf[PIT_BEG+PIT_P_FR-FRAME],
  71. &bpf_den[section*3],&bpf_num[section*3],
  72. &sigbuf[PIT_BEG+PIT_P_FR-FRAME],&bpfdelin[0][section*2],
  73. &bpfdelout[0][section*2],FRAME);
  74.     }
  75.     v_equ(&bpfsp[0][0],&sigbuf[PIT_BEG+FRAME],(Shortword)(PIT_P_FR-FRAME));
  76.     /* Scale signal for pitch correlations */
  77.     f_pitch_scale(&sigbuf[PIT_BEG],&sigbuf[PIT_BEG],PIT_P_FR);
  78.     *pitch = frac_pch(&sigbuf[FIRST_CNTR],&bpvc[0],fpitch[0],5,
  79.       PITCHMIN,PITCHMAX,PITCHMIN_Q7,PITCHMAX_Q7,LMIN);
  80.     for (j = 1; j < NUM_PITCHES; j++) {
  81.       temp = frac_pch(&sigbuf[FIRST_CNTR],&pcorr,fpitch[j],5,
  82.       PITCHMIN,PITCHMAX,PITCHMIN_Q7,PITCHMAX_Q7,LMIN);
  83.       /* choose largest correlation value */
  84.       if (pcorr > bpvc[0]) {
  85. *pitch = temp;
  86. bpvc[0] = pcorr; 
  87.       }
  88.     }
  89.     
  90.     /* Calculate bandpass voicing for frames */
  91.     
  92.     for (j = 1; j < NUM_BANDS; j++) {
  93.       /* Bandpass filter input speech */
  94.       v_equ(&sigbuf[PIT_BEG],&bpfsp[j][0],(Shortword)(PIT_P_FR-FRAME));
  95.       v_equ(&sigbuf[PIT_BEG+PIT_P_FR-FRAME],
  96.     &speech[PIT_FR_BEG+PIT_P_FR-FRAME],FRAME);
  97.       for (section=0; section<BPF_ORD/2; section++) {
  98.   filt_index = j*(BPF_ORD/2)*3 + section*3;
  99.   iir_2nd_s(&sigbuf[PIT_BEG+PIT_P_FR-FRAME],
  100.     &bpf_den[filt_index],&bpf_num[filt_index],
  101.     &sigbuf[PIT_BEG+PIT_P_FR-FRAME],&bpfdelin[j][section*2],
  102.     &bpfdelout[j][section*2],FRAME);
  103.       }
  104.       v_equ(&bpfsp[j][0],&sigbuf[PIT_BEG+FRAME],(Shortword)(PIT_P_FR-FRAME));
  105.       /* Scale signal for pitch correlations */
  106.       scale = f_pitch_scale(&sigbuf[PIT_BEG],&sigbuf[PIT_BEG],PIT_P_FR);
  107.       /* Check correlations for each frame */
  108.       temp = frac_pch(&sigbuf[FIRST_CNTR],&bpvc[j],*pitch,0,
  109.       PITCHMIN,PITCHMAX,PITCHMIN_Q7,PITCHMAX_Q7,LMIN);
  110.       /* Calculate envelope of bandpass filtered input speech */
  111.       /* update delay buffers without scaling */
  112.       temp = shr(envdel2[j],scale);
  113.       envdel2[j] = shr(sigbuf[PIT_BEG+FRAME-1],(Shortword)(-scale));
  114.       v_equ_shr(&sigbuf[PIT_BEG-ENV_ORD],&envdel[j][0],scale,ENV_ORD);
  115.       envelope(&sigbuf[PIT_BEG],temp,&sigbuf[PIT_BEG],PIT_P_FR);
  116.       v_equ_shr(&envdel[j][0],&sigbuf[PIT_BEG+FRAME-ENV_ORD],
  117. (Shortword)(-scale),ENV_ORD);
  118.       /* Scale signal for pitch correlations */
  119.       f_pitch_scale(&sigbuf[PIT_BEG],&sigbuf[PIT_BEG],PIT_P_FR);
  120.       /* Check correlations for each frame */
  121.       temp = frac_pch(&sigbuf[FIRST_CNTR],&pcorr,*pitch,0,
  122.       PITCHMIN,PITCHMAX,PITCHMIN_Q7,PITCHMAX_Q7,LMIN);
  123.       /* reduce envelope correlation */
  124.       pcorr = sub(pcorr,(Shortword)X01_Q14);
  125.       if (pcorr > bpvc[j])
  126. bpvc[j] = pcorr;
  127.     }
  128. } /* bpvc_ana */
  129. void bpvc_ana_init(Shortword fr, Shortword pmin, Shortword pmax, 
  130.    Shortword nbands, Shortword num_p, Shortword lmin)
  131. {
  132.     /* Initialize constants */
  133.     FRAME = fr;
  134.     PITCHMIN = pmin;
  135.     PITCHMAX = pmax;
  136.     PITCHMIN_Q7 = shl_a(pmin,7);
  137.     PITCHMAX_Q7 = shl_a(pmax,7);
  138.     NUM_BANDS = nbands;
  139.     NUM_PITCHES = num_p;
  140.     LMIN = lmin;
  141.     PIT_BEG = BPF_ORD;
  142.     PIT_P_FR = ((2*PITCHMAX)+1);
  143.     PIT_FR_BEG = (-PITCHMAX);
  144.     FIRST_CNTR = (PIT_BEG+PITCHMAX);
  145.     BPF_BEG = (PIT_BEG+PIT_P_FR-FRAME);
  146.     /* Allocate memory */
  147.     MEM_2ALLOC(malloc,bpfdelin,NUM_BANDS,BPF_ORD,Shortword);
  148.     v_zap(&bpfdelin[0][0],(Shortword)(NUM_BANDS*BPF_ORD));
  149.     MEM_2ALLOC(malloc,bpfdelout,NUM_BANDS,BPF_ORD,Shortword);
  150.     v_zap(&bpfdelout[0][0],(Shortword)(NUM_BANDS*BPF_ORD));
  151.     MEM_2ALLOC(malloc,bpfsp,NUM_BANDS,PIT_P_FR-FRAME,Shortword);
  152.     v_zap(&bpfsp[0][0],(Shortword)(NUM_BANDS*(PIT_P_FR-FRAME)));
  153.     MEM_2ALLOC(malloc,envdel,NUM_BANDS,ENV_ORD,Shortword);
  154.     v_zap(&envdel[0][0],(Shortword)(NUM_BANDS*ENV_ORD));
  155.     MEM_ALLOC(malloc,envdel2,NUM_BANDS,Shortword);
  156.     v_zap(envdel2,NUM_BANDS);
  157.     /* Allocate scratch buffer */
  158.     MEM_ALLOC(malloc,sigbuf,PIT_BEG+PIT_P_FR,Shortword);
  159. }
  160. /*
  161.     Name: dc_rmv.c
  162.     Description: remove DC from input signal
  163.     Inputs: 
  164.       sigin[] - input signal
  165.       dcdel[] - filter delay history (size DC_ORD)
  166.       frame - number of samples to filter
  167.     Outputs: 
  168.       sigout[] - output signal
  169.       dcdel[] - updated filter delay history
  170.     Returns: void 
  171.     See_Also:
  172.     Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.
  173. */
  174. /* Filter order */
  175. #define DC_ORD 4
  176. /* DC removal filter */
  177. /* 4th order Chebychev Type II 60 Hz removal filter */
  178. /* cutoff=60 Hz, stop=-30 dB */
  179. /* matlab commands: [z,p,k]=cheby2(4,30,0.015,'high');  */
  180. /*                      sos=zp2sos(z,p,k);        */
  181. /* order of sections swapped */
  182. /* Q13 */
  183. static Shortword dc_num[(DC_ORD/2)*3] = {
  184.            7769, -15534, 7769,
  185.            8007, -15999, 8007};
  186. /* sign of coefficients for dc_den is reversed */
  187. static Shortword dc_den[(DC_ORD/2)*3] = {
  188.            -8192, 15521, -7358,
  189.    -8192, 15986, -7836};
  190. void dc_rmv(Shortword sigin[],Shortword sigout[],Shortword delin[],
  191.     Shortword delout_hi[],Shortword delout_lo[],
  192.     Shortword frame)
  193. {
  194.   Shortword section;
  195.   /* Remove DC from input speech */
  196.   v_equ(sigout,sigin,frame);
  197.   for (section=0; section<DC_ORD/2; section++) {
  198.  /*    for (i=0; i<frame; i++){           */
  199. /*         printf("%dn",sigout[i]);    */
  200. /*                                    } */                          
  201.     iir_2nd_d(sigout,&dc_den[section*3],&dc_num[section*3],sigout,
  202.       &delin[section*2],&delout_hi[section*2],&delout_lo[section*2],
  203.       frame);
  204.   /*  for (i=0; i<frame; i++){           */
  205. /*         printf("%dn",sigout[i]);     */
  206. /*                                    }  */                          
  207.   }
  208. }
  209. /*
  210.     Name: gain_ana.c
  211.     Description: analyze gain level for input signal
  212.     Inputs: 
  213.       sigin[] - input signal
  214.       pitch - pitch value (for pitch synchronous window)
  215.       minlength - minimum window length
  216.       maxlength - maximum window length
  217.     Outputs: 
  218.     Returns: log gain in dB
  219.     See_Also:
  220.     Copyright (c) 1997 by Texas Instruments, Inc.  All rights reserved.
  221.     Q values
  222.     --------
  223.     pitch - Q7
  224.     sigin (speech) - Q0
  225. */
  226. #define CONSTANT_SCALE 0
  227. #define MINGAIN        0
  228. #define LOG10OF2X2     1233         /* 2*log10(2) in Q11 */
  229. Shortword gain_ana(Shortword sigin[], Shortword pitch, 
  230.    Shortword minlength, Shortword maxlength)
  231. {
  232.     Shortword length;    /* Q0 */
  233.     Shortword flength;   /* Q6 */
  234.     Shortword gain;      /* Q8 */
  235.     Shortword pitch_Q6;  /* Q6 */
  236.     Shortword scale;
  237.     Shortword tmp_minlength;
  238.     Shortword sigbegin;
  239.     Shortword *temp_buf, *tmp_sig;
  240.     Shortword S_temp1, S_temp2;
  241.     Longword L_temp;
  242. Longword L_temp1,L_temp2;
  243.     
  244.     /* initialize scaled pitch and minlength */
  245.  /*    pitch_Q6 = shr(pitch,1);       Q7->Q6     data_move();mark del */
  246. /*                                                                          */
  247. /*     tmp_minlength = shl(minlength,6);   // data_move();mark del          */
  248.     
  249. L_temp1 = _shr2((Longword)pitch,1); 
  250.     pitch_Q6 = (Shortword) (0x0000ffffL & L_temp1); 
  251. tmp_minlength = shl_a(minlength,6);
  252.     /* Find shortest pitch multiple window length (floating point) */
  253.     flength = pitch_Q6; //   data_move();mark del
  254.     while (flength < tmp_minlength) {
  255.       /* increment complexity for while statement */
  256. //      compare_nonzero();mark del
  257.       /* flength = add(flength,pitch_Q6);   //   data_move();mark del */
  258.    L_temp1 = _sadd2((Longword)flength,(Longword)pitch_Q6);
  259.        flength = (Shortword) (0x0000ffffL & L_temp1);
  260.     }
  261.     /* Convert window length to integer and check against maximum */
  262.    /*  length = shr(add(flength, (Shortword)X05_Q6), 6);  //   data_move();mark del */
  263.        L_temp1 = _sadd2((Longword)flength, (Longword)X05_Q6);
  264.    L_temp1 = _shr2(L_temp1,6);
  265.    length = (Shortword) (0x0000ffffL & L_temp1);
  266.     /* increment complexity for if statement */
  267. //    compare_nonzero();mark del
  268.     if (length > maxlength) {
  269.       /* divide by 2 */
  270.       /* length = shr(length,1);  //  data_move();mark del */
  271.         L_temp1 = _shr2((Longword)length,1);
  272.     length = (Shortword) (0x0000ffffL & L_temp1);
  273.     }
  274.     
  275.     /* Calculate RMS gain in dB */
  276.     /*gain = 10.0*log10(0.01+(v_magsq(&sigin[-(length/2)],length)/length));*/
  277.     
  278.     /* use this adaptive scaling if more precision needed at low 
  279.        levels.  Seemed like it wasn't worth the mips */
  280.     /* sigbegin = negate(shr(length,1)); */
  281.   L_temp2 = _shr2((Longword)length,1);
  282.   sigbegin = (Shortword) (0x0000ffffL & L_temp2);
  283.   sigbegin = negate(sigbegin);
  284.     /* Right shift input signal and put in temp buffer */
  285.     MEM_ALLOC(MALLOC,temp_buf,length,Shortword);
  286. #if(CONSTANT_SCALE)
  287.     scale=3;
  288. #else
  289.     scale = 3;
  290.     v_equ_shr(temp_buf,&sigin[sigbegin],scale,length);
  291.     L_temp = L_v_magsq(temp_buf,length,0,1);
  292. //    compare_zero();mark del
  293.     if (L_temp) {
  294.      /*  S_temp1 = norm_l(L_temp); */
  295.   L_temp1 = _norm(L_temp);
  296.   if (L_temp == 0){
  297.   L_temp1 = (Longword)0;
  298.   }
  299.   S_temp1 = (Shortword) (0x0000ffffL & L_temp1);
  300.       scale = sub(scale,shr_a(S_temp1,1));
  301.       if (scale < 0)
  302. scale = 0;
  303.     }
  304.     else
  305.       scale = 0;
  306. #endif
  307.     if (scale)
  308.       v_equ_shr(temp_buf,&sigin[sigbegin],scale,length);
  309.     else
  310.       v_equ(temp_buf,&sigin[sigbegin],length);
  311.     tmp_sig = temp_buf - sigbegin;
  312.     /* increment complexity for if statement */
  313. //    compare_zero();mark del
  314.     if (scale) {
  315.       L_temp = L_v_magsq(&tmp_sig[sigbegin],length,0,0);
  316.       S_temp1 = L_log10_fxp(L_temp,0);
  317.       S_temp2 = L_log10_fxp(L_deposit_l(length),0); 
  318.       S_temp1 = sub(S_temp1,S_temp2);
  319.       /* shift right to counter-act for the shift in L_mult */
  320.      /*  S_temp2 = extract_l(L_shr(L_mult(scale,LOG10OF2X2),1)); */
  321. /*       S_temp1 = add(S_temp1,S_temp2);                         */
  322. /*      S_temp1 = mult(TEN_Q11,S_temp1);                        */
  323. /*       gain = shl(S_temp1,1);  //  data_move();mark del        */
  324.       L_temp2 = _sshvr(_smpy(scale,LOG10OF2X2),1);
  325.       S_temp2 = (Shortword) (0x0000ffffL & L_temp2);
  326.   L_temp1 = _sadd2((Longword)S_temp1,(Longword)S_temp2);
  327.       S_temp1 = (Shortword) (0x0000ffffL & L_temp1);
  328.   L_temp2 = _smpy(TEN_Q11,S_temp1);
  329.       S_temp1 = (Shortword) (0x0000ffffL & (L_temp2 >> 16));
  330.       gain = shl_a(S_temp1,1);
  331.     }
  332.     else {
  333.       L_temp = L_v_magsq(&tmp_sig[sigbegin],length,0,0);
  334.       /* Add one to avoid log of a zero value */
  335.       if (L_temp == 0)
  336. S_temp1 = N2_Q11;
  337.       else
  338. S_temp1 = L_log10_fxp(L_temp,0);
  339.       S_temp2 = L_log10_fxp(L_deposit_l(length),0);
  340.       S_temp1 = sub(S_temp1,S_temp2);
  341.       /* S_temp1 = mult(TEN_Q11,S_temp1); */
  342.   L_temp1 = _smpy(TEN_Q11,S_temp1);
  343.       S_temp1 = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
  344.       gain = shl_a(S_temp1,1);  //  data_move();mark del
  345.     }
  346.     /* increment complexity for if statement */
  347. //    compare_nonzero();mark del
  348.     if (gain < MINGAIN) {
  349.       gain = MINGAIN;   // data_move();mark del
  350.     }
  351.     MEM_FREE(FREE,temp_buf);
  352.     return(gain);
  353. } /* gain_ana */
  354. /*
  355.     Name: lin_int_bnd.c
  356.     Description: Linear interpolation within bounds
  357.     Inputs:
  358.       x - input X value
  359.       xmin - minimum X value
  360.       xmax - maximum X value
  361.       ymin - minimum Y value
  362.       ymax - maximum Y value
  363.     Returns: y - interpolated and bounded y value
  364.     Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.
  365.     Q values:
  366.     x,xmin,xmax - Q8
  367.     y,ymin,ymax - Q15
  368. */
  369. Shortword lin_int_bnd(Shortword x,Shortword xmin,Shortword xmax,
  370.       Shortword ymin,Shortword ymax)
  371. {
  372.     Shortword y;
  373.     Shortword temp1,temp2;
  374. Longword L_temp,L_y;
  375.     if (x <= xmin)
  376.       y = ymin;
  377.     else if (x >= xmax)
  378.       y = ymax;
  379.     else {
  380.       /* y = ymin + (x-xmin)*(ymax-ymin)/(xmax-xmin); */
  381.       temp1 = sub(x,xmin);
  382.       temp2 = sub(ymax,ymin);
  383.    /*    temp1 = mult(temp1,temp2);      temp1 in Q8  */
  384.       L_temp = _smpy(temp1,temp2);
  385.   temp1 = (Shortword) (0x0000ffffL & (L_temp >> 16));
  386.       temp2 = sub(xmax,xmin);
  387.       /* temp1 always smaller than temp2 */
  388.       temp1 = divide_s(temp1,temp2);    /* temp1 in Q15 */
  389.      /*  y = add(ymin,temp1); */
  390.   L_y = _sadd2((Longword)ymin,(Longword)temp1);
  391.   y = (Shortword) (0x0000ffffL & L_y);
  392.     }
  393.     return(y);
  394. }
  395. /*
  396.     Name: noise_est.c
  397.     Description: Estimate long-term noise floor
  398.     Inputs:
  399.       gain - input gain (in dB)
  400.       noise_gain - current noise gain estimate
  401.       up - maximum up stepsize
  402.       down - maximum down stepsize
  403.       min - minimum allowed gain
  404.       max - maximum allowed gain
  405.     Outputs:
  406.       noise_gain - updated noise gain estimate
  407.     Returns: void
  408.     Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.
  409.     Q values:
  410.     gain - Q8
  411.     *noise_gain - Q8
  412.     up - Q19
  413.     down - Q17
  414.     min - Q8
  415.     max - Q8
  416. */
  417. void noise_est(Shortword gain,Shortword *noise_gain,Shortword up,
  418.        Shortword down,Shortword min,Shortword max)
  419. {
  420.     Shortword temp1,temp2;
  421.     Longword L_noise_gain,L_temp;
  422. Longword L_Prod;
  423.     /* Update noise_gain */
  424.     /* temp1 = add(*noise_gain,up);
  425.        temp2 = add(*noise_gain,down);  */
  426.    /*  L_noise_gain = L_deposit_h(*noise_gain);     L_noise_gain in Q24  */
  427. /*     L_temp = L_shl(L_deposit_l(up),5);                                    */
  428. /*     L_temp = L_add(L_noise_gain,L_temp);                                  */
  429. /*     temp1 = round(L_temp);                                                */
  430.       L_noise_gain = (Longword) (*noise_gain) << 16; 
  431.       L_temp = _sshl((Longword)up,5);
  432.       L_temp = _sadd(L_noise_gain,L_temp);
  433.       L_Prod = _sadd(L_temp, 0x00008000L); /* round MSP */
  434.       temp1 = (Shortword)(0x0000ffffL & (L_Prod >> 16));
  435.     /* L_temp = L_shl(L_deposit_l(down),7); */
  436. /*     L_temp = L_add(L_noise_gain,L_temp); */
  437. /*     temp2 = round(L_temp);               */
  438.       L_temp = _sshl((Longword)down,7);
  439.   L_temp = _sadd(L_noise_gain,L_temp);
  440.   L_Prod = _sadd(L_temp, 0x00008000L); /* round MSP */
  441.       temp2 = (Shortword)(0x0000ffffL & (L_Prod >> 16));
  442.       
  443. //    compare_nonzero();mark del
  444.     if (gain > temp1)
  445.       *noise_gain = temp1;
  446.     else if (gain < temp2)
  447.       *noise_gain = temp2;
  448.     else
  449.       *noise_gain = gain;
  450.     /* Constrain total range of noise_gain */
  451. //    compare_nonzero();mark del
  452.     if (*noise_gain < min)
  453.       *noise_gain = min;
  454. //    compare_nonzero();mark del
  455.     if (*noise_gain > max)
  456.       *noise_gain = max;
  457. }
  458. /*
  459.     Name: noise_sup.c
  460.     Description: Perform noise suppression on speech gain
  461.     Inputs: (all in dB)
  462.       gain - input gain (in dB)
  463.       noise_gain - current noise gain estimate (in dB)
  464.       max_noise - maximum allowed noise gain 
  465.       max_atten - maximum allowed attenuation
  466.       nfact - noise floor boost
  467.     Outputs:
  468.       gain - updated gain 
  469.     Returns: void
  470.     Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.
  471.     Q values:
  472.     *gain - Q8
  473.     noise_gain - Q8
  474.     max_noise - Q8
  475.     max_atten - Q8
  476.     nfact - Q8
  477. */
  478. void noise_sup(Shortword *gain,Shortword noise_gain,Shortword max_noise,
  479.        Shortword max_atten,Shortword nfact)
  480. {
  481.     Shortword gain_lev,suppress;
  482.     Shortword temp;
  483.     Longword L_temp;
  484. Longword L_temp1;
  485. Shortword temp1;
  486.     /* Reduce effect for louder background noise */
  487.     if (noise_gain > max_noise)
  488.       noise_gain = max_noise;
  489.     /* Calculate suppression factor */
  490.     /* gain_lev = sub(*gain,add(noise_gain,nfact)); */
  491.    L_temp1 = _sadd2((Longword)noise_gain,(Longword)nfact);
  492.    temp1 = (Shortword) (0x0000ffffL & L_temp1);
  493.        gain_lev = sub(*gain,temp1);
  494. //    compare_nonzero();mark del
  495.     if (gain_lev > X0001_Q8) {
  496.         /* suppress = -10.0*log10(1.0 - pow(10.0,-0.1*gain_lev)); */
  497.     /*     L_temp = L_mult((Shortword)M01_Q15,gain_lev);      L_temp in Q24 */ 
  498. /*  temp = extract_h(L_shl(L_temp,4));      temp in Q12 */    
  499.        L_temp = _smpy((Shortword)M01_Q15,gain_lev);     
  500.        L_temp = _sshl(L_temp,4); 
  501.        temp = (Shortword) (0x0000ffffL & (L_temp >> 16));            
  502. temp = pow10_fxp(temp,14);
  503. temp = sub(ONE_Q14,temp);
  504. /* suppress = mult(M10_Q11,log10_fxp(temp,14));   log returns Q12  */
  505. L_temp1 = _smpy(M10_Q11,log10_fxp(temp,14));
  506.     suppress = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
  507. // compare_nonzero();mark del
  508. if (suppress > max_atten)
  509.   suppress = max_atten;
  510.     }
  511.     else
  512.       suppress = max_atten;
  513.     /* Apply suppression to input gain */
  514.     *gain = sub(*gain,suppress);
  515. } /* noise_sup */
  516. /*
  517.     Name: q_bpvc.c, q_bpvc_dec.c
  518.     Description: Quantize/decode bandpass voicing
  519.     Inputs:
  520.       bpvc, bpvc_index
  521.       bpthresh - threshold
  522.       NUM_BANDS - number of bands
  523.     Outputs: 
  524.       bpvc, bpvc_index
  525.     Returns: uv_flag - flag if unvoiced
  526.     Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.
  527.     Q values:
  528.     *bpvc - Q14
  529.     bpthresh - Q14
  530. */
  531. /* Compile constants */
  532. #define INVALID_BPVC 0001
  533. Shortword q_bpvc(Shortword *bpvc,Shortword *bpvc_index,Shortword bpthresh,
  534.  Shortword NUM_BANDS)
  535. {
  536.     Shortword j, uv_flag;
  537.     uv_flag = 1;   //  data_move();mark del
  538.     if (bpvc[0] > bpthresh) {
  539. /* Voiced: pack bandpass voicing */
  540. uv_flag = 0;  //   data_move();mark del
  541. *bpvc_index = 0;   //  data_move();mark del
  542. bpvc[0] = ONE_Q14;  //   data_move();mark del
  543. for (j = 1; j < NUM_BANDS; j++) {
  544.     *bpvc_index = shl(*bpvc_index,1);    /* left shift one bit */
  545.     if (bpvc[j] > bpthresh) {
  546. bpvc[j] = ONE_Q14;   //  data_move();mark del
  547. *bpvc_index |= 1;   //  logic();mark del
  548.     }
  549.     else {
  550. bpvc[j] = 0;   //  data_move();mark del
  551. *bpvc_index |= 0;   //  logic();mark del
  552.     }
  553. }
  554. /* Don't use invalid code (only top band voiced) */
  555. if (*bpvc_index == INVALID_BPVC) {
  556.     bpvc[(NUM_BANDS-1)] = 0;
  557.     *bpvc_index = 0;
  558. }
  559.     }
  560.     else {
  561. /* Unvoiced: force all bands unvoiced */
  562. *bpvc_index = 0;
  563. for (j = 0; j < NUM_BANDS; j++)
  564.     bpvc[j] = 0;
  565.     }
  566.     return(uv_flag);
  567. } /* q_bpvc */
  568. void q_bpvc_dec(Shortword *bpvc,Shortword *bpvc_index,Shortword uv_flag,
  569. Shortword NUM_BANDS)
  570. {
  571.     Shortword j;
  572.     if (uv_flag) {
  573. /* Unvoiced: set all bpvc to 0 */
  574. *bpvc_index = 0;
  575. bpvc[0] = 0;
  576.     }
  577.     
  578.     else {
  579. /* Voiced: set bpvc[0] to 1.0 */
  580. bpvc[0] = ONE_Q14;
  581.     }
  582.     
  583.     if (*bpvc_index == INVALID_BPVC) {
  584. /* Invalid code received: set higher band voicing to zero */
  585. *bpvc_index = 0;
  586.     }
  587.     /* Decode remaining bands */
  588.     for (j = NUM_BANDS-1; j > 0; j--) {
  589. //        compare_nonzero();mark del
  590. // logic();mark del
  591. if ((*bpvc_index & 1) == 1)
  592.     bpvc[j] = ONE_Q14;
  593. else
  594.     bpvc[j] = 0;
  595. *bpvc_index = shr_a(*bpvc_index,1);
  596.     }
  597. } /* q_bpvc_dec */
  598. /*
  599.     Name: q_gain.c, q_gain_dec.c
  600.     Description: Quantize/decode two gain terms using quasi-differential coding
  601.     Inputs:
  602.       gain[2],gain_index[2]
  603.       GN_QLO,GN_QUP,GN_QLEV for second gain term
  604.     Outputs: 
  605.       gain[2],gain_index[2]
  606.     Returns: void
  607.     Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.
  608.     Q values:
  609.     *gain - Q8
  610.     GN_QLO - Q8
  611.     GN_QUP - Q8
  612.     GN_QLEV_Q - Q10
  613. */
  614. /* Compile constants */
  615. #define GAIN_INT_DB_Q8 1280    /* (5*(1<<8)) */
  616. void q_gain(Shortword *gain,Shortword *gain_index,Shortword GN_QLO,
  617.     Shortword GN_QUP,Shortword GN_QLEV,Shortword GN_QLEV_Q,
  618.     Shortword double_flag,Shortword scale)
  619. {
  620.     static Shortword prev_gain = 0;
  621.     Shortword temp,temp2;
  622.     /* Quantize second gain term with uniform quantizer */
  623.     quant_u(&gain[1],&gain_index[1],GN_QLO,GN_QUP,GN_QLEV,GN_QLEV_Q,
  624.     double_flag,scale);
  625.     
  626.     /* Check for intermediate gain interpolation */
  627.     if (gain[0] < GN_QLO) {
  628.       gain[0] = GN_QLO;  //   data_move();mark del
  629.     }
  630.     if (gain[0] > GN_QUP) {
  631.       gain[0] = GN_QUP;   //  data_move();mark del
  632.     }
  633.     /* if (fabs(gain[1] - prev_gain) < GAIN_INT_DB && 
  634.          fabs(gain[0] - 0.5*(gain[1]+prev_gain)) < 3.0) */
  635.     temp = add(shr(gain[1],1),shr(prev_gain,1));
  636.     if (abs_s(sub(gain[1],prev_gain)) < GAIN_INT_DB_Q8 &&
  637. abs_s(sub(gain[0],temp)) < THREE_Q8) {
  638. /* interpolate and set special code */
  639.         /* gain[0] = 0.5*(gain[1]+prev_gain); */
  640.         gain[0] = temp;
  641. gain_index[0] = 0;
  642.     }
  643.     else {
  644. /* Code intermediate gain with 7-levels */
  645. if (prev_gain < gain[1]) {
  646.     temp = prev_gain;  //   data_move();mark del
  647.     temp2 = gain[1];    // data_move();mark del
  648. }
  649. else {
  650.     temp = gain[1];    // data_move();mark del
  651.     temp2 = prev_gain;    // data_move();mark del
  652. }
  653. temp = sub(temp,SIX_Q8);
  654. temp2 = add(temp2,SIX_Q8);
  655. if (temp < GN_QLO) {
  656.   temp = GN_QLO;   //  data_move();mark del
  657. }
  658. if (temp2 > GN_QUP) {
  659.   temp2 = GN_QUP;   //  data_move();mark del
  660. }
  661. quant_u(&gain[0],&gain_index[0],temp,temp2,6,SIX_Q12,0,3);
  662. /* Skip all-zero code */
  663. gain_index[0] = add(gain_index[0],1);
  664.     }
  665.     /* Update previous gain for next time */
  666.     prev_gain = gain[1];   //  data_move();mark del
  667.     
  668. } /* q_gain */
  669. void q_gain_dec(Shortword *gain,Shortword *gain_index,Shortword GN_QLO,
  670. Shortword GN_QUP,Shortword GN_QLEV_Q,Shortword scale)
  671. {
  672.     static Shortword prev_gain = 0;
  673.     static Shortword prev_gain_err = 0;
  674.     Shortword temp,temp2;
  675. Longword L_temp,L_temp1;
  676.     /* Decode second gain term */
  677.     quant_u_dec(gain_index[1],&gain[1],GN_QLO,GN_QUP,GN_QLEV_Q,scale);
  678.     
  679.     if (gain_index[0] == 0) {
  680. /* interpolation bit code for intermediate gain */
  681.         temp = sub(gain[1],prev_gain);
  682. /* temp = abs_s(temp); */
  683.       L_temp = _abs2((Longword)temp);
  684.   temp = (Shortword) (0x0000ffffL & L_temp);
  685. // compare_nonzero();mark del
  686. if (temp > GAIN_INT_DB_Q8) {
  687.     /* Invalid received data (bit error) */
  688.     if (prev_gain_err == 0) {
  689. /* First time: don't allow gain excursion */
  690. gain[1] = prev_gain;
  691.     }
  692.     prev_gain_err = 1;
  693. }
  694. else 
  695.   prev_gain_err = 0;
  696. /* Use interpolated gain value */
  697. /* gain[0] = 0.5*(gain[1]+prev_gain); */
  698. /* gain[0] = add(shr(gain[1],1),shr(prev_gain,1)); */
  699.    L_temp = _shr2((Longword)(gain[1]),1);
  700.    L_temp1 = _shr2((Longword)prev_gain,1);
  701.    L_temp = _sadd2(L_temp,L_temp1);
  702.    gain[0] = (Shortword) (0x0000ffffL & L_temp);
  703.     }
  704.     else {
  705. /* Decode 7-bit quantizer for first gain term */
  706. prev_gain_err = 0;
  707. gain_index[0] = sub(gain_index[0],1);
  708. // compare_nonzero();mark del
  709. if (prev_gain < gain[1]) {
  710.     temp = prev_gain;
  711.     temp2 = gain[1];
  712. }
  713. else {
  714.     temp = gain[1];
  715.     temp2 = prev_gain;
  716. }
  717. temp = sub(temp,SIX_Q8);
  718. /* temp2 = add(temp2,SIX_Q8); */
  719. L_temp = _sadd2((Longword)temp2,(Longword)SIX_Q8);
  720. temp2 = (Shortword) (0x0000ffffL & L_temp);
  721. // compare_nonzero();mark del
  722. if (temp < GN_QLO)
  723.   temp = GN_QLO;
  724. // compare_nonzero();mark del
  725. if (temp2 > GN_QUP)
  726.   temp2 = GN_QUP;
  727. quant_u_dec(gain_index[0],&gain[0],temp,temp2,SIX_Q12,3);
  728.     }
  729.     /* Update previous gain for next time */
  730.     prev_gain = gain[1];  //  data_move();mark del
  731.     
  732. } /* q_gain_dec */
  733. /*
  734.     Name: scale_adj.c
  735.     Description: Adjust scaling of output speech signal.
  736.     Inputs:
  737.       speech - speech signal
  738.       gain - desired RMS gain (log gain)
  739.       prev_scale - previous scale factor
  740.       length - number of samples in signal
  741.       SCALEOVER - number of points to interpolate scale factor
  742.     Warning: SCALEOVER is assumed to be less than length.
  743.     Outputs: 
  744.       speech - scaled speech signal
  745.       prev_scale - updated previous scale factor
  746.     Returns: void
  747.     Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.
  748.     Q values:
  749.     *speech - Q0
  750.     gain - Q12
  751.     *prev_scale - Q13
  752. */
  753. void scale_adj(Shortword *speech, Shortword gain, Shortword *prev_scale, 
  754.        Shortword length, Shortword SCALEOVER, 
  755.        Shortword INV_SCALEOVER_Q18)
  756. {
  757.     Shortword i;
  758.     Shortword scale;
  759.     Shortword shift,log_magsq,log_length;
  760.     Shortword temp;
  761.     Shortword *tempbuf;
  762.     Longword L_magsq,L_length,interp1,interp2;
  763.     Longword L_temp;
  764. Longword L_temp1;
  765.     /* Calculate desired scaling factor to match gain level */
  766.     /* scale = gain / (sqrt(v_magsq(&speech[0],length) / length) + .01); */
  767.     /* find normalization factor for buffer */
  768.     MEM_ALLOC(MALLOC,tempbuf,length,Shortword);
  769.     shift = 4;
  770.     v_equ_shr(tempbuf,speech,shift,length);
  771.     L_magsq = L_v_magsq(tempbuf,length,0,1);
  772. //    compare_zero();mark del
  773.     if (L_magsq) {
  774.       /* normalize with 1 bit of headroom */
  775.       /* temp = norm_l(L_magsq); */
  776.        L_temp1 = _norm(L_magsq);
  777.    if (L_magsq == 0){
  778.      L_temp1 = (Longword)0;
  779.    }
  780.    temp = (Shortword) (0x0000ffffL & L_temp1);
  781.       temp = sub(temp,1);
  782.       shift = sub(shift,shr_a(temp,1));
  783.     }
  784.     else
  785.       shift = 0;
  786.     v_equ_shr(tempbuf,speech,shift,length);
  787.     /* exp = log(2^shift) */
  788.     shift = shl_a(shift,1);     /* total compensation = shift*2 */
  789.     temp = shl(ONE_Q8,shift);
  790.     shift = log10_fxp(temp,8);    /* shift in Q12 */
  791.     L_magsq = L_v_magsq(tempbuf,length,0,0);
  792.    /*  L_magsq = L_add(L_magsq,1);      ensure L_magsq is not zero  */
  793.     L_magsq = _sadd(L_magsq,1);
  794.     log_magsq = L_log10_fxp(L_magsq,0);      /* log_magsq in Q11 */
  795.     /* L_magsq = log_magsq in Q12 */
  796.    /*  L_magsq = L_deposit_l(log_magsq); */
  797. /*     L_magsq = L_shl(L_magsq,1);       */
  798.      L_magsq = (Longword)log_magsq;
  799.     L_magsq = _sshl(L_magsq,1);
  800.     /* compensate for normalization */
  801.     /* L_magsq = log magnitude/2 in Q13 */
  802.    /*  L_temp = L_deposit_l(shift);     */
  803. /*     L_magsq = L_add(L_magsq,L_temp); */
  804.     L_temp = (Longword)shift;
  805.     L_magsq = _sadd(L_magsq,L_temp);
  806.     temp = shl_a(length,7);
  807.     log_length = log10_fxp(temp,7);      /* log_length in Q12 */
  808.     /* L_length = log_length/2 in Q13 */
  809.    /*  L_length = L_deposit_l(log_length); */
  810.     L_length = (Longword)log_length;
  811.   /*   L_temp = L_deposit_l(gain);                        */
  812. /*     L_temp = L_shl(L_temp,1);       L_temp in Q13  */
  813. /*     L_temp = L_sub(L_temp,L_magsq);                    */
  814. /*     L_temp = L_add(L_temp,L_length);                   */
  815. /*     L_temp = L_shr(L_temp,1);       Q13 -> Q12     */
  816. /*     temp = extract_l(L_temp);      temp in Q12     */
  817.     L_temp = (Longword)gain;
  818.     L_temp = _sshl(L_temp,1);      /* L_temp in Q13 */
  819.     L_temp = _ssub(L_temp,L_magsq);
  820.     L_temp = _sadd(L_temp,L_length);
  821.     L_temp = _sshvr(L_temp,1);      /* Q13 -> Q12 */
  822.     temp = (Shortword)(0x0000ffffL & L_temp);     /* temp in Q12 */
  823.     scale = pow10_fxp(temp,13);
  824.     /* interpolate scale factors for first SCALEOVER points */
  825.     for (i = 1; i < SCALEOVER; i++) {
  826.       /* speech[i-1] *= ((scale*i + *prev_scale*(SCALEOVER-i))
  827.       * (1.0/SCALEOVER) ); */
  828.       temp = sub(SCALEOVER,i);
  829.       temp = shl_a(temp,11);
  830.      /*  L_temp = L_mult(temp,INV_SCALEOVER_Q18);   L_temp in Q30 */  
  831. /*       L_temp = L_shl(L_temp,1);                  L_temp in Q31 */  
  832. /*       temp = extract_h(L_temp);                  temp in Q15 */    
  833. /*       interp1 = L_mult(*prev_scale,temp);        interp1 in Q29 */ 
  834.       L_temp = _smpy(temp,INV_SCALEOVER_Q18);  /* L_temp in Q30 */
  835.       L_temp = _sshl(L_temp,1);                 /* L_temp in Q31 */
  836.       temp = (Shortword) (0x0000ffffL & (L_temp >> 16));                 /* temp in Q15 */
  837.       interp1 = _smpy(*prev_scale,temp);       /* interp1 in Q29 */
  838.       temp = shl_a(i,11);
  839.     /*   L_temp = L_mult(temp,INV_SCALEOVER_Q18);   L_temp in Q30 */  
  840. /*       L_temp = L_shl(L_temp,1);                  L_temp in Q31 */  
  841. /*       temp = extract_h(L_temp);                  temp in Q15 */    
  842. /*       interp2 = L_mult(scale,temp);              interp2 in Q29 */ 
  843. /*       L_temp = L_add(interp1,interp2);                               */
  844. /*       interp1 = extract_h(L_temp);               interp1 in Q13 */ 
  845.        L_temp = _smpy(temp,INV_SCALEOVER_Q18);  /* L_temp in Q30 */
  846.       L_temp = _sshl(L_temp,1);                 /* L_temp in Q31 */
  847.       temp = (Shortword) (0x0000ffffL & (L_temp >> 16));                 /* temp in Q15 */
  848.       interp2 = _smpy(scale,temp);             /* interp2 in Q29 */
  849.       L_temp = _sadd(interp1,interp2);
  850.       interp1 = (Shortword) (0x0000ffffL & (L_temp >> 16));              /* interp1 in Q13 */
  851.       /* L_temp = L_mult(speech[i-1],(Shortword)interp1); */
  852. /*       L_temp = L_shl(L_temp,2);                        */
  853. /*       speech[i-1] = extract_h(L_temp);                 */
  854.      L_temp = _smpy(speech[i-1],(Shortword)interp1);
  855.      L_temp = _sshl(L_temp,2);
  856.      speech[i-1] = (Shortword) (0x0000ffffL & (L_temp >> 16));
  857.     }
  858.     
  859.     /* Scale rest of signal */
  860.     v_scale_shl(&speech[SCALEOVER-1],scale,(Shortword)(length-SCALEOVER+1),2);
  861.     /* Update previous scale factor for next call */
  862.     *prev_scale = scale;   //   data_move();mark del
  863.     MEM_FREE(FREE,tempbuf);
  864. } /* scale_adj */