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

📄 enc_wbplus.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../lib_amr/enc_if.h"
#include "../lib_amr/dec_if.h"
#include "../include/amr_plus.h"
#include "../include/wbplus3gplib.h"

void copyright(void)
{
   fprintf(stderr, "\n");
   fprintf(stderr, "\n");
}

static void usage(char *argv)
{
   fprintf(stderr,
           "Usage: %s -rate <Bit rate> [-mono] | -mi <mode index> [-isf <factor>] [-lc] [-dtx] -ff <3gp/raw> -if <infile.wav> -of <outfile.wb+>\n",
           argv);
   fprintf(stderr, "\n");
   fprintf(stderr, "-rate   Bit rate between 6-36 kbps mono or 7-48 kbps stereo \n");
   fprintf(stderr, "-mono   Force mono encoding \n");
   fprintf(stderr, "\n");
   fprintf(stderr, "\n");
   fprintf(stderr, "-mi     Mode Index (0..15  -> AMR WB\n                  16..47 -> AMR WB+) (see ts 26.290 Table 25) \n");
   fprintf(stderr,
                   "-isf    Internal Sampling Frequency (0.5... 1.5, default is 1.0).\n");
   fprintf(stderr, "\n");
   fprintf(stderr, "\n");

   fprintf(stderr, "-lc     low complexity (for AMR-WB+ modes).\n");
   fprintf(stderr,
                   "-dtx    enables VAD/DTX functionality (for AMR-WB modes).\n");
   fprintf(stderr, "\n");
   fprintf(stderr, "-ff     3gp File Format / raw format\n");
   fprintf(stderr, "-if     input audio WAV file.\n");
   fprintf(stderr, "-of     output AMRWB+ 3gp file.\n");
	fprintf(stderr, "-cf     configuration file\n");
   fprintf(stderr, "\n");
}
float get_bitrate(EncoderConfig * conf)
{
   if (conf->fscale != 0)
   {
      return (float) (get_nb_bits(conf->extension, conf->mode, conf->st_mode) * conf->fscale) / (80.0f *
                                                           FSCALE_DENOM);
   }
   else
   {
      return (float) get_nb_bits(conf->extension, conf->mode, conf->st_mode) / 80.0f;
   }
}

int get_core_mode(float bitrate)
{
   float min_dist = 1e16f;
   int mode;
   int i;
   mode = 0;
   for (i = 0; i < 8; i++)
   {
      if (fabs(bitrate - (float) (NBITS_CORE[i] + NBITS_BWE) / 80.0f) <
          min_dist)
      {
         min_dist = (float)fabs(bitrate - (float) (NBITS_CORE[i] + NBITS_BWE) / 80.0f);
         mode = i;
      }
   }
   return mode;
}

int get_stereo_mode(float bitrate)
{
   float min_dist = 1e16f;
   int mode;
   int i;
    
   if (bitrate == 0)
      return -1;

   mode = 0;
   for (i = 0; i < 16; i++)
   {
      if (fabs(bitrate - (float) (StereoNbits[i] + NBITS_BWE) / 80.0f) <
          min_dist)
      {

         min_dist =
            (float)fabs(bitrate - (float) (StereoNbits[i] + NBITS_BWE) / 80.0f);
         mode = i;
      }
   }
   return mode;
}

void get_raw_3gp_mode(short *mode, short *st_mode, short raw_3gp_mode ,short extension )
{ 
    short index;
    /* Mono mode only */
    if( raw_3gp_mode <= 8 )
    {
        if (extension != 0)
        {
            fprintf(stderr, "-isf is not supported by amr_wb\n");
            exit(EXIT_FAILURE);
        }

        *mode = raw_3gp_mode;
        *st_mode = -1;
    }
    else if(raw_3gp_mode== 10)    /* 14m */
    {
        *mode = 2;
        *st_mode = -1;
    }
    else if (raw_3gp_mode== 11) /* 18s */
    {
        *mode = 2;
        *st_mode = 6;
    }
    else if (raw_3gp_mode== 12)   /* 24m*/
    {
        *mode = 7;
        *st_mode = -1;
    }
    else if (raw_3gp_mode == 13)    /*24s*/
    {
        *mode = 5;
        *st_mode = 7;
    }  
    else if(raw_3gp_mode >= 16 && raw_3gp_mode < 24)
    {
        *mode =   raw_3gp_mode - 16;
        *st_mode = -1;
    }
    else if(raw_3gp_mode >= 24 && raw_3gp_mode <= 47)
    {
        index = raw_3gp_mode - 24;
        *mode = miMode[2*index];
        *st_mode = miMode[2*index+1];
    }
    else
    {
        printf("Invalid Mode Index\n");
        exit(EXIT_FAILURE);
    }

}

short get_isf_index(short *fscale)
{ 
  short index, i ;
  float dist = 512.0f, ftmp;

  index = 0;

  /* Mono mode only */
  for (i = 0;i < 14; i++)
  {
    ftmp = (float)fabs(*fscale-isfIndex[i]);
    if(ftmp < dist)
    {
      dist = ftmp;
      index = i;
    }

  }
  *fscale = isfIndex[index];
  return index;
}

static void parsecmdline(int argc,
                         char *argv[],
                         char **input_filename,
                         char **output_filename, 
                         char **config_filename, 
                         EncoderConfig * conf,
                         float *rate)
{
   int simple_mode,amr_wb, amr_wbp_carac, mi_mode;
   float srate;
   float mrate;

   if (argc == 1)
   {
      
      usage(argv[0]);
      
      exit(EXIT_FAILURE);
   }
   
   conf->extension    = 0;
   conf->allow_dtx    = 0;
   conf->use_case_mode= USE_CASE_A;
   conf->fscale       = 0;
   conf->mode         = -1;
   conf->st_mode      = -1;
   conf->FileFormat   = F3GP;
   conf->mode_index   = -1;
   conf->fscale_index = 0;    
   conf->bc = 0;


   simple_mode = 0;
   amr_wb = 0;
   mi_mode = 0;
   amr_wbp_carac = 0;

   mrate = -1;
   srate = -1;
   *rate = -1;
   argc--;
   argv++;
   
   
   while (argc > 0)
   {
      
      if (!strcmp(*argv, "-mi"))
      {  

         if (simple_mode)
         {
            fprintf(stderr, "Can't use -rate with -mi\n");
            exit(EXIT_FAILURE);
         }
         
         mi_mode = 1;
         argv++;
         argc--;
         
         conf->mode_index = (short)atoi(*argv);
         if (conf->mode_index < 0 || conf->mode_index > 47)
         {
            fprintf(stderr, "Unknown Mode Index (see TS 26.290 Table 25)\n");
            exit(EXIT_FAILURE);
         }
         else if (conf->mode_index == 9 || conf->mode_index == 14 || conf->mode_index == 15)
         {
            fprintf(stderr, "Mode Index %d is reserved (see TS 26.290 Table 21)\n", conf->mode_index);
            exit(EXIT_FAILURE);  
         }
         else
         {
            if ( (conf->mode_index >= 0) &&  (conf->mode_index <= 8) ) /* amr_wb modes */
            {
               get_raw_3gp_mode(&(conf->mode), &(conf->st_mode),(short) atoi(*argv), conf->extension = 0);
               amr_wb = 1;
            }
            else if ( (conf->mode_index >= 10) && (conf->mode_index <= 13) )  /* WB+ tested modes */    
            {
               get_raw_3gp_mode(&(conf->mode), &(conf->st_mode),(short) atoi(*argv), conf->extension = 0);
               conf->extension = 1;
               amr_wbp_carac = 1;
            }
            else
            {
               conf->extension = 1;   
               get_raw_3gp_mode(&(conf->mode), &(conf->st_mode),conf->mode_index, conf->extension );

               if(conf->fscale == 0)
               {
                 conf->fscale = FSCALE_DENOM;
                 conf->fscale_index = 8;   
               }
               
            }
            
         }
      }
      else if (!strcmp(*argv, "-isf"))
      {
         if (simple_mode)
         {
            fprintf(stderr, "Can't use -rate with -isf\n");
            exit(EXIT_FAILURE);
         }
         if (amr_wb)
         {
            fprintf(stderr, "-isf is not supported by amr_wb\n");
            exit(EXIT_FAILURE);
         }
         argv++;
         argc--;
         
         mi_mode = 1;               /* -isf is only allow with -mi */
         conf->extension = 1;
         if ((atof(*argv) >= 0.5) && (atof(*argv) <= 1.5))
         {
            conf->fscale = (short) ((atof(*argv) * FSCALE_DENOM) + 0.5f);
            /* force scale to be an even number */
            conf->fscale = (conf->fscale >> 1) << 1;
            /* limit the scale factor */
            if (conf->fscale > FAC_FSCALE_MAX)
            {
               conf->fscale = FAC_FSCALE_MAX;
            }
            if (conf->fscale < FAC_FSCALE_MIN)
            {
               conf->fscale = FAC_FSCALE_MIN;
            }
            conf->fscale_index = get_isf_index(&(conf->fscale));      /* Use "fscale from index" */
         }
         else
         {
            fprintf(stderr, "Unknown Inernal Sampling Frequency factor\n");
            exit(EXIT_FAILURE);
         }
      }
      else if (!strcmp(*argv, "-rate"))
      {
        if(mi_mode)
        {
          fprintf(stderr, "Can't use -rate with -mi or -isf \n");
          exit(EXIT_FAILURE);
        }
        argv++;
        argc--;
        simple_mode = 1;
        *rate = (float)atof(*argv);
        conf->extension = 1;
        if(*rate < 6.0 || *rate > 48.0) 
        {
          fprintf(stderr, "Minimum rate is 6.0kbps and maximum rate is 48.0 kbps\n");
          exit(EXIT_FAILURE);
        }
      }
      else if (!strcmp(*argv, "-mono"))
      {
          conf->st_mode = -2;  /* indicate mono is forced */
          if(*rate > 36.0) 
          {
             fprintf(stderr, "Maximum mono rate is 36.0 kbps\n");
             exit(EXIT_FAILURE);
          }
      }
      else if (!strcmp(*argv, "-lc"))
      {
         conf->use_case_mode = USE_CASE_B;
      }
      else if (!strcmp(*argv, "-dtx"))
      {
         conf->allow_dtx = 1;
      }
      else if (!strcmp(*argv, "-bc"))
      {
         conf->bc = 1;
      }
      else if (!strcmp(*argv, "-if"))
      {
         argv++;
         argc--;
         *input_filename = *argv;
      }
      else if (!strcmp(*argv, "-of"))
      {
         argv++;
         argc--;
         *output_filename = *argv;
      } 
		else if (!strcmp(*argv,"-cf")) {
			argv++;
			argc--;
         *config_filename = *argv;
      }
      else if (!strcmp(*argv, "-ff"))
      {
         argv++;
         argc--;
         if(!strcmp(*argv, "raw"))
         {
            conf->FileFormat = FRAW;
         }
         else
         {
            conf->FileFormat = F3GP;
         }
      }
      else
      {
         fprintf(stderr, "Unknown option %s\n", *argv);
         exit(EXIT_FAILURE);
      }
      argv++;
      argc--;
     }
     if (amr_wbp_carac && conf->fscale != 0)
     {
        fprintf(stderr, "-isf is not supported with AMR WB caracterized modes\n");
        exit(EXIT_FAILURE);
     }
     if (conf->st_mode == -2 && simple_mode != 1)
     {
        fprintf(stderr, "Choose right Mode Index to encode mono File\n-mono option is only supported with -rate\n");
        exit(EXIT_FAILURE);
     }


}

static void set_frame_length(int samplingRate,
                             int fscale,
                             int *L_frame, int *L_next, int *L_next_st)
{
   if (fscale != 0)
   {
      switch (samplingRate)
      {
#ifdef FILTER_48kHz
      case 8000:
      case 16000:
      case 24000:
      case 32000:
      case 48000:
        *L_frame = 2 * L_FRAME48k;
        break;
#endif
#ifdef FILTER_44kHz
      case 11025:
      case 22050:
      case 44100:
        *L_frame = 2 * L_FRAME44k;
        break;
#endif
      default:
         fprintf(stderr, "error in sampling frequency.  choice of filter are: \n");
#ifdef FILTER_44kHz
         fprintf(stderr, "     11, 22, 44 kHz \n");
#endif
#ifdef FILTER_48kHz
         fprintf(stderr, "     8, 16, 24, 32, 48 kHz \n");
#endif
         exit(EXIT_FAILURE);
         break;
      }
   }
   else {
      switch (samplingRate)
      {
      case 8000:
         *L_frame = L_FRAME8k;
         *L_next = L_NEXT8k;
         *L_next_st = L_NEXT_ST8k;
         break;
      case 16000:
         *L_frame = L_FRAME16kPLUS;
         *L_next = L_NEXT16k;
         *L_next_st = L_NEXT_ST16k;
         break;
      case 24000:
         *L_frame = L_FRAME24k;
         *L_next = L_NEXT24k;
         *L_next_st = L_NEXT_ST24k;
         break;
      default:
         fprintf(stderr, "error in sampling freq: without fsratio(isf) only 8, 16 or 24 kHz are allowed\n");
         exit(EXIT_FAILURE);
         break;
      }
   }

}

static void GetRate(EncoderConfig *conf,float rate, const short *TableRate, short lenght)
{
  short index, i ;
  float dist = 512.0f, ftmp;

  index = 0;
  /* Mono mode only */
  for (i = 0;i < lenght; i+=3)
  {
    ftmp = (float)fabs(rate*2 - TableRate[i]);
    if(ftmp < dist)
    {
      dist = ftmp;
      index = i;
    }
  }
  conf->mode_index = TableRate[index+1];
  conf->fscale_index = TableRate[index+2];
  get_raw_3gp_mode(&conf->mode, &conf->st_mode, conf->mode_index, conf->extension);
  conf->fscale = isfIndex[conf->fscale_index];
}

static void moveAndRound(float *in, short *out, int n)
{

⌨️ 快捷键说明

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