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

语音压缩

开发平台:

C/C++

  1. /*
  2.   fs_lib.c: Fourier series 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 "fs.h"
  15. #include "constant.h"
  16. /*  compiler constants */
  17. #define PRINT 1
  18. /*  external variable */
  19. //extern int complexity;
  20. /* */
  21. /* Subroutine FIND_HARM: find Fourier coefficients using */
  22. /* FFT of input signal divided into pitch dependent bins. */
  23. /* */
  24. /*  Q values:
  25.     input - Q0
  26.     fsmag - Q13
  27.     pitch - Q7 */
  28. #define FFTLENGTH 512
  29. /* Memory definition */
  30. static Shortword find_hbuf[2*FFTLENGTH];
  31. static Longword mag[FFTLENGTH];
  32. static Shortword wr_array[FFTLENGTH/2+1];
  33. static Shortword wi_array[FFTLENGTH/2+1];
  34. void find_harm(Shortword input[],Shortword fsmag[],Shortword pitch,
  35.        Shortword num_harm,Shortword length)
  36. {
  37.     Shortword i, j, k, iwidth, i2;
  38.     Shortword fwidth;
  39.     Shortword num_harm_Q11;
  40.     Longword  avg;
  41.     Shortword temp;
  42.     Shortword shift, max;
  43.     Longword *L_fsmag;
  44. Longword L_temp,L_shift;
  45. Shortword temp1;
  46.     
  47.     MEM_ALLOC(MALLOC, L_fsmag, num_harm, Longword);
  48.     /* Find normalization factor of frame and */
  49.     /* scale input to maximum precision.      */
  50.     max = 0;    //   data_move();mark del
  51.     for (i = 0; i < length; i++) {
  52.       /* temp = abs_s(input[i]); */
  53.    L_temp = _abs2((Longword)input[i]);
  54.    temp = (Shortword) (0x0000ffffL & L_temp);
  55. //      compare_nonzero();  mark del
  56.       if (temp > max)
  57. max = temp;
  58.     }
  59.    /*  shift = norm_s(max); */
  60.    L_temp = (Longword) max << 16;
  61.    L_shift = _norm(L_temp);
  62.    if (L_temp == 0){
  63.     L_shift = (Longword)0;
  64.    }
  65.    shift = (Shortword) (0x0000ffffL & L_shift);
  66.     /* initialize fsmag */
  67.     for (i = 0; i < num_harm; i++)
  68.       fsmag[i] = ONE_Q13;
  69.     /* Perform peak-picking on FFT of input signal */
  70.     /* Calculate FFT of complex signal in scratch buffer */
  71.     v_zap(find_hbuf,2*FFTLENGTH);
  72.     for (i = 0; i < 2*length; i+=2) {
  73.        find_hbuf[i] = shl(input[i/2],shift);  
  74.        /*  find_hbuf[i] = (shift >=0)? (shl_a(input[i/2],shift)) : (shr_a(input[i/2],shift)); */
  75.       // data_move();mark del
  76.     }
  77.     fft(find_hbuf,FFTLENGTH,MONE_Q15);
  78.     /* Implement pitch dependent staircase function */
  79.     /* Harmonic bin width */
  80.     /* fwidth=Q6 */
  81.     /* fwidth = shr(divide_s((Shortword)FFTLENGTH,pitch),2); */
  82.        temp1 = divide_s((Shortword)FFTLENGTH,pitch);
  83.    L_temp = _shr2((Longword)temp1,2);
  84.    fwidth = (Shortword) (0x0000ffffL & L_temp);
  85.     /* iwidth = (int) fwidth */
  86.   /*   iwidth = shr(fwidth,6); */
  87.        L_temp = _shr2((Longword)fwidth,6);
  88.    iwidth = (Shortword) (0x0000ffffL & L_temp);
  89. //    compare_nonzero();mark del
  90.     if (iwidth < 2) {
  91.       iwidth = 2;    
  92.       //  data_move();  mark del
  93.     }
  94.     /* i2 = shr(iwidth,1); */
  95.   L_temp = _shr2((Longword)iwidth,1);
  96.   i2 = (Shortword) (0x0000ffffL & L_temp);
  97.     /* if (num_harm > 0.25*pitch) num_harm = 0.25*pitch */
  98.     /* temp = 0.25*pitch in Q0 */
  99.    /*  temp = shr(pitch,9); */
  100.       L_temp = _shr2((Longword)pitch,9);
  101.   temp = (Shortword) (0x0000ffffL & L_temp);
  102. //    compare_nonzero();  mark del
  103.     if (num_harm > temp) {
  104.       num_harm = temp;
  105.     }
  106.     /* initialize avg to make sure that it is non-zero */
  107.     avg = 1;    //   L_data_move();data_move
  108.     for (k = 0; k < num_harm; k++) {
  109.       /* i = ((k+1)*fwidth) - i2 + 0.5 */ /* Start at peak-i2 */
  110.       /* temp = extract_l(L_mult(add(k,1),fwidth));   temp=Q7  */
  111. /*       i = shr(add(sub(temp,shl(i2,7)),(Shortword)X05_Q7),7);    */
  112.         L_temp = _sadd2((Longword)k,(Longword)1);
  113. temp1 = (Shortword) (0x0000ffffL & L_temp);
  114. L_temp = _smpy(temp1,fwidth);
  115. temp = (Shortword) (0x0000ffffL & L_temp);
  116. temp1 = sub(temp,shl_a(i2,7));
  117. L_temp = _sadd2((Longword)temp1,(Longword)X05_Q7);
  118. L_temp = _shr2(L_temp,7);
  119. i = (Shortword) (0x0000ffffL & L_temp);
  120.       /* Calculate magnitude squared of coefficients */
  121.       for (j = i; j < i+iwidth; j++) {
  122. /* mag[j] = L_add(L_mult(find_hbuf[2*j],find_hbuf[2*j]),      */
  123. /*         L_mult(find_hbuf[(2*j)+1],find_hbuf[(2*j)+1]));   */
  124.        mag[j] = _sadd(_smpy(find_hbuf[2*j],find_hbuf[2*j]),
  125.        _smpy(find_hbuf[(2*j)+1],find_hbuf[(2*j)+1]));
  126. // L_data_move();   mark del
  127.       }
  128.       /* j = add(i,findmax(&mag[i],iwidth)); */
  129.       temp1 = findmax(&mag[i],iwidth);
  130.   L_temp = _sadd2((Longword)i,(Longword)temp1);
  131.   j = (Shortword) (0x0000ffffL & L_temp);
  132.       L_fsmag[k] = mag[j];    
  133. //         L_data_move();   mark del
  134.       /* avg = L_add(avg,mag[j]); */
  135.   avg = _sadd(avg,mag[j]);
  136.     }
  137.     /* Normalize Fourier series values to average magnitude */
  138.     num_harm_Q11 = shl_a(num_harm,11);
  139.     for (i = 0; i < num_harm; i++) {
  140.       /* temp = num_harm/(avg+ .0001) */
  141.       /* fsmag[i] = sqrt(temp*fsmag[i]) */
  142.       /* temp = L_divider2(L_fsmag[i],avg,0,0);      temp=Q15 */ 
  143. /*       temp = mult(num_harm_Q11,temp);     temp=Q11 */         
  144. /*       fsmag[i] = shl(sqrt_fxp(temp,11),2);                      */   
  145.          temp = L_divider2(L_fsmag[i],avg,0,0);
  146.  L_temp = _smpy(num_harm_Q11,temp);
  147.  temp = (Shortword) (0x0000ffffL & (L_temp >> 16));
  148.  fsmag[i] = shl_a(sqrt_fxp(temp,11),2);
  149.  
  150.       //   data_move();   mark del
  151.     }
  152.     MEM_FREE(FREE,L_fsmag);
  153. } /* find_harm */
  154.     
  155. /* Subroutine FFT: Fast Fourier Transform  */
  156. /**************************************************************
  157. * Replaces data by its DFT, if isign is 1, or replaces data   *
  158. * by inverse DFT times nn if isign is -1.  data is a complex  *
  159. * array of length nn, input as a real array of length 2*nn.   *
  160. * nn MUST be an integer power of two.  This is not checked    *
  161. * The real part of the number should be in the zeroeth        *
  162. * of data , and the imaginary part should be in the next      *
  163. * element.  Hence all the real parts should have even indeces *
  164. * and the imaginary parts, odd indeces.       *
  165. * Data is passed in an array starting in position 0, but the  *
  166. * code is copied from Fortran so uses an internal pointer     *
  167. * which accesses position 0 as position 1, etc.       *
  168. * This code uses e+jwt sign convention, so isign should be    *
  169. * reversed for e-jwt.                                         *
  170. ***************************************************************/
  171. /* Q values:
  172.    datam1 - Q14
  173.    isign - Q15 */
  174. #define SWAP(a,b) temp1 = (a);(a) = (b); (b) = temp1
  175. void fft(Shortword *datam1,Shortword nn,Shortword isign)
  176. {
  177. Shortword n,mmax,m,j,istep,i;
  178. Shortword wr,wi,temp1;
  179. register Longword  L_tempr,L_tempi;
  180. Shortword *data;
  181. Longword L_temp1,L_temp2;
  182. Shortword index,index_step;
  183. Longword L_temp;
  184. /*  Use pointer indexed from 1 instead of 0 */
  185. data = &datam1[-1];
  186. n = shl_a(nn,1);
  187. j = 1;
  188. for( i = 1; i < n; i+=2 ) {
  189.   if ( j > i) {
  190.     SWAP(data[j],data[i]);  
  191. //       data_move();    data_move();  mark del
  192.     SWAP(data[j+1],data[i+1]);  
  193. //       data_move();    data_move();  mark del
  194.   }
  195.   m = nn;
  196.   while ( m >= 2 && j > m ) {
  197. j = sub(j,m);
  198. /* m = shr(m,1); */
  199. L_temp = _shr2((Longword)m,1);
  200. m = (Shortword) (0x0000ffffL & L_temp);
  201.   }
  202.  /*  j = add(j,m); */
  203.     L_temp = _sadd2((Longword)j,(Longword)m);
  204. j = (Shortword) (0x0000ffffL & L_temp);
  205. }
  206. mmax = 2;
  207. /* initialize index step */
  208. index_step = nn;
  209. while ( n > mmax) {
  210.   istep = shl_a(mmax,1);  /* istep = 2 * mmax */
  211.   index = 0;
  212.   /* index_step = shr(index_step,1); */
  213.   L_temp = _shr2((Longword)index_step,1);
  214.       index_step = (Shortword) (0x0000ffffL & L_temp);
  215.   wr = ONE_Q15;
  216.   wi = 0;
  217.   for ( m = 1; m < mmax;m+=2) {
  218.     for ( i = m; i <= n; i += istep) {
  219. j = i + mmax;
  220. /* note: complexity is reduced since L_shr is not necessary 
  221.    on TMS32C5x with SPM=0, mac and msu can be used */
  222. /*tempr = wr * data[j] - wi * data[j+1] */
  223. /*  L_temp1 = L_shr(L_mult(wr,data[j]),1);   */
  224. /*  L_temp2 = L_shr(L_mult(wi,data[j+1]),1); */
  225. /*  L_tempr = L_sub(L_temp1,L_temp2);      */
  226.         L_temp1 = _sshvr(_smpy(wr,data[j]),1);
  227. L_temp2 = _sshvr(_smpy(wi,data[j+1]),1);
  228. L_tempr = _ssub(L_temp1,L_temp2);
  229. // complexity -= (2+2+2);   mark del
  230. /* tempi = wr * data[j+1] + wi * data[j] */
  231. /*  L_temp1 = L_shr(L_mult(wr,data[j+1]),1); */
  232. /*  L_temp2 = L_shr(L_mult(wi,data[j]),1);   */
  233. /*         L_tempi = L_add(L_temp1,L_temp2);  */
  234.         L_temp1 = _sshvr(_smpy(wr,data[j+1]),1);
  235. L_temp2 = _sshvr(_smpy(wi,data[j]),1);
  236.     L_tempi = _sadd(L_temp1,L_temp2);
  237. // complexity -= (2+2+2);   mark del
  238.     /* data[j] = data[i] - tempr */
  239. /*  L_temp1 = L_shr(L_deposit_h(data[i]),1);        */
  240. /*      data[j] = extract_h(L_sub(L_temp1,L_tempr));    */
  241.         L_temp = (Longword)(data[i] << 16);
  242.         L_temp1 = _sshvr(L_temp,1);
  243. L_temp = _ssub(L_temp1,L_tempr);
  244.         data[j] = (Shortword) (0x0000ffffL & (L_temp >> 16));
  245. // complexity -= 2;    mark del
  246. /* data[i] += tempr */
  247. /* data[i] = extract_h(L_add(L_temp1,L_tempr)); */
  248. L_temp = _sadd(L_temp1,L_tempr);
  249.         data[i] = (Shortword) (0x0000ffffL & (L_temp >> 16));
  250. /* data[j+1] = data[i+1] - tempi */
  251. /* L_temp1 = L_shr(L_deposit_h(data[i+1]),1);     */
  252. /*  data[j+1] = extract_h(L_sub(L_temp1,L_tempi));   */
  253.         L_temp = (Longword) (data[i+1] << 16);
  254.         L_temp1 = _sshvr(L_temp,1);
  255. L_temp = _ssub(L_temp1,L_tempi);
  256.         data[j+1] = (Shortword) (0x0000ffffL & (L_temp >> 16));
  257.  
  258. // complexity -= 2;    mark del
  259. /* data[i+1] += tempi */
  260. /* data[i+1] = extract_h(L_add(L_temp1,L_tempi)); */
  261.  L_temp = _sadd(L_temp1,L_tempi);
  262.          data[i+1] = (Shortword) (0x0000ffffL & (L_temp >> 16));
  263.     }
  264.    /*  index = add(index,index_step); */
  265.     L_temp = _sadd2((Longword)index,(Longword)index_step);
  266. index = (Shortword) (0x0000ffffL & L_temp);
  267.     wr = wr_array[index];
  268.     if (isign < 0)
  269.       wi = negate(wi_array[index]);
  270.     else
  271.       wi = wi_array[index];
  272.   }
  273.   mmax = istep;
  274. }
  275. } /* fft */
  276. /*                                                              */
  277. /*      Subroutine FINDMAX: find maximum value in an            */
  278. /*      input array.                                            */
  279. /*                                                              */
  280. /* Shortword findmax(Longword input[],Shortword npts) */
  281. /* {                                                  */
  282. /*   register Shortword     i, maxloc;                */
  283. /*   register Longword  maxval, *p_in;                */
  284. /*                                                    */
  285. /*   p_in = &input[0];                                */
  286. /*   maxloc = 0;                                      */
  287. /* //     data_move();   mark del                     */
  288. /*   maxval = input[maxloc];                          */
  289. /* //   data_move();  mark del                        */
  290. /*   for (i = 1; i < npts; i++ ) {                    */
  291. /* //    compare_nonzero();mark del                   */
  292. /*     if (*(++p_in) > maxval) {                      */
  293. /*       maxloc = i;                                  */
  294. /* //         data_move();   mark del                 */
  295. /*       maxval = *p_in;                              */
  296. /* //       data_move();   mark del                   */
  297. /*     }                                              */
  298. /*   }                                                */
  299. /*   return(maxloc);                                  */
  300. /* }                                                  */
  301. /* Initialization of wr_array and wi_array */
  302. void fs_init()
  303. {
  304.   Shortword i;
  305.   Shortword fft_len2,shift,step,theta;
  306.   Longword L_temp,L_shift;
  307. /*   fft_len2 = shr(FFTLENGTH,1); */
  308. /*   shift = norm_s(fft_len2);    */
  309.   L_temp = _shr2((Longword)FFTLENGTH,1);
  310.   fft_len2 = (Shortword) (0x0000ffffL & L_temp);
  311.   L_temp = (Longword) fft_len2 << 16;
  312.   L_shift = _norm(L_temp);
  313.   if (L_temp == 0){
  314.     L_shift = (Longword)0;
  315.   }
  316.   shift = (Shortword) (0x0000ffffL & L_shift);
  317.   /* step = shl(2,shift); */
  318.   step = (shift >= 0)?(shl_a(2,shift)) : (shr_a(2,shift));
  319.   theta = 0;
  320.   for (i = 0; i <= fft_len2; i++) {
  321.     wr_array[i] = cos_fxp(theta);   
  322. //     data_move();    mark del
  323.     wi_array[i] = sin_fxp(theta);   
  324. //     data_move();   mark del
  325.     if (i >= (fft_len2-1))
  326.       theta = ONE_Q15;
  327.     else{
  328.       /* theta = add(theta,step); */
  329.   L_temp = _sadd2((Longword)theta,(Longword)step);
  330.   theta = (Shortword) (0x0000ffffL & L_temp);
  331.       }
  332.   }
  333. }
  334. /* */
  335. /* Subroutine IDFT_REAL: take inverse discrete Fourier  */
  336. /* transform of real input coefficients. */
  337. /* Assume real time signal, so reduce computation */
  338. /* using symmetry between lower and upper DFT */
  339. /* coefficients. */
  340. /* */
  341. /*  Q values:
  342.     real - Q13
  343.     signal - Q15
  344. */
  345. #define DFTMAX 160
  346. /* Memory definition */
  347. static Shortword idftc[DFTMAX];
  348. void idft_real(Shortword real[], Shortword signal[], Shortword length)
  349. {
  350.     Shortword i, j, k, k_inc, length2;
  351.     Shortword w, w2;
  352.     Shortword temp;
  353.     Longword L_temp;
  354. Longword L_temp1,L_temp2,L_temp3;
  355. #if (PRINT)
  356.     if (length > DFTMAX) {
  357. printf("****ERROR: IDFT size too large **** n");
  358. exit(1);
  359.     }
  360. #endif
  361.     
  362.    /*  length2 = add(shr(length,1),1); */
  363.     L_temp1 = _shr2((Longword)length,1);
  364. L_temp1 = _sadd2(L_temp1,(Longword)1);
  365. length2 = (Shortword) (0x0000ffffL & L_temp1);
  366.     /* w = TWOPI / length; */
  367.     w = divide_s(TWO_Q3,length);   /* w = 2/length in Q18 */
  368.     for (i = 0; i < length; i++ ) {
  369.        /*  L_temp = L_mult(w,i);       L_temp in Q19  */
  370.    L_temp = _smpy(w,i);
  371. /* make sure argument for cos function is less than 1 */
  372. // L_compare_nonzero();    mark del
  373. if (L_temp > (Longword)ONE_Q19) {
  374.   /* cos(pi+x) = cos(pi-x) */
  375.   /* L_temp = L_sub((Longword)TWO_Q19,L_temp); */
  376.    L_temp = _ssub((Longword)TWO_Q19,L_temp);
  377. }
  378. else if (L_temp == (Longword)ONE_Q19)
  379.   L_temp = _ssub(L_temp,1);
  380. L_temp = _sshvr(L_temp,4);      /* L_temp in Q15 */
  381. /*  temp = extract_l(L_temp);  */
  382.     temp = (Shortword) (0x0000ffffL & L_temp);
  383. idftc[i] = cos_fxp(temp);      /* idftc in Q15 */
  384.     }
  385.     /* w = shr(w,1);         w = 2/length in Q17    */
  386. /*     w2 = shr(w,1);       w2 = 1/length in Q17    */
  387. /*     real[0] = mult(real[0],w2);      real in Q15  */
  388.      L_temp1 = _shr2((Longword)w,1);
  389.  w = (Shortword) (0x0000ffffL & L_temp1);
  390.      L_temp2 = _shr2((Longword)w,1);
  391.  w2 = (Shortword) (0x0000ffffL & L_temp2);
  392.  L_temp3 = _smpy(real[0],w2);
  393.      real[0] = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
  394.     temp = sub(length2,1);
  395.     for (i = 1; i < temp; i++ ) {
  396.       /* real[i] *= (2.0/length); */
  397.       /* real[i] = mult(real[i],w); */
  398.    L_temp1 = _smpy(real[i],w);
  399.        real[i] = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
  400.     }
  401.     temp = shl_a(i,1);
  402.     if (temp == length){
  403.       /* real[i] *= (1.0/length); */
  404.     /*   real[i] = mult(real[i],w2); */
  405.   L_temp2 = _smpy(real[i],w2);
  406.   real[i] = (Shortword) (0x0000ffffL & (L_temp2 >> 16));
  407.      }
  408.     else{
  409.       /* real[i] *= (2.0/length);*/
  410.      /*  real[i] = mult(real[i],w); */
  411.   L_temp3 = _smpy(real[i],w);
  412.   real[i] = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
  413. }
  414.     for (i = 0; i < length; i++ ) {
  415. /* L_temp = L_deposit_h(real[0]);     L_temp in Q31 */
  416.     L_temp = (Longword)(real[0]) << 16;
  417. k_inc = i;
  418. k = k_inc;
  419. for (j = 1; j < length2; j++ ) {
  420.    /*  L_temp = L_mac(L_temp,real[j],idftc[k]); */
  421.     L_temp = _sadd(L_temp,_smpy(real[j],idftc[k]));
  422.     k += k_inc;
  423.     if (k >= length)
  424. k -= length;
  425. }
  426. /* signal[i] = round(L_temp); */
  427.     L_temp1 = _sadd(L_temp, 0x00008000L); /* round MSP */
  428.     signal[i] = (Shortword)(0x0000ffffL & (L_temp1 >> 16));
  429.     }
  430. } /* IDFT_REAL */