melp_sub.c
上传用户:cxx_68
上传日期:2021-02-21
资源大小:161k
文件大小:26k
源码类别:

语音压缩

开发平台:

Visual C++

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