⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enc_wbplus.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
   int i;
   float temp;

   for (i = 0; i < n; i++)
   {
      temp = *in++;
      if (temp >= 0.0)
         temp += 0.5;
      else
         temp -= 0.5;
      if (temp > 32767.0)
         temp = 32767.0;
      if (temp < -32767.0)
         temp = -32767.0;
      *out++ = (short) temp;
   }
}
static void deinterleave(float *buf, float *left, float *right, int length)
{
   int i;

   for (i = 0; i < length; i++)
   {
      left[i] = buf[i * 2];
      right[i] = buf[(i * 2) + 1];
   }

}

int get_config(FILE *fp, float t[])
{
  int OK = 0;
  if (!fp || feof(fp))
    return 0;
  
  /*
    read from config file the following items
    time  extension  mode_index fscale 
    time (in seconds) must always be above 0.0, 0.000001 is OK
  */
  while (!OK && !feof(fp)) {
    char s[100], *sp;
    int ix  = 0;
    t[0] = 0.0;
    fgets(s,99,fp);
    sp = strtok(s," \t");
    while (sp && ix < 4) 
    {
      t[ix++] = (float)atof(sp);

      sp = strtok(0," \t");
    }
    if (t[0] != 0.0) {
      return 1;
    }
  }
  return 0;
}
void close_wbp(Coder_State_Plus *st, Word16 UseCaseB)
{

  if(st->stClass != NULL && UseCaseB > 0 )
  {
    free(st->stClass);
    st->stClass = NULL;
  }
  if(st->vadSt != NULL && UseCaseB > 0 )
    wb_vad_exit(&st->vadSt);
 

  if(st != NULL)
  {
    free(st);
    st = NULL;
  }

}
void main(int argc, char *argv[])
{
   FILE *f_speech;              /* File of speech data                   */
   FILE *f_serial;              /* File of serial bits for transmission  */
   short speech16[L_FRAME_FSMAX * 2];
   short serial[NBITS_MAX];     /* serial parameters.                    */
   unsigned char serialAmrwb[NBITS_MAX];        /* serial parameters.                    */
   float channel_right[4 * L_FRAME_FSMAX];
   float channel_left[2 * L_FRAME_FSMAX];
   float mem_up_right[2*L_FILT_OVER_FS], mem_up_left[2*L_FILT_OVER_FS];
   int frac_up_right, frac_up_left;
   int fac_up, fac_down, nb_samp_fs;
   Coder_State_Plus *st = NULL;
   short numOfChannels, bitsPerSample;
   void *stAmrwbEnc = NULL;
   int nb_bits = 0;
   int i, lg, L_frame;
   long frame, samplingRate, dataSize;
   int L_next, L_next_st;
   int nb_samp, nb_hold;
   short /*codec_mode,*/ mode, extension;
   short serial_size = 0;
   char *input_filename;
   char *output_filename;
   int st_mode, old_st_mode;
   EncoderConfig conf;
   short fst;
   float rate;
   char FileFormatType[25];

   FILE *f_config = 0;
   float rec_time = 0.0;
   float config_file_time = 0.0;
   float t[4]; /* time,conf.extension,conf.mode_index,conf.fscale */
   float old_bitrate;
   char *config_filename;

   int Processed_sample = 0;
   int nb_sample_to_process = 0;

   f_serial = NULL;
   /* Initializations */
   input_filename = NULL;
   output_filename = NULL;
   config_filename = NULL;

   copyright();
   parsecmdline(argc, argv, &input_filename, &output_filename, &config_filename, &conf, &rate);

   /* Open input wave file */
   if ((f_speech =
        Wave_fopen(input_filename, "rb", &numOfChannels, &samplingRate,
                   &bitsPerSample, &dataSize)) == NULL)
   {
      fprintf(stderr, "Error opening the input file %s.\n", input_filename);
      exit(EXIT_FAILURE);
   }
   /* Simple interface */
   if (rate != -1.0)
   {
      if(conf.st_mode == -2 || numOfChannels == 1)
      {
          GetRate(&conf, rate, MonoRate, 3*18);
      }
      else
      {
          GetRate(&conf, rate, StereoRate, 3*26);
      }

   }
   /* test if it is stereo input */
   if ((conf.st_mode >= 0) && (numOfChannels != 2))
   {
      fprintf(stderr, "Input file %s must be stereo\n", input_filename);
      exit(EXIT_FAILURE);
   }
   /* test if it is 16 bits PCM */
   if (bitsPerSample != 16)
   {
       fprintf(stderr, "Input file %s must be 16 bits encoded\n",
              input_filename);
      exit(EXIT_FAILURE);
   }

   if (conf.FileFormat == F3GP)
   {
       strcpy(FileFormatType,"3gp File Format");
       if(conf.bc == 1) 
       {
          /* create backward compatible file */
          Create3GPAMRWB();
       }
       else 
       {
          Create3GPAMRWBPlus();
       }
   }
   else /* raw data */
   {
        strcpy(FileFormatType,"Raw File Format");

        /* Open the output bitstream file */
        if ((f_serial = fopen(output_filename, "wb")) == NULL) 
        {
	        fprintf(stderr, "Error opening output bitstream file %s.\n",output_filename);
	        exit(EXIT_FAILURE);
        }

   }

   if ((conf.extension == 0) && (samplingRate != 16000))
   {
      fprintf(stderr, "AMR-WB work only at 16kHz\n");
      exit(EXIT_FAILURE);
   }

   fac_up = fac_down = 12;     /* no oversampling by default */
   frac_up_right = 0;
   frac_up_left = 0;

   if (conf.fscale != 0)
   {
     switch (samplingRate) {
     case 8000:
       fac_down = 2;
       samplingRate  = 48000;
       break;
     case 16000:
       fac_down = 4;
       samplingRate  = 48000;
       break;
     case 24000:
       fac_down = 6;
       samplingRate  = 48000;
       break;
     case 32000:
       fac_down = 8;
       samplingRate  = 48000;
       break;
     case 11025:
       fac_down = 3;
       samplingRate  = 44100;
       break;
     case 22050:
       fac_down = 6;
       samplingRate  = 44100;
       break;
     }
     set_zero(mem_up_right, 2*L_FILT_OVER_FS);
     set_zero(mem_up_left, 2*L_FILT_OVER_FS);
   }

  /* Set default buffer lengths */
   set_frame_length(samplingRate, conf.fscale, &L_frame, &L_next, &L_next_st);
   st = malloc(sizeof(Coder_State_Plus));
   memset(serial, 0x42, NBITS_MAX * sizeof(short));
   
   old_bitrate = get_bitrate(&conf);
   fprintf(stderr, "%s\nEncoding @ %6.2fkbps",FileFormatType,  get_bitrate(&conf));
   
   init_coder_amrwb_plus(st, (int) numOfChannels, conf.fscale,
                         conf.use_case_mode, 1);
   stAmrwbEnc = E_IF_init();

   /* number of sample per channel to read from file */
   nb_samp_fs = ((L_frame*fac_down)+frac_up_right) / fac_up;

   lg = read_data(f_speech, channel_right, (numOfChannels * nb_samp_fs));
   if (lg != (numOfChannels * nb_samp_fs))
   {
      printf("Error: file too short!\n");
      exit(EXIT_FAILURE);
   }
   if (numOfChannels == 2)
   {
      deinterleave(channel_right, channel_left, channel_right, nb_samp_fs);

      over_fs(channel_left, channel_left, L_frame,
              fac_down, mem_up_left, &frac_up_left);
   }
   over_fs(channel_right, channel_right, L_frame,
           fac_down, mem_up_right, &frac_up_right);
   
   if (conf.extension > 0)
   {
      nb_samp =
         coder_amrwb_plus_first(channel_right, channel_left, numOfChannels,
                                L_frame,
                                (numOfChannels == 1) ? L_next : L_next_st,
                                conf.fscale, st);
   }
   else
   {
      moveAndRound(channel_right, speech16, 320);
      E_IF_encode_first(stAmrwbEnc, speech16);
      nb_samp = 320;
   }
   fprintf(stderr, "\n --- Running ---\n");


  /*---------------------------------------------------------------------------*
	* Loop for every analysis/transmission frame.                               *
	*   -New L_FRAME_PLUS data are read. (L_FRAME_PLUS = number of speech data per frame) *
	*   -Conversion of the speech data from 16 bit integer to real              *
	*   -Call coder_wb to encode the speech.                                    *
	*   -The compressed serial output stream is written to a file.              *
	*   -The synthesis speech is written to a file                              *
	*--------------------------------------------------------------------------*/
   mode = conf.mode;
   extension = conf.extension;
   old_st_mode = st_mode = conf.st_mode;

   frame = 0;
   fst = conf.fscale;
   if (config_filename != 0) {
      if(fac_down != 12)
      {
         fprintf(stderr, "Must have 16kHz (to switch amr-wb -> wb+ (mode 10@13))\n"
         "or 48kHz (wb+) input\n\n");
         exit(EXIT_FAILURE);
      }
      if(conf.mode_index < 16 && samplingRate != 16000)
      {
        fprintf(stderr, "Must have a 16kHz input file (to switch amr-wb -> wb+ (mode 10@13))\n");
        exit(EXIT_FAILURE);
      }
      if( numOfChannels == 1)
      {
        fprintf(stderr, "** Warning **\nDo not switch to stereo... \nyou have mono input\n\n");
      }
      f_config = fopen(config_filename,"r");
      if (!f_config) {
        fprintf(stderr, "Error opening config file %s.\n",config_filename);
        exit(EXIT_FAILURE);
      }
      while (!get_config(f_config,t) && !feof(f_config)) {
         printf("%2.3f \n",t[0]);
      }
      config_file_time = t[0];
      rec_time = 0;
   }
  nb_sample_to_process = dataSize*numOfChannels - lg;
  Processed_sample += nb_samp;
   
  while (Processed_sample < nb_sample_to_process || frame == 0)
   {
      fprintf(stderr, " Frames processed: %ld    \r", frame);
      frame++;

      if (f_config) 
      {
         if (rec_time >= config_file_time && (t[0] != -1.0) && !feof(f_config)) 
         {  
            short tmp_mode_index;
            extension = (short)(t[1]+0.01); 
            tmp_mode_index = (short)(t[2]+0.01); 
            if (extension == 0) 
            {
               mode  = tmp_mode_index;
               st_mode = -1;
               conf.mode = tmp_mode_index;
               conf.st_mode = -1;
               conf.mode_index = tmp_mode_index;
            } 
            else 
            {
                conf.mode_index = tmp_mode_index;
                get_raw_3gp_mode(&(conf.mode), &(conf.st_mode),conf.mode_index, extension );
            }
            fst = (short)(t[3]*FSCALE_DENOM+0.5);

            get_isf_index(&fst);      /* Use "fscale from index" */
            
            while (!get_config(f_config,t)&& !feof(f_config)) {}
            config_file_time = t[0];
         }
      }
      if (fst != conf.fscale)
      {
         conf.fscale = fst;
         init_coder_amrwb_plus(st, (int) numOfChannels, conf.fscale,
                           conf.use_case_mode, 0);
         set_frame_length(samplingRate, conf.fscale, &L_frame, &L_next,
                      &L_next_st);
         conf.fscale_index = get_isf_index(&(conf.fscale));      /* Use "fscale from index" */

      }

      nb_hold = L_frame - nb_samp;

      mvr2r(channel_right + nb_samp, channel_right, nb_hold);
      mvr2r(channel_left + nb_samp, channel_left, nb_hold);

      /* number of sample per channel to read from file */
      nb_samp_fs = ((nb_samp*fac_down)+frac_up_right) / fac_up;

      lg =
         read_data(f_speech, channel_right + nb_hold,
                   (numOfChannels * nb_samp_fs));  

      if (numOfChannels == 2)
      {
         deinterleave(channel_right + nb_hold, channel_left + nb_hold,
                      channel_right + nb_hold, nb_samp_fs);

         over_fs(channel_left + nb_hold, channel_left + nb_hold, nb_samp,
                 fac_down, mem_up_left, &frac_up_left);
      }
      over_fs(channel_right + nb_hold, channel_right + nb_hold, nb_samp,
              fac_down, mem_up_right, &frac_up_right);

      if (((extension == 0) && (conf.extension == 1))
          || ((extension == 1) && (conf.extension == 0)))
      {
         if (((mode >= 0 && mode <= 9) || mode == 15) && (conf.extension > 0))
         {
            copy_coder_state(st, stAmrwbEnc, 1, conf.use_case_mode);
         }
         else if ((mode >= 0 && mode <= 8) && (conf.extension == 0))
         {
            copy_coder_state(st, stAmrwbEnc, 0, conf.use_case_mode);
         }
         /* conf.mode = mode; */
         conf.extension = extension;
      }
      if (conf.extension > 0)
      {
         /* update needed if mode changes */
         nb_bits = get_nb_bits(conf.extension, conf.mode, conf.st_mode);
         if (numOfChannels == 2)
         {
            nb_samp =
               coder_amrwb_plus_stereo(channel_right, channel_left,
                                       conf.mode, L_frame,
                                       serial, st, conf.use_case_mode,
                                       conf.fscale, conf.st_mode);
         }
         else
         {
            nb_samp =
               coder_amrwb_plus_mono(channel_right, 
                                    conf.mode,
                                     L_frame, serial, st, conf.use_case_mode,
                                     conf.fscale 
                                     );
         }
         old_st_mode = conf.st_mode;

         if(conf.FileFormat == F3GP)
         {
            WriteSamplesAMRWBPlus( conf,serial, nb_bits);
         }
         else
         {
             for(i = 0;i < 4; i++)
             {
                WriteHeader(conf, (short)nb_bits, (short)i, f_serial);  
                WriteBitstreamPlus(conf, (short)nb_bits, (short)i, serial, f_serial);    
             }
         }
      }
      else
      {
         for (i = 0; i < 4; i++)
         {
            moveAndRound(&channel_right[i * 320], speech16, 320);
            serial_size =
               (short) E_IF_encode(stAmrwbEnc, (Word16) conf.mode, speech16,
                                   serialAmrwb, conf.allow_dtx);
            if(conf.FileFormat == F3GP)
            {
                WriteSamplesAMRWBPlus(conf,serialAmrwb, serial_size);
            }
            else
            {
                WriteHeader(conf, (short)serial_size, (short)i, f_serial);  
                WriteBitstream(conf, (short)serial_size, (short)i, serialAmrwb, f_serial);    
            }
         }
         nb_samp = 4 * L_FRAME16k;

      }
      if (fabs(old_bitrate-get_bitrate(&conf)) > 0.00001) {
         old_bitrate = get_bitrate(&conf);
         fprintf(stderr, "Rectime: %2.3f Encoding @ %6.2fkbps\n", rec_time, old_bitrate);
      }
      rec_time += nb_samp/((float)(samplingRate));
      Processed_sample += (nb_samp_fs*numOfChannels);

   }


   if(conf.FileFormat == F3GP)
   {
      Close3GP(output_filename);
   }
   else
   {
      fclose(f_serial);
   }
   Wave_fclose(f_speech, bitsPerSample);

   if(stAmrwbEnc != NULL)
       E_IF_exit(stAmrwbEnc);

   close_wbp(st, conf.use_case_mode);  


   exit(EXIT_SUCCESS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -