📄 enc_wbplus.c
字号:
#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 + -