cmain.c
上传用户:touchwatch
上传日期:2007-01-06
资源大小:168k
文件大小:5k
源码类别:

语音压缩

开发平台:

Unix_Linux

  1. /*************************************************************************/
  2. /*                                                                       */
  3. /*                            LD-CELP  G.728                             */
  4. /*                                                                       */
  5. /*    Low-Delay Code Excitation Linear Prediction speech compression.    */
  6. /*                                                                       */
  7. /*    Code edited by Michael Concannon.                                  */
  8. /*    Based on code written by Alex Zatsman, Analog Devices 1993         */
  9. /*                                                                       */
  10. /*************************************************************************/
  11. /* Real multitasking works on a DSP target only, on other platform
  12.    it is simulated */
  13. #include <stdio.h>
  14. #include <signal.h>
  15. #include "common.h"
  16. #include "parm.h"
  17. #include "prototyp.h"
  18. extern void init_input();
  19. void init_encoder();
  20. void encoder();
  21. void encode_vector(int);
  22. void adapt_frame();
  23. static int dec_end; /* Index of the end of the decoded speech */
  24. int encoder_done = 0;
  25. #ifdef MAIN
  26. extern char *ifile_name;
  27. extern char *xfile_name;
  28. void main(int argc, char *argv[])
  29. {
  30.     void encoder();
  31.     static void usage(char*);
  32.     
  33.     if (argc != 3)
  34. usage(argv[0]);
  35.     ifile_name = argv[1];
  36.     xfile_name = argv[2];
  37.     ffase = 1;
  38.     encoder();
  39. }
  40. static void usage(char *name)
  41. {
  42.     fprintf(stderr, "Usage: %s <audio-file> <index-file>n", name);
  43.     exit(0);
  44. }
  45. #endif
  46. real thequeue[QSIZE];
  47. real * vector_end;
  48. void encoder()
  49. {
  50.     int vnum,i;
  51.     init_encoder();
  52.     for(i=0; i<QSIZE; i++) 
  53. thequeue[i]=0;
  54.     for(vnum=0; 
  55. read_sound_buffer(IDIM, thequeue + (vnum * IDIM)%QSIZE) > 0;
  56. vnum++) 
  57.     {
  58. vector_end = thequeue+(vnum*IDIM)%QSIZE+IDIM;
  59. encode_vector(0);
  60. adapt_frame();
  61.     }
  62. }
  63. void init_encoder()
  64. {
  65.     int i;
  66.     init_pwf_adapter(pwf_z_coeff, pwf_p_coeff);
  67.     pwf_z_coeff_next[0] = pwf_p_coeff_next[0] = 1.0;
  68.     pwf_z_coeff_obsolete_p = 0;
  69.     init_bsf_adapter(sf_coeff);
  70.     sf_coeff_next[0] = 1.0;
  71.     sf_coeff_obsolete_p = 0;
  72.     init_gain_adapter(gp_coeff);
  73.     init_gain_buf();
  74.     gp_coeff_next[0] = 1.0;
  75.     gp_coeff_next[1] = -1.0;
  76.     gp_coeff_obsolete_p = 0;
  77.     init_input();
  78.     vector_end=thequeue;
  79.     ZARR(imp_resp);
  80.     imp_resp[0] = 1.0;
  81.     shape_conv(imp_resp, shape_energy);
  82. }
  83. void encode_vector(int ignore)
  84. {
  85.     int ix; /* Computed Codebook Index */
  86.     int vx;     /* Index of Recently Read Vector  */
  87.     int lgx; /* Logarithmic Gain Index */
  88.     static real QMEM *vector; /* recently read vector in the queue */
  89.     static real
  90. zero_response[IDIM],
  91. weighted_speech[IDIM],
  92. target[IDIM],
  93. normtarg[IDIM],
  94. cb_vec[IDIM],
  95. pn[IDIM];
  96.     static real gain =1.0, scale=1.0;
  97.     
  98.     vector = vector_end - IDIM;
  99.     if (vector < thequeue)
  100. vector += QSIZE;
  101.     vx = vector-thequeue;
  102.     UPDATE(pwf_z_coeff); /* Copy new coeff if flag set */
  103.     UPDATE(pwf_p_coeff);
  104.     pwfilter2(vector, weighted_speech);
  105.     UPDATE(sf_coeff);
  106.     zresp(zero_response);
  107.     sub_sig(weighted_speech, zero_response, target);
  108.     UPDATE(gp_coeff);
  109.     gain = predict_gain();
  110.     scale = 1.0 / gain;
  111.     sig_scale(scale, target, normtarg);
  112.     UPDATE(imp_resp);
  113.     trev_conv(imp_resp, normtarg, pn);
  114.     UPDATE(shape_energy);
  115.     ix = cb_index(pn);
  116.     put_index(ix);
  117.     cb_excitation(ix, cb_vec);
  118.     sig_scale(gain, cb_vec, qspeech+vx);
  119.     lgx = vx/IDIM;
  120.     update_gain(qspeech+vx, log_gains + lgx);
  121.     mem_update(qspeech+vx, synspeech+vx);
  122.     dec_end = vx+IDIM;
  123.     if (dec_end >= QSIZE)
  124. dec_end -= QSIZE;
  125.     NEXT_FFASE; /* Update vector counter  */
  126. }
  127. /* Update the filter coeff if we are at the correct vector in the frame */
  128. /* ffase is the vector count (1-4) within the current frame */
  129. void adapt_frame()
  130. {
  131.     static real
  132. input [NUPDATE*IDIM],
  133. synth [NUPDATE*IDIM],
  134. lg [NUPDATE];
  135.     int gx; /* Index for log_gains, cycle end */
  136.     /* Backward syn. filter coeff update.  Occurs after full frame (before
  137.        first vector) but not used until the third vector of the frame */
  138.     FFASE(1)
  139.     {
  140.       CIRCOPY(synth,synspeech,dec_end,NUPDATE*IDIM,QSIZE);
  141.       bsf_adapter (synth, sf_coeff_next); /* Compute then new coeff */
  142.     }
  143.     /* Before third vector of frame */
  144.     FFASE(3)
  145.       sf_coeff_obsolete_p = 1; /* Copy coeff computed above(2 frames later)*/
  146.     /* Gain coeff update before second vector of frame */
  147.     FFASE(2)
  148.     {
  149. gx = dec_end/IDIM;
  150. CIRCOPY(lg, log_gains, gx, NUPDATE, QSIZE/IDIM);
  151. gain_adapter(lg, gp_coeff_next);
  152. gp_coeff_obsolete_p = 1;
  153.     }
  154.     FFASE(3)
  155.     {
  156. CIRCOPY(input,thequeue,dec_end,NUPDATE*IDIM,QSIZE);
  157. pwf_adapter(input, pwf_z_coeff_next, pwf_p_coeff_next);
  158. pwf_z_coeff_obsolete_p = 1;
  159. pwf_p_coeff_obsolete_p = 1;
  160.     }
  161.     FFASE(3)
  162.     {
  163. iresp_vcalc(sf_coeff_next, pwf_z_coeff_next, pwf_p_coeff_next, 
  164.     imp_resp_next);
  165. shape_conv(imp_resp_next, shape_energy_next);
  166. shape_energy_obsolete_p = 1;
  167. imp_resp_obsolete_p = 1;
  168.     }
  169. }