📄 aac_qc.c
字号:
/* $Id: aac_qc.c,v 1.29 1999/07/22 15:52:19 purnhage Exp $ *//***********This software module was originally developed byDolby Laboratoriesand edited byTakashi Koike (Sony Corporation) Mikko Suonio (Nokia)in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC13818-7, 14496-1, 2 and 3. This software module is an implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of theMPEG-2NBC/MPEG-4 Audio standards free license to this software moduleor modifications thereof for use in hardware or software productsclaiming conformance to the MPEG-2 NBC/MPEG-4 Audio standards. Thoseintending to use this software module in hardware or software productsare advised that this use may infringe existing patents. The originaldeveloper of this software module, the subsequenteditors and their companies, and ISO/IEC have no liability for use ofthis software module or modifications thereof in animplementation. Copyright is not released for non MPEG-2 NBC/MPEG-4Audio conforming products. The original developer retains full right touse the code for the developer's own purpose, assign or donate the code to athird party and to inhibit third party from using the code for nonMPEG-2 NBC/MPEG-4 Audio conforming products. This copyright noticemust be included in all copies or derivative works. Copyright 1996. ***********//******************************************************************** // filename : nbc_qc.c/ project : MPEG-2 NBC/ author : SNL, Dolby Laboratories, Inc/ date : November 15, 1996/ contents/description : slow rate/distortion quantizer, / huffman coding, bit packing/ /*******************************************************************/ #include <stdio.h> /* moved here HP 980211 */#include <math.h>#include <float.h>#include "block.h" /* handler, defines, enums */#include "buffersHandle.h" /* handler, defines, enums */#include "concealmentHandle.h" /* handler, defines, enums */#include "interface.h" /* handler, defines, enums */#include "mod_bufHandle.h" /* handler, defines, enums */#include "reorderspecHandle.h" /* handler, defines, enums */#include "resilienceHandle.h" /* handler, defines, enums */#include "tf_mainHandle.h" /* handler, defines, enums */#include "bitstreamStruct.h" /* structs */#include "nok_ltp_common.h" /* structs */#include "obj_descr.h" /* structs */#include "tf_mainStruct.h" /* structs */#include "common_m4a.h" #include "bitstream.h"#include "nttNew.h"#include "tf_main.h"#include "nok_bwp_enc.h"#include "nok_ltp_enc.h"#include "tns3.h"#include "aac_qc.h"#include "bitmux.h"static int table_choice = 5; /* CHOOSE HERE BETWEEN TABLES 4 or 5 */static int huffman_code_table[13][1090][4];static int qdebug;static double pow_quant[9000];/* quantizes each scalefactor band separately, in a very SLOW algorithm. But, it does work, by incrementing (by one) the scalefactor in the corresponding scalefactor band with the largest ratio of error energy to allowed distortion. There are both rate and distortion loops currently implemented. Again, this algorithm has NOT been modified for speed. With more time, the rate/distortion loops can be sped up. --SNL 11/15/96 *//* tf_encode_spectrum now correctly outputs the amount of bits written to the bitstream, along with accurately keeping a bit count in the quantizer loop. --SNL 11/8/96*//* This code sucessfully implements grouping. To test different versions of grouping, change the following variables near the top of tf_encode_spectrum_nbc(): window_group_length[8] and num_window_groups. An example of this grouping could be: (currently used) int window_group_length[8] = {3,1,2,1,1}; num_window_groups = 5; This translates to there being five groups of short windows. The first group contains three short windows, the second window contains one, etc. November 1, 1996*//* This quantizer / noiseless coder is a work in progress. Currently, it supports only long or only short block modes. The quantizer is a uniform quantizer that implements only the rate quantization loop, and not yet the distortion quantization loop. Grouping is not yet supported, so during short blocks, the default implementation is each of the eight short blocks are individual groups. The noiseless coding section is fully operational. The output of this code is a NBC, CD compliant bitstream. This code also allows you to switch between two different huffman codebooks, which I'll call RM4 and CD codebooks, received both from AT&T on different dates. If table_choice == 4, then you choose to use the all signed, RM4 codebooks. If table_choice == 5, then the CD codebooks will be loaded instead. Both of these codebooks have been tested sucessfully with their respective decoders. September 24, 1996*//* RM4 has tables with the following characteristics: (they're all signed tables) ---> book signed/unsigned range values_in_codebook dimension 1 signed +/- 1 81 4 2 signed +/- 1 81 4 3 signed +/- 2 625 4 4 signed +/- 2 625 4 5 signed +/- 4 81 2 6 signed +/- 4 81 2 7 signed +/- 7 225 2 8 signed +/- 7 225 2 9 signed +/- 12 625 2 10 signed +/- 12 625 2 11 signed +/- 16 1089 2 RM5 has tables with the following characteristics: (they're signed and unsigned) ---> book signed/unsigned range values_in_codebook dimension 1 signed +/- 1 81 4 2 signed +/- 1 81 4 3 unsigned 0,1,2 81 4 4 unsigned 0,1,2 81 4 5 signed +/- 4 81 2 6 signed +/- 4 81 2 7 unsigned 0...7 64 2 8 unsigned 0...7 64 2 9 unsigned 0...12 169 2 10 unsigned 0...12 169 2 11 unsigned 0...16 289 2*/int pns_sfb_start = 1000; /* lower border for Perceptual Noise Substitution (off by default) */void tf_init_encode_spectrum_aac( int qc_select, int debugLevel ){ FILE *fpout; short tmpc[4]; unsigned int j; int *huff_ptr= &(huffman_code_table[0][0][0]); qdebug = debugLevel; /* This function reads either one of the two set of huffman codebook tables into huff[][][]. */ if (table_choice == 5) { /* read the data in from file (used scan_huff_att3.c to read in rm5huf.txt from ascii)*/ if ((fpout = fopen("../tables_enc/rm5hufbook","rb")) == NULL){ if ((fpout = fopen("./tables_enc/rm5hufbook","rb")) == NULL){ CommonExit(-1,"\ncannot open rm5hufbook"); } } } if ((table_choice != 4) && (table_choice != 5)){ CommonExit(-1,"\nInvalid value of table_choice=%d, please choose either 4 or 5\n",table_choice); } for (j=0;j<sizeof(huffman_code_table)/sizeof(huffman_code_table[0][0][0]) ;j++){ tmpc[3] = getc(fpout); tmpc[2] = getc(fpout); tmpc[1] = getc(fpout); tmpc[0] = getc(fpout); *huff_ptr++ = (tmpc[0]<<0)+(tmpc[1]<<8)+(tmpc[2]<<16)+(tmpc[3]<<24); } /* THIS IS NOT PROTABLE !!: */ /* i = fread(huff,sizeof(int),13*1090*4,fpout); */ fprintf(stderr,"\nread %d huffman codebook values \n",j); for (j=0;j<9000;j++){ pow_quant[j]=pow((double)j, ((double)4.0/(double)3.0)); }}void debugPrint( int nr_of_sfb, double *ratio, double *energy, double *allowed_dist, double *error_energy, int *scale_factor, int common_scalefac){ int sb; fprintf(stderr,"\nratios :"); for (sb=0; sb<nr_of_sfb; sb++){ fprintf(stderr,"%6.1f|",10*log10(ratio[sb]+1e-15)); } fprintf(stderr,"\nenrgy :"); for (sb=0; sb<nr_of_sfb; sb++){ fprintf(stderr,"%6.1f|",10*log10(energy[sb]+1e-15)); } fprintf(stderr,"\nmask enrgy:"); for (sb=0; sb<nr_of_sfb; sb++){ fprintf(stderr,"%6.1f|",10*log10(allowed_dist[sb]+1e-15)); } fprintf(stderr,"\nerro enrgy:"); for (sb=0; sb<nr_of_sfb; sb++){ fprintf(stderr,"%6.1f|",10*log10(error_energy[sb]+1e-15)); } fprintf(stderr,"\nscalefacto:"); for (sb=0; sb<nr_of_sfb; sb++){ fprintf(stderr,"%6i|",(common_scalefac + SF_OFFSET -scale_factor[sb])); } }int tf_encode_spectrum_aac( double *p_spectrum[MAX_TIME_CHANNELS], double energy[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS], double allowed_dist[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS], WINDOW_SEQUENCE windowSequence[MAX_TIME_CHANNELS], int sfb_width_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS], int nr_of_sfb[MAX_TIME_CHANNELS], int average_block_bits, int available_bitreservoir_bits, int padding_limit, BsBitStream *fixed_stream, BsBitStream *var_stream, BsBitBuffer **gcBitBuf, /* bit buffer for gain_control_data() */ int nr_of_chan, double *p_reconstructed_spectrum[MAX_TIME_CHANNELS], int useShortWindows, WINDOW_SHAPE window_shape[MAX_TIME_CHANNELS], /* offers the possibility to select different window functions */ int aacAllowScalefacs, long sampling_rate, QC_MOD_SELECT qc_select, PRED_TYPE predictor_type, NOK_LT_PRED_STATUS nok_lt_status[MAX_TIME_CHANNELS], NOK_BW_PRED_STATUS nok_bwp_status[MAX_TIME_CHANNELS], int blockSizeSamples, int num_window_groups, int window_group_length[], TNS_INFO *tnsInfo[MAX_TIME_CHANNELS], int bandwidth ) { static int quant[CHANNEL][NUM_COEFF]; int i=0; int j=0; int k,sfb; int ch=0; double max_dct_line[MAX_TIME_CHANNELS]; int common_scalefac[MAX_TIME_CHANNELS]; int common_scalefac_save; int scale_factor[MAX_TIME_CHANNELS][SFB_NUM_MAX]; int scale_factor_save[SFB_NUM_MAX]; double error_energy[MAX_TIME_CHANNELS][SFB_NUM_MAX]; double linediff[MAX_TIME_CHANNELS][NUM_COEFF]; double pow_spectrum[MAX_TIME_CHANNELS][NUM_COEFF]; int sfb_amplify_check[MAX_TIME_CHANNELS][SFB_NUM_MAX]; double requant[CHANNEL][NUM_COEFF]; double ftmp; int largest_sb, sb; double largest_ratio; double ratio[MAX_TIME_CHANNELS][SFB_NUM_MAX]; int data[5*NUM_COEFF]; /* for each pair of spec values 5 bitstream elemets are requiered: 1*(esc)+2*(sign)+2*(esc value)=5 */ int len[5*NUM_COEFF]; int counter =0; int max_quant; int sfb_offset[250]; int sf_bits; int extra_bits = 0; int book_bits; int spectral_bits; int max_bits; int book_vector[MAX_TIME_CHANNELS][SFB_NUM_MAX]; int sf_test[SFB_NUM_MAX]; int bits_written = 0; int output_book_vector[MAX_TIME_CHANNELS][SFB_NUM_MAX*2]; int all_amplified; int maxRatio; /* change these values to test the different GROUPING possibilities */ int rateLoopCnt; double allowed_distortion[SFB_NUM_MAX]; int calc_sf[MAX_TIME_CHANNELS][SFB_NUM_MAX]; int no_subblocks, lines_per_subblock, no_coded_lines, nr_of_sfs; int pns_sfb_nrg[MAX_TIME_CHANNELS][SFB_NUM_MAX]; /* energies of each scalefactor band */ int pns_sfb_flag[MAX_TIME_CHANNELS][SFB_NUM_MAX]; /* PNS on/off flag for each scalefactor band */ double quantFac; /* Nokia 971128 / HP 980211 */ double invQuantFac; double spectrum[MAX_TIME_CHANNELS][2*NUM_COEFF]; int start_com_sf ; start_com_sf = 40 ; /* simple scale factors to make decoding testing easier */ for (k=0; k<SFB_NUM_MAX; k++){ sf_test[k] = k; } windowSequence[1] = windowSequence[0]; for( ch=1; ch<nr_of_chan; ch++ ) { if( windowSequence[ch] != windowSequence[0] ) { CommonExit( 1, "Only common window is supported currently" ); } } /* Bandwidth limiting: Do not code beyond cutoff bandwidth */ no_subblocks = (windowSequence[MONO_CHAN] == EIGHT_SHORT_SEQUENCE) ? 8 : 1; lines_per_subblock = 0; for (sfb=0; sfb<nr_of_sfb[MONO_CHAN]; sfb++) lines_per_subblock += sfb_width_table[MONO_CHAN][sfb];/* lines_per_subblock /= no_subblocks; */ no_coded_lines = (int)(bandwidth * 2.0 / sampling_rate * lines_per_subblock); for( ch=0; ch<nr_of_chan; ch++ ) { for (k=0; k<no_subblocks; k++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -