www.pudn.com > AVS_M_ver10.rar > dec_wbplus.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2007 Audio Video Coding Standard, Part Ⅹ * * This software module was developed by AVS Audio sub-group * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ #include#include #include #include #include "../lib_amr/enc_if.h" #include "../lib_amr/dec_if.h" #include "../include/amr_plus.h" #include "../include/wbplus3gplib.h" extern const UWord8 block_size[]; static void copyright(void) { fprintf(stderr, "\n"); } static void usage(char *argv) { fprintf(stderr, "Usage: %s [-ff <3gp/raw> -fs ][-mono] [-limiter] -if -of -fer \n", argv); fprintf(stderr, "\n"); fprintf(stderr, "-ff file format used (default is 3gp)\n"); fprintf(stderr, "-fs frequency sampling\n"); fprintf(stderr, "-mono mono output \n"); fprintf(stderr, "-limiter avoids output clipping (recommended)\n"); fprintf(stderr, "-if input AMRWB+ bitstream file\n"); fprintf(stderr, "-of output audio WAV file\n"); fprintf(stderr, "-fer frame erasures file (0/1)"); fprintf(stderr, "\n"); } static float get_bitrate(DecoderConfig * 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; } } static void parsecmdline(int argc, char *argv[], char **input_filename, char **output_filename, char **fer_filename, DecoderConfig * conf) { conf->fs = 0; conf->mono_dec_stereo = 0; conf->limiter_on = 0; conf->fer_sim = 0; conf->FileFormat = F3GP; if (argc < 5) { usage(*argv); exit(EXIT_FAILURE); } argc--; argv++; while (argc > 0) { if (!strcmp(*argv, "-fs")) { argv++; argc--; conf->fs = atoi(*argv); } else if (!strcmp(*argv, "-ff")) { argv++; argc--; if (!strcmp(*argv, "3gp")) { conf->FileFormat = F3GP; } else { conf->FileFormat = FRAW; } } else if (!strcmp(*argv, "-mono")) { conf->mono_dec_stereo = 1; } else if (!strcmp(*argv, "-limiter")) { conf->limiter_on = 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, "-fer")) { argv++; argc--; *fer_filename = *argv; conf->fer_sim=1; } else { fprintf(stderr, "Unknown option %s\n", *argv); exit(EXIT_FAILURE); } argv++; argc--; } } static void select_fs(DecoderConfig * conf) { /* default sampling rate if undefined */ if (conf->fs == 0) { if (conf->extension == 0) conf->fs = 16000; else if (conf->fscale == 0) conf->fs = 24000; else conf->fs = 48000; } /* user specified sampling rate */ else { if (conf->extension == 0) { if (conf->fs != 16000) { fprintf(stderr, "Sampling rate not supported"); exit(EXIT_FAILURE); } } else { if (conf->fscale == 0) { if ((conf->fs != 16000) && (conf->fs != 24000) && (conf->fs != 8000)) { fprintf(stderr, "Sampling rate not supported"); exit(EXIT_FAILURE); } } else { if ((conf->fs!=44100) && (conf->fs!=48000)) { fprintf(stderr, "Sampling rate not supported"); exit(EXIT_FAILURE); } } } } } static void set_frame_length(DecoderConfig * conf, int *L_frame) { switch (conf->fs) { case 8000: *L_frame = L_FRAME8k; break; case 16000: *L_frame = L_FRAME16kPLUS; break; case 24000: *L_frame = L_FRAME24k; break; case 32000: *L_frame = L_FRAME32k; break; #ifdef FILTER_44kHz case 44100: *L_frame = L_FRAME44k; break; #endif #ifdef FILTER_48kHz case 48000: *L_frame = L_FRAME48k; break; #endif default: fprintf(stderr, "Sampling rate not supported"); exit(1); } } static void interleave(float *right, float *left, float *out, int length) { int i; for (i = length - 1; i >= 0; i--) { out[(i * 2) + 1] = right[i]; out[i * 2] = left[i]; } } static void simple_frame_limiter(float *signal, float *gain, int lg) { int i; int pos_start, pos_end; float amp, slope; float max_amp; float target_gain; max_amp = -1; pos_start = -1; for (i = 0; i < lg; i++) { amp = (float)fabs(signal[i]); if (amp > 32767.0f) { if (pos_start < 0) pos_start = i; pos_end = i; if (amp > max_amp) { max_amp = amp; } } } if (max_amp > 0) { target_gain = 32767.0f / max_amp; slope = (target_gain - *gain) / ((float) pos_start + 1.0f); for (i = 0; i < lg; i++) { if (i < pos_start + 1) *gain += slope; signal[i] *= *gain; } } else { if (*gain != 1.0) { slope = (1.0f - *gain) / ((float) lg); for (i = 0; i < lg; i++) { *gain += slope; signal[i] *= *gain; } } } } #ifdef PW_UPDATE float gamma1=0.91f; float gamma2=0.5f; float gamma3=0.2f; #endif void main(int argc, char *argv[]) { FILE *f_serial; /* File of serial bits for transmission */ FILE *f_syn; /* File of synthesis speech */ FILE *f_fer; /* File of frame errasures */ short speech16[L_FRAME48k * 2]; Decoder_State_Plus *st_d; void *stAmrwbDec; unsigned short serial[NBITS_MAX]; /* serial parameters. */ short bitsPerSample = 16; int bfi[4] = { 0, 0, 0, 0 }; Word16 bfiTemp;/* 坏帧指示器临时变量,用于帧错误隐藏 */ int L_frame; long frame, dataSize; float channel_right[4 * L_FRAME48k]; float channel_left[2 * L_FRAME48k]; float mem_down_right[2*L_FILT_DECIM_FS], mem_down_left[2*L_FILT_DECIM_FS]; int frac_down_right, frac_down_left; int fac_up, fac_down, nb_samp_fs; long fs_output; short nb_samp; short mode, extension; short st_mode; short num_channels; char *input_filename = ""; char *output_filename = ""; char *fer_filename= ""; short fst_switched; short old_st_mode; short fst; DecoderConfig conf; float left_limiter_gain; float right_limiter_gain; short i, j; short tfi = 0; float old_bitrate; f_serial = NULL; f_fer = NULL; left_limiter_gain = 1.0f; right_limiter_gain = 1.0f; copyright(); parsecmdline(argc, argv, &input_filename, &output_filename,&fer_filename, &conf); if(conf.FileFormat == F3GP) { Open3GP(&tfi, bfi, input_filename,0,&conf); } else { if ((f_serial = fopen(input_filename, "rb")) == NULL) { fprintf(stderr, "Error opening the input bitstream file %s.\n", input_filename); exit(EXIT_FAILURE); } ReadHeader(&tfi, bfi, conf.FileFormat, &(conf.extension), &(conf.mode), &(conf.st_mode), &(conf.fscale), 0, f_serial); rewind(f_serial); } /* In case of bad frame; hard initialization */ if((conf.fs == 16000 || conf.fs == 8000) && conf.mode == 14 ) { /* Force to wb */ conf.fscale = 0; conf.extension = 0; } else if (conf.mode == 14) { /* Force to wb+ if sampling rate desire is different than 16 or 8kHz */ conf.mode = 2; conf.fscale = 96; conf.extension = 1; } /* default sampling rate if undefined */ if (conf.fs == 0) { if (conf.extension == 0) conf.fs = 16000; else if (conf.fscale == 0) conf.fs = 24000; else { #ifdef FILTER_44kHz conf.fs = 44100; #endif #ifdef FILTER_48kHz conf.fs = 48000; #endif } } fs_output = conf.fs; fac_up = fac_down = 12; /* no oversampling by default */ frac_down_right = 0; frac_down_left = 0; if (conf.fscale != 0) { switch (conf.fs) { case 8000: fac_up = 2; conf.fs = 48000; break; case 16000: fac_up = 4; conf.fs = 48000; break; case 24000: fac_up = 6; conf.fs = 48000; break; case 32000: fac_up = 8; conf.fs = 48000; break; case 11025: fac_up = 3; conf.fs = 44100; break; case 22050: fac_up = 6; conf.fs = 44100; break; } set_zero(mem_down_right, 2*L_FILT_DECIM_FS); set_zero(mem_down_left, 2*L_FILT_DECIM_FS); } /* read the mode/fscale (1st frame) for initialization */ select_fs(&conf); set_frame_length(&conf, &L_frame); num_channels = 2; if ((conf.fscale == 0) && (conf.st_mode < 0) || (conf.extension == 0) || (conf.mono_dec_stereo)) num_channels = 1; /* Frame errasure simualtion */ if(conf.fer_sim) { if ((f_fer = fopen(fer_filename,"rt")) == NULL) { fprintf(stderr, "Error opening fer file %s.\n",fer_filename); exit(0); } } /* Open output wav file */ if ((f_syn = Wave_fopen(output_filename, "wb", &num_channels, &fs_output, &bitsPerSample, &dataSize)) == NULL) { fprintf(stderr, "Error opening output wav file %s.\n", output_filename); exit(0); } old_bitrate = get_bitrate(&conf); fprintf(stderr, "Decoding @ %6.2fkbps", get_bitrate(&conf)); /* Initialize decoders */ stAmrwbDec = D_IF_init(); st_d = malloc(sizeof(Decoder_State_Plus)); /* NEW_STEREO */ st_d->old_bitrate = old_bitrate; /* END_NEW_STEREO */ init_decoder_amrwb_plus(st_d, (int) num_channels, conf.fscale, 1); 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 * *--------------------------------------------------------------------------*/ frame = 0; tfi = (short)frame%4; old_st_mode = conf.st_mode; extension = conf.extension; mode = conf.mode; st_mode = conf.st_mode; fst = conf.fscale; while (1) { fst_switched = 0; fprintf(stderr, "Frames processed: %ld \r", frame/4); /* get next frame 4x20ms if AMR-WB+ or 1x20ms if AMR-WB */ if (conf.FileFormat == F3GP) { if(GetNextFrame3GP(&tfi, bfi, &extension,&mode,&st_mode,&fst,(void *)serial,0)) { break; } conf.mode = mode; conf.st_mode = st_mode; } else { if(!ReadRawFile(&tfi, bfi, &conf, &extension, &mode, &st_mode, &fst, f_serial, (void*) serial)) break; } if(conf.fer_sim) { if(conf.extension > 0) { /* …… 读取模拟坏帧模块插入(起始) ……*/ for(i=0;i<4;i++) { /*读取模拟坏帧文件,用于帧错误隐藏测试*/ fread(&bfiTemp, sizeof (Word16), 1, f_fer ); if(bfiTemp==0x6b21) bfi[i]=0;/* 好帧 */ else bfi[i]=1;/* 坏帧 */ } /* …… 读取模拟坏帧模块插入(结束) ……*/ } else { fscanf(f_fer,"%d",&bfi[tfi]); } } /* note that mode switching is only allowed within 80ms super-frames */ if (fst != conf.fscale && !fst_switched) { select_fs(&conf); set_frame_length(&conf, &L_frame); init_decoder_amrwb_plus(st_d, (int) num_channels, fst, 0); fst_switched = 1; } /* set new config */ if (((extension == 0) && (conf.extension == 1)) || ((extension == 1) && (conf.extension == 0))) { if (((mode >= 0 && mode <= 9) || mode == 15) && (conf.extension > 0)) { copy_decoder_state(st_d, stAmrwbDec, 1); } else if (((mode >= 0 && mode <= 8) || mode == 15) && (conf.extension == 0)) { copy_decoder_state(st_d, stAmrwbDec, 0); } conf.mode = mode; conf.extension = extension; } if (conf.extension > 0) { nb_samp = decoder_amrwb_plus((int)conf.mode, (short*)serial, bfi, L_frame, (int)num_channels, channel_right, channel_left, st_d, (int)fst, (int)conf.st_mode, conf.mono_dec_stereo, conf.fscale); frame +=4; } else { nb_samp = L_FRAME16k; D_IF_decode(stAmrwbDec, (unsigned char*)serial, speech16, bfi[tfi]? _bad_frame:_good_frame); for (j = 0; j < 320; j++) channel_right[ j] = speech16[j]; frame ++; } old_st_mode = conf.st_mode; if (num_channels == 2) { if (conf.limiter_on) { simple_frame_limiter(channel_right, &right_limiter_gain, nb_samp); simple_frame_limiter(channel_left, &left_limiter_gain, nb_samp); } nb_samp_fs = decim_fs(channel_right, nb_samp, channel_right, fac_up, mem_down_right, &frac_down_right); nb_samp_fs = decim_fs(channel_left, nb_samp, channel_left, fac_up, mem_down_left, &frac_down_left); /* interleave of left and right samples (stereo file format) */ interleave(channel_right, channel_left, channel_right, nb_samp_fs); writ_data(channel_right, 2 * nb_samp_fs, f_syn); } else { if (conf.limiter_on) { simple_frame_limiter(channel_right, &right_limiter_gain, nb_samp); } nb_samp_fs = decim_fs(channel_right, nb_samp, channel_right, fac_up, mem_down_right, &frac_down_right); writ_data(channel_right, nb_samp_fs, f_syn); } conf.fscale = fst; if (fst_switched) { set_frame_length(&conf, &L_frame); } fflush(f_syn); if (fabs(old_bitrate - get_bitrate(&conf)) > 0.0001) { old_bitrate = get_bitrate(&conf); if (old_bitrate != 0) fprintf(stderr, "Decoding @ %6.2fkbps\n", old_bitrate); else /* DTX frame return a bit rate of 0 kbps */ fprintf(stderr, "Decoding DTX\n"); } } Wave_fclose(f_syn, bitsPerSample); exit(EXIT_SUCCESS); }