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

语音压缩

开发平台:

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.   dsp_sub.c: general subroutines.
  25. */
  26. /*  compiler include files  */
  27. #include        <stdio.h>
  28. #include        <stdlib.h>
  29. #include        <math.h>
  30. #include "spbstd.h"
  31. #include "mathhalf.h"
  32. #include "mathdp31.h"
  33. #include "wmops.h"
  34. #include "mat.h"
  35. #include "math_lib.h"
  36. #include "dsp_sub.h"
  37. #include "constant.h"
  38. #define PRINT 1 
  39. /* */
  40. /* Subroutine envelope: calculate time envelope of signal. */
  41. /*      Note: the delay history requires one previous sample    */
  42. /*      of the input signal and two previous output samples.    */
  43. /*      Output is scaled down by 4 bits from input signal       */
  44. /* */
  45. #define C2_Q14 -15415    /* (-0.9409*(1<<14)) */
  46. #define C1_Q14 31565     /* (1.9266*(1<<14)) */
  47. void envelope(Shortword input[], Shortword prev_in, Shortword output[], 
  48.       Shortword npts)
  49. {
  50.     Shortword i;
  51.     Shortword curr_abs, prev_abs;
  52.     Longword L_temp;
  53.     prev_abs = abs_s(prev_in);
  54.     for (i = 0; i < npts; i++) {
  55.         curr_abs = abs_s(input[i]);
  56. /* output[i] = curr_abs - prev_abs + C2*output[i-2] + C1*output[i-1] */
  57. L_temp = L_shr(L_deposit_h(sub(curr_abs,prev_abs)),5);
  58. L_temp = L_mac(L_temp,(Shortword)C1_Q14,output[i-1]);
  59. L_temp = L_mac(L_temp,(Shortword)C2_Q14,output[i-2]);
  60. L_temp = L_shl(L_temp,1);
  61. output[i] = round(L_temp);
  62.         prev_abs = curr_abs;
  63.     }
  64. }
  65. /* */
  66. /*  Subroutine fill: fill an input array with a value. */
  67. /* */
  68. void fill(Shortword output[], Shortword fillval, Shortword npts)
  69. {
  70.   Shortword i;
  71.   for (i = 0; i < npts; i++ )
  72.     output[i] = fillval;
  73. }
  74. /* */
  75. /* Subroutine interp_array: interpolate array              */
  76. /*                                                              */
  77. /*  Q values:
  78.     ifact - Q15
  79. */
  80. void interp_array(Shortword prev[],Shortword curr[],Shortword out[],
  81.   Shortword ifact,Shortword size)
  82. {
  83.     Shortword i;
  84.     Shortword ifact2;
  85.     Shortword temp1,temp2;
  86.     if (ifact == 0) {
  87.       for (i = 0; i < size; i++) {
  88. out[i] = prev[i];     data_move();
  89.       }
  90.     }
  91.     else if (ifact == ONE_Q15) {
  92.       for (i = 0; i < size; i++) {
  93. out[i] = curr[i];     data_move();
  94.       }
  95.     }
  96.     else {
  97.       ifact2 = sub(ONE_Q15,ifact);
  98.       for (i = 0; i < size; i++) {
  99. temp1 = mult(ifact,curr[i]);
  100. temp2 = mult(ifact2,prev[i]);
  101. out[i] = add(temp1,temp2);
  102.       }
  103.     }
  104. }
  105. /* */
  106. /* Subroutine median: calculate median value               */
  107. /* */
  108. #define MAXSORT 5
  109. Shortword median(Shortword input[], Shortword npts)
  110. {
  111.     Shortword i,j,loc;
  112.     Shortword insert_val;
  113.     Shortword sorted[MAXSORT];
  114.     /* sort data in temporary array */
  115. #ifdef PRINT
  116.     if (npts > MAXSORT) {
  117. printf("ERROR: median size too large.n");
  118. exit(1);
  119.     }
  120. #endif
  121.     v_equ(sorted,input,npts);
  122.     for (i = 1; i < npts; i++) {
  123. /* for each data point */
  124. for (j = 0; j < i; j++) {
  125.     /* find location in current sorted list */
  126.     compare_nonzero();
  127.     if (sorted[i] < sorted[j])
  128.       break;
  129. }
  130. /* insert new value */
  131. loc = j;      data_move();
  132. insert_val = sorted[i];     data_move();
  133. for (j = i; j > loc; j--) {
  134.   sorted[j] = sorted[j-1];     data_move();
  135. }
  136. sorted[loc] = insert_val;     data_move();
  137.     }
  138.     return(sorted[npts/2]);
  139. }
  140. #undef MAXSORT
  141. /* */
  142. /* Subroutine PACK_CODE: Pack bit code into channel. */
  143. /* */
  144. void pack_code(Shortword code,UShortword **p_ch_beg,Shortword *p_ch_bit, 
  145.        Shortword numbits,Shortword wsize)
  146. {
  147.     Shortword i,ch_bit;
  148.     UShortword *ch_word;
  149. ch_bit = *p_ch_bit;
  150. ch_word = *p_ch_beg;
  151. for (i = 0; i < numbits; i++) {
  152. /* Mask in bit from code to channel word */
  153. if (ch_bit == 0)
  154.   *ch_word = (UShortword)(shr((Shortword)(code & (shl(1,i))),i));
  155. else
  156.   *ch_word |= (UShortword)(shl((shr((Shortword)(code & (shl(1,i))),i)),ch_bit));
  157. /* Check for full channel word */
  158. ch_bit = add(ch_bit,1);
  159. if (ch_bit >= wsize) {
  160. ch_bit = 0;
  161. (*p_ch_beg)++ ;
  162. ch_word++ ;
  163. }
  164. }
  165. /* Save updated bit counter */
  166. *p_ch_bit = ch_bit;
  167. }
  168. /* */
  169. /* Subroutine peakiness: estimate peakiness of input       */
  170. /*      signal using ratio of L2 to L1 norms.                   */
  171. /* */
  172. /* Q_values
  173.    --------
  174.    peak_fact - Q12
  175.    input - Q0
  176.    
  177. */
  178. /* Upper limit of (magsq/sum_abs) to prevent saturation of peak_fact */
  179. #define LIMIT_PEAKI    20723
  180. Shortword peakiness(Shortword input[], Shortword npts)
  181. {
  182.     Shortword i;
  183.     Shortword peak_fact;
  184.     Longword  sum_abs;
  185.     Shortword scale;
  186.     Shortword temp1, temp2;
  187.     Longword L_temp;
  188.     Shortword *temp_buf;
  189.     
  190.     MEM_ALLOC(MALLOC,temp_buf,npts,Shortword);
  191.     scale = 4;
  192.     v_equ_shr(temp_buf,input,scale,npts);
  193.     L_temp = L_v_magsq(temp_buf,npts,0,1);
  194.     compare_zero();
  195.     if (L_temp) {
  196.       temp1 = norm_l(L_temp);
  197.       scale = sub(scale,shr(temp1,1));
  198.       if (scale < 0)
  199. scale = 0;
  200.     }
  201.     else
  202.       scale = 0;
  203.     sum_abs = 0;    data_move();
  204.     for (i = 0; i < npts; i++) {
  205.       L_temp = L_deposit_l(abs_s(input[i]));
  206.       sum_abs = L_add(sum_abs, L_temp);
  207.     }
  208.     /* Right shift input signal and put in temp buffer */
  209.     /* increment complexity for if statement */
  210.     compare_zero();
  211.     if (scale)
  212.       v_equ_shr(temp_buf,input,scale,npts);
  213.     /* increment complexity for if statement */
  214.     compare_zero();
  215.     if (sum_abs > 0)
  216.       {
  217. /* peak_fact = sqrt(npts*v_magsq(input,npts)) / sum_abs */
  218. /*           = sqrt(npts)*(sqrt(v_magsq(input,npts))/sum_abs) */
  219. /* increment complexity for if statement */
  220. compare_zero();
  221. if (scale)
  222.   L_temp = L_v_magsq(temp_buf,npts,0,0);
  223. else
  224.   L_temp = L_v_magsq(input,npts,0,0);
  225. L_temp = L_deposit_l(L_sqrt_fxp(L_temp,0));    /* L_temp in Q0 */
  226. peak_fact = L_divider2(L_temp,sum_abs,0,0);
  227. compare_nonzero();
  228. if (peak_fact > LIMIT_PEAKI) {
  229.   peak_fact = SW_MAX;        data_move();
  230. }
  231. else {
  232.   /* shl 7 is mult , other shift is Q7->Q12 */
  233.   temp1 = add(scale,5);
  234.   temp2 = shl(npts,7);
  235.   temp2 = sqrt_fxp(temp2,7);
  236.   L_temp = L_mult(peak_fact,temp2);
  237.   L_temp = L_shl(L_temp,temp1);
  238.   peak_fact = extract_h(L_temp);
  239. }
  240.       }
  241.     else
  242.       peak_fact = 0;
  243.     MEM_FREE(FREE,temp_buf);
  244.     return(peak_fact);
  245. } /* peakiness */
  246. #undef LIMIT_PEAKI
  247. /* */
  248. /* Subroutine QUANT_U: quantize positive input value with  */
  249. /* symmetrical uniform quantizer over given positive */
  250. /* input range. */
  251. /* */
  252. void quant_u(Shortword *p_data, Shortword *p_index, Shortword qmin, 
  253.      Shortword qmax, Shortword nlev, Shortword nlev_q, 
  254.      Shortword double_flag, Shortword scale)
  255. {
  256.   Shortword i;
  257.   Shortword step, half_step, qbnd, *p_in;
  258.   Longword L_step, L_half_step, L_qbnd, L_qmin, L_p_in;
  259.   Shortword temp;
  260.   Longword L_temp;
  261.   p_in = p_data;
  262.   /*  Define symmetrical quantizer stepsize */
  263.   /* step = (qmax - qmin) / (nlev - 1); */
  264.   temp = sub(qmax,qmin);
  265.   step = divide_s(temp,nlev_q);
  266.   if (double_flag) {
  267.     /* double precision specified */
  268.     /*  Search quantizer boundaries */
  269.     /*qbnd = qmin + (0.5 * step); */
  270.     L_step = L_deposit_l(step);
  271.     L_half_step = L_shr(L_step,1);
  272.     L_qmin = L_shl(L_deposit_l(qmin),scale);
  273.     L_qbnd = L_add(L_qmin,L_half_step);
  274.     L_p_in = L_shl(L_deposit_l(*p_in),scale);
  275.     for (i = 0; i < nlev; i++) {
  276.       if (L_p_in < L_qbnd)
  277. break;
  278.       else
  279. L_qbnd = L_add(L_qbnd,L_step);
  280.     }
  281.     /* Quantize input to correct level */
  282.     /* *p_in = qmin + (i * step); */
  283.     L_temp = L_sub(L_qbnd,L_half_step);
  284.     *p_in = extract_l(L_shr(L_temp,scale));
  285.     *p_index = i;
  286.   }
  287.   else {
  288.     /*  Search quantizer boundaries */
  289.     /* qbnd = qmin + (0.5 * step); */
  290.     step = shr(step,scale);
  291.     half_step = shr(step,1);
  292.     qbnd = add(qmin,half_step);
  293.     for (i = 0; i < nlev; i ++ ) {
  294.       if (*p_in < qbnd)
  295. break;
  296.       else
  297. qbnd = add(qbnd,step);
  298.     }
  299.     /*  Quantize input to correct level */
  300.     /* *p_in = qmin + (i * step); */
  301.     *p_in = sub(qbnd,half_step);
  302.     *p_index = i;
  303.   }
  304. } /* quant_u */
  305. /* */
  306. /* Subroutine QUANT_U_DEC: decode uniformly quantized */
  307. /* value. */
  308. /* */
  309. void quant_u_dec(Shortword index, Shortword *p_data, Shortword qmin, 
  310.  Shortword qmax, Shortword nlev_q, Shortword scale)
  311. {
  312.   Shortword step,temp;
  313.   Longword L_qmin, L_temp;
  314.   /*  Define symmetrical quantizer stepsize */
  315.   /* step = (qmax - qmin) / (nlev - 1); */
  316.   temp = sub(qmax,qmin);
  317.   step = divide_s(temp,nlev_q);
  318.   /*  Decode quantized level */
  319.   /* double precision specified */
  320.   L_temp = L_shr(L_mult(step,index),1);
  321.   L_qmin = L_shl(L_deposit_l(qmin),scale);
  322.   L_temp = L_add(L_qmin,L_temp);
  323.   *p_data = extract_l(L_shr(L_temp,scale));
  324. }
  325. /* */
  326. /* Subroutine rand_num: generate random numbers to fill    */
  327. /*      array using "minimal standard" random number generator. */
  328. /*                                                              */
  329. void rand_num(Shortword output[], Shortword amplitude, Shortword npts)
  330. {
  331.     Shortword i,temp;
  332.     Shortword rand_minstdgen(void);
  333.     for (i = 0; i < npts; i++ ) {
  334. /* rand_minstdgen returns 0 <= x < 1 */
  335.         /* -0.5 <= temp < 0.5 */
  336.         temp = sub(rand_minstdgen(),(Shortword)X05_Q15);
  337. output[i] = mult(amplitude,shl(temp,1));
  338.     }
  339. }
  340. /****************************************************************************/
  341. /* RAND() - COMPUTE THE NEXT VALUE IN THE RANDOM NUMBER SEQUENCE.           */
  342. /*                                                                          */
  343. /*     The sequence used is x' = (A*x) mod M,  (A = 16807, M = 2^31 - 1).   */
  344. /*     This is the "minimal standard" generator from CACM Oct 1988, p. 1192.*/
  345. /*     The implementation is based on an algorithm using 2 31-bit registers */
  346. /*     to represent the product (A*x), from CACM Jan 1990, p. 87.           */
  347. /*                                                                          */ 
  348. /****************************************************************************/ 
  349. #define A 16807u                        /* MULTIPLIER VALUE    */
  350. static ULongword next = 1;   /* seed; must not be zero!!! */
  351. Shortword rand_minstdgen()
  352. {
  353.      extern int saturation;
  354.      int old_saturation;
  355.      UShortword x0 = extract_l(next);      /* 16 LSBs OF SEED     */
  356.      UShortword x1 = extract_h(next);      /* 16 MSBs OF SEED     */
  357.      ULongword p, q;                       /* MSW, LSW OF PRODUCT */
  358.      ULongword L_temp1,L_temp2;
  359.      ULongword L_mpyu(UShortword var1, UShortword var2);
  360.      /*---------------------------------------------------------------------*/
  361.      /* COMPUTE THE PRODUCT (A * next) USING CROSS MULTIPLICATION OF        */
  362.      /* 16-BIT HALVES OF THE INPUT VALUES.  THE RESULT IS REPRESENTED AS 2  */
  363.      /* 31-BIT VALUES.  SINCE 'A' FITS IN 15 BITS, ITS UPPER HALF CAN BE    */
  364.      /* DISREGARDED.  USING THE NOTATION val[m::n] TO MEAN "BITS n THROUGH  */
  365.      /* m OF val", THE PRODUCT IS COMPUTED AS:                              */
  366.      /*   q = (A * x)[0::30]  = ((A * x1)[0::14] << 16) + (A * x0)[0::30]   */
  367.      /*   p = (A * x)[31::60] =  (A * x1)[15::30]       + (A * x0)[31]  + C */
  368.      /* WHERE C = q[31] (CARRY BIT FROM q).  NOTE THAT BECAUSE A < 2^15,    */
  369.      /* (A * x0)[31] IS ALWAYS 0.                                           */
  370.      /*---------------------------------------------------------------------*/
  371.      /* save and reset saturation count */
  372.      old_saturation = saturation;
  373.      saturation = 0;
  374.      /* q = ((A * x1) << 17 >> 1) + (A * x0); */
  375.      /* p = ((A * x1) >> 15) + (q >> 31); */
  376.      /* q = q << 1 >> 1; */                        /* CLEAR CARRY */
  377.      L_temp1 = L_mpyu(A,x1);
  378.      /* store bit 15 to bit 31 in p */
  379.      p = L_shr(L_temp1,15);
  380.      /* mask bit 15 to bit 31 */
  381.      L_temp1 = L_shl((L_temp1 & (Longword)0x00007fff),16);     L_logic();
  382.      L_temp2 = L_mpyu(A,x0);
  383.      q = L_add(L_temp1,L_temp2);
  384.      compare_zero();
  385.      if (saturation > 0) {
  386.        /* reset saturation */
  387.        saturation = 0;
  388.        /* subtract 0x80000000 from sum */
  389.        L_temp1 = L_sub(L_temp1,(Longword)0x7fffffff);
  390.        L_temp1 = L_sub(L_temp1,1);
  391.        q = L_add(L_temp1,L_temp2);
  392.        p = L_add(p,1);
  393.      }
  394.      /*---------------------------------------------------------------------*/
  395.      /* IF (p + q) < 2^31, RESULT IS (p + q).  OTHERWISE, RESULT IS         */
  396.      /* (p + q) - 2^31 + 1.  (SEE REFERENCES).                              */
  397.      /*---------------------------------------------------------------------*/
  398.      /* p += q; */
  399.      /* next = ((p + (p >> 31)) << 1) >> 1; */ /* ADD CARRY, THEN CLEAR IT */
  400.      L_temp1 = L_add(p,q);
  401.      compare_zero();
  402.      if (saturation > 0) {
  403.        /* subtract 0x7fffffff from sum */
  404.        L_temp1 = L_sub(p,(Longword)0x7fffffff);
  405.        L_temp1 = L_add(L_temp1,q);
  406.      }
  407.      next = L_temp1;     L_data_move();
  408.      /* restore saturation count */
  409.      saturation = old_saturation;
  410.      x1 = extract_h(next);
  411.      return (x1);
  412. } /* rand_minstdgen */
  413. /***************************************************************************
  414.  *
  415.  *   FUNCTION NAME: L_mpyu
  416.  *
  417.  *   PURPOSE:
  418.  *
  419.  *     Perform an unsigned fractional multipy of the two unsigned 16 bit 
  420.  *     input numbers with saturation.  Output a 32 bit unsigned number.
  421.  *
  422.  *   INPUTS:
  423.  *
  424.  *     var1
  425.  *                     16 bit short unsigned integer (Shortword) whose value
  426.  *                     falls in the range 0xffff 0000 <= var1 <= 0x0000 ffff.
  427.  *     var2
  428.  *                     16 bit short unsigned integer (Shortword) whose value
  429.  *                     falls in the range 0xffff 0000 <= var2 <= 0x0000 ffff.
  430.  *
  431.  *   OUTPUTS:
  432.  *
  433.  *     none
  434.  *
  435.  *   RETURN VALUE:
  436.  *
  437.  *     L_Out
  438.  *                     32 bit long unsigned integer (Longword) whose value
  439.  *                     falls in the range
  440.  *                     0x0000 0000 <= L_var1 <= 0xffff ffff.
  441.  *
  442.  *   IMPLEMENTATION:
  443.  *
  444.  *     Multiply the two unsigned 16 bit input numbers. 
  445.  *
  446.  *   KEYWORDS: multiply, mult, mpy
  447.  *
  448.  *************************************************************************/
  449. ULongword L_mpyu(UShortword var1, UShortword var2)
  450. {
  451.   ULongword L_product;
  452.   extern int complexity;
  453.   int old_complexity;
  454.   
  455.   old_complexity = complexity;
  456.   L_product = (ULongword) var1 *var2; /* integer multiply */
  457.       
  458.   complexity = old_complexity + 1;
  459.   return (L_product);
  460. }
  461. /* */
  462. /* Subroutine READBL: read block of input data */
  463. /* */
  464. #define MAXSIZE 1024
  465. Shortword readbl(Shortword input[], FILE *fp_in, Shortword size)
  466. {
  467.     Shortword i, length;
  468.     Shortword int_sp[MAXSIZE]; /*  integer input array */
  469. #ifdef PRINT
  470.     if (size > MAXSIZE) {
  471. printf("****ERROR: read block size too large **** n");
  472. exit(1);
  473.     }
  474. #endif
  475.     length = fread(int_sp,sizeof(Shortword),size,fp_in);
  476.     for (i = 0; i < length; i++ )
  477.       input[i] = int_sp[i];
  478.     for (i = length; i < size; i++ )
  479.       input[i] = 0;
  480.     return length;
  481. }
  482. #undef MAXSIZE
  483. /* */
  484. /* Subroutine UNPACK_CODE: Unpack bit code from channel. */
  485. /*      Return 1 if erasure, otherwise 0.                       */
  486. /* */
  487. Shortword unpack_code(UShortword **p_ch_beg, Shortword *p_ch_bit, 
  488.       Shortword *p_code, Shortword numbits, Shortword wsize, 
  489.       UShortword ERASE_MASK)
  490. {
  491.     Shortword ret_code;
  492.     Shortword i,ch_bit;
  493.     UShortword *ch_word;
  494. ch_bit = *p_ch_bit;
  495. ch_word = *p_ch_beg;
  496. *p_code = 0;
  497.         ret_code = *ch_word & ERASE_MASK;    
  498. for (i = 0; i < numbits; i++) {
  499. /* Mask in bit from channel word to code */
  500. *p_code |= shl(shr((Shortword)((Shortword)*ch_word & shl(1,ch_bit)),ch_bit),i);
  501. /* Check for end of channel word */
  502. ch_bit = add(ch_bit,1);
  503. if (ch_bit >= wsize) {
  504. ch_bit = 0;
  505. (*p_ch_beg)++ ;
  506. ch_word++ ;
  507. }
  508. }
  509. /*  Save updated bit counter */
  510. *p_ch_bit = ch_bit;
  511.     /* Catch erasure in new word if read */
  512.     if (ch_bit != 0)
  513.       ret_code |= *ch_word & ERASE_MASK;    
  514.     return(ret_code);
  515. }
  516. /* */
  517. /* Subroutine window: multiply signal by window            */
  518. /* */
  519. /* Q values:
  520.    input - Q0
  521.    win_cof - Q15
  522.    output - Q0 */
  523. void window(Shortword input[], Shortword win_cof[], 
  524.     Shortword output[], Shortword npts)
  525. {
  526.     Shortword i;
  527.     for (i = 0; i < npts; i++ ) {
  528.       output[i] = mult(win_cof[i],input[i]);    data_move();
  529.     }
  530. }
  531. /* */
  532. /* Subroutine window: multiply signal by window            */
  533. /* */
  534. /* Q values:
  535.    win_cof - Qin
  536.    output = input */
  537. void window_Q(Shortword input[], Shortword win_cof[], 
  538.   Shortword output[], Shortword npts, Shortword Qin)
  539. {
  540.     Shortword i;
  541.     Shortword shift;
  542.     shift = sub(15,Qin);
  543.     for (i = 0; i < npts; i++ ) {
  544.       output[i] = extract_h(L_shl(L_mult(win_cof[i],input[i]),shift));
  545.     }
  546. }
  547. /* */
  548. /* Subroutine WRITEBL: write block of output data */
  549. /* */
  550. #define MAXSIZE 1024
  551. void writebl(Shortword output[], FILE *fp_out, Shortword size)
  552. {
  553.     fwrite(output,sizeof(Shortword),size,fp_out);
  554. }
  555. #undef MAXSIZE
  556. /*                                                              */
  557. /*      Subroutine zerflt: all zero (FIR) filter.               */
  558. /*      Note: the output array can overlay the input.           */
  559. /*                                                              */
  560. /* Q values:
  561.    input - Q0
  562.    coeff - Q12
  563.    output - Q0 */
  564. void zerflt(Shortword input[], Shortword coeff[], 
  565. Shortword output[], Shortword order, Shortword npts)
  566. {
  567.     Shortword i,j;
  568.     Longword  accum;
  569.     
  570.     
  571.     for (i = npts-1; i >= 0; i-- ) {
  572.       accum = 0;    data_move();
  573.       for (j = 0; j <= order; j++ )
  574. accum = L_mac(accum, input[i-j],coeff[j]);
  575.       /* Round off output */
  576.       accum = L_shl(accum,3);
  577.       output[i] = round(accum);
  578.     }
  579. }
  580. /*                                                              */
  581. /*      Subroutine zerflt_Q: all zero (FIR) filter.             */
  582. /*      Note: the output array can overlay the input.           */
  583. /*                                                              */
  584. /* Q values:
  585.    coeff - specified by Q_coeff
  586.    output - same as input */
  587. void zerflt_Q(Shortword input[], Shortword coeff[], Shortword output[], 
  588.       Shortword order, Shortword npts, Shortword Q_coeff)
  589. {
  590.     Shortword i,j,scale;
  591.     Longword  accum;
  592.     
  593.     scale = sub(15,Q_coeff);
  594.     for (i = npts-1; i >= 0; i-- ) {
  595.       accum = 0;    data_move();
  596.       for (j = 0; j <= order; j++ )
  597. accum = L_mac(accum, input[i-j],coeff[j]);
  598.       /* Round off output */
  599.       accum = L_shl(accum,scale);
  600.       output[i] = round(accum);
  601.     }
  602. }
  603. /*                                                              */
  604. /*      Subroutine iir_2nd_d: Second order IIR filter           */
  605. /*                            (Double precision)                */
  606. /*      Note: the output array can overlay the input.           */
  607. /*                                                              */
  608. /* Input scaled down by a factor of 2 to prevent overflow */
  609. void iir_2nd_d(Shortword input[],Shortword den[],Shortword num[],
  610.        Shortword output[],Shortword delin[],Shortword delout_hi[],
  611.        Shortword delout_lo[],Shortword npts)
  612. {
  613.   Shortword i,temp;
  614.   Longword accum;
  615.   for (i = 0; i < npts; i++) {
  616.     accum = L_mult(delout_lo[0],den[1]);
  617.     accum = L_mac(accum,delout_lo[1],den[2]);
  618.     accum = L_shr(accum,14);
  619.     accum = L_mac(accum,delout_hi[0],den[1]);
  620.     accum = L_mac(accum,delout_hi[1],den[2]);
  621.     accum = L_mac(accum,shr(input[i],1),num[0]);
  622.     accum = L_mac(accum,delin[0],num[1]);
  623.     accum = L_mac(accum,delin[1],num[2]);
  624.     /* shift result to correct Q value */
  625.     accum = L_shl(accum,2);      /* assume coefficients in Q13 */
  626.     /* update input delay buffer */
  627.     delin[1] = delin[0];    data_move();
  628.     delin[0] = shr(input[i],1);    data_move();
  629.     /* update output delay buffer */
  630.     delout_hi[1] = delout_hi[0];    data_move();
  631.     delout_lo[1] = delout_lo[0];    data_move();
  632.     delout_hi[0] = extract_h(accum);
  633.     temp = shr(extract_l(accum),2);
  634.     delout_lo[0] = temp & (Shortword)0x3FFF;    logic();
  635.     /* round off result */
  636.     accum = L_shl(accum,1);
  637.     output[i] = round(accum);
  638.   }
  639. }
  640. /*                                                              */
  641. /*      Subroutine iir_2nd_s: Second order IIR filter           */
  642. /*                            (Single precision)                */
  643. /*      Note: the output array can overlay the input.           */
  644. /*                                                              */
  645. /* Input scaled down by a factor of 2 to prevent overflow */
  646. void iir_2nd_s(Shortword input[],Shortword den[],Shortword num[],
  647.        Shortword output[],Shortword delin[],Shortword delout[],
  648.        Shortword npts)
  649. {
  650.   Shortword i;
  651.   Longword accum;
  652.   for (i = 0; i < npts; i++) {
  653.     accum = L_mult(input[i],num[0]);
  654.     accum = L_mac(accum,delin[0],num[1]);
  655.     accum = L_mac(accum,delin[1],num[2]);
  656.     accum = L_mac(accum,delout[0],den[1]);
  657.     accum = L_mac(accum,delout[1],den[2]);
  658.     /* shift result to correct Q value */
  659.     accum = L_shl(accum,2);      /* assume coefficients in Q13 */
  660.     /* update input delay buffer */
  661.     delin[1] = delin[0];    data_move();
  662.     delin[0] = input[i];    data_move();
  663.     /* round off result */
  664.     output[i] = round(accum);
  665.     /* update output delay buffer */
  666.     delout[1] = delout[0];    data_move();
  667.     delout[0] = output[i];    data_move();
  668.   }
  669. }