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

语音压缩

开发平台:

C/C++

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