ref: 1dfd8c08ece7cba0be8eab1ffb2f00f80aa10ffc
dir: /aac_se_enc.c/
/********************************************************************* * * Module for writing/counting AAC syntactic elements * * Authors: * CL Chuck Lueck, TI <lueck@ti.com> * ADD Alberto Duenas, TI <alberto@ndsuk.com> * RG Ralf Geiger, FhG/IIS * Changes: * 07-jun-97 CL Initial revision. * 14-sep-97 CL Modified WritePredictorData to actually write * predictor data. Still need to add resets. * 20-oct-97 CL Updated WriteTNSData to support TNS. * 03-Dec-97 ADD Addding the prediction reset * 22-Jan-98 CL Added support for CPE's and common windows. * 07-Apr-98 RG Added WriteLFE to write LFE channel element. * **********************************************************************/ #include <stdlib.h> #include "aac_se_enc.h" #include "quant.h" #include "huffman.h" int max_pred_sfb; /*****************************************************************************/ /* WriteAACFillBits(...) */ /* Write fill_elements to the bitstream. */ /* Number of bits written is LEN_SE_ID + FIL_COUNT_LEN + a multiple of 8. */ /* Return number of bits left over (less than 7 ). */ /*****************************************************************************/ int WriteAACFillBits(BsBitStream* ptrBs, /* Pointer to bitstream */ int numBits, /* Number of bits needed to fill */ int writeFlag) { int numberOfBitsLeft=numBits; /* Need at least (LEN_SE_ID + LEN_F_CNT) bits for a fill_element */ int minNumberOfBits = LEN_SE_ID + LEN_F_CNT; while (numberOfBitsLeft>=minNumberOfBits) { int numberOfBytes; int maxCount; if (writeFlag) { BsPutBit(ptrBs,ID_FIL,LEN_SE_ID); /* Write fill_element ID */ } numberOfBitsLeft-=minNumberOfBits; /* Subtract for ID,count */ numberOfBytes=(int)(numberOfBitsLeft/LEN_BYTE); maxCount = (1<<LEN_F_CNT) - 1; /* Max count without escaping */ /* if we have less than maxCount bytes, write them now */ if (numberOfBytes<maxCount) { int i; if (writeFlag) { BsPutBit(ptrBs,numberOfBytes,LEN_F_CNT); for (i=0;i<numberOfBytes;i++) { BsPutBit(ptrBs,0,LEN_BYTE); } } /* otherwise, we need to write an escape count */ } else { int maxEscapeCount,maxNumberOfBytes,escCount; int i; if (writeFlag) { BsPutBit(ptrBs,maxCount,LEN_F_CNT); } maxEscapeCount = (1<<LEN_BYTE) - 1; /* Max escape count */ maxNumberOfBytes = maxCount + maxEscapeCount; numberOfBytes = (numberOfBytes > maxNumberOfBytes ) ? (maxNumberOfBytes) : (numberOfBytes); escCount = numberOfBytes - maxCount; if (writeFlag) { BsPutBit(ptrBs,escCount,LEN_BYTE); for (i=0;i<numberOfBytes-1;i++) { BsPutBit(ptrBs,0,LEN_BYTE); } } } numberOfBitsLeft -= LEN_BYTE*numberOfBytes; } return numberOfBitsLeft; } int WriteADTSHeader(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ BsBitStream* fixedStream, /* Pointer to bitstream */ int used_bits, int writeFlag) /* 1 means write, 0 means count only */ { if (writeFlag) { /* Fixed ADTS header */ BsPutBit(fixedStream, 0xFFFF, 12); // 12 bit Syncword BsPutBit(fixedStream, 1, 1); // ID BsPutBit(fixedStream, 0, 2); // layer BsPutBit(fixedStream, 1, 1); // protection absent BsPutBit(fixedStream, quantInfo->profile, 2); // profile BsPutBit(fixedStream, quantInfo->srate_idx, 4); // sampling rate BsPutBit(fixedStream, 0, 1); // private bit BsPutBit(fixedStream, 1, 3); // ch. config (must be > 0) BsPutBit(fixedStream, 0, 1); // original/copy BsPutBit(fixedStream, 0, 1); // home BsPutBit(fixedStream, 0, 2); // emphasis /* Variable ADTS header */ BsPutBit(fixedStream, 0, 1); // copyr. id. bit BsPutBit(fixedStream, 0, 1); // copyr. id. start BsPutBit(fixedStream, bit2byte(used_bits), 13); // number of bits BsPutBit(fixedStream, 0x7FF, 11); // buffer fullness (0x7FF for VBR) BsPutBit(fixedStream, 0, 2); // raw data blocks (0+1=1) } return 58; } /*****************************************************************************/ /* WriteSCE(...), write a single-channel element to the bitstream. */ /*****************************************************************************/ int WriteSCE(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ int tag, BsBitStream* fixedStream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int bit_count=0; if (writeFlag) { /* write ID_SCE, single_element_channel() identifier */ BsPutBit(fixedStream,ID_SCE,LEN_SE_ID); /* write the element_identifier_tag */ BsPutBit(fixedStream,tag,LEN_TAG); } bit_count += LEN_SE_ID; bit_count += LEN_TAG; /* Write an individual_channel_stream element */ bit_count += WriteICS(quantInfo,0,fixedStream,writeFlag); return bit_count; } /*****************************************************************************/ /* WriteLFE(...), write a lfe-channel element to the bitstream. */ /*****************************************************************************/ int WriteLFE(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ int tag, BsBitStream* fixedStream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int bit_count=0; if (writeFlag) { /* write ID_LFE, lfe_element_channel() identifier */ BsPutBit(fixedStream,ID_LFE,LEN_SE_ID); /* write the element_identifier_tag */ BsPutBit(fixedStream,tag,LEN_TAG); } bit_count += LEN_SE_ID; bit_count += LEN_TAG; /* Write an individual_channel_stream element */ bit_count += WriteICS(quantInfo,0,fixedStream,writeFlag); return bit_count; } /*****************************************************************************/ /* WriteCPE(...), write a channel_pair_element to the bitstream. */ /*****************************************************************************/ int WriteCPE(AACQuantInfo* quantInfoL, /* AACQuantInfo structure, left */ AACQuantInfo* quantInfoR, /* AACQuantInfo structure, right */ int tag, int commonWindow, /* common_window flag */ MS_Info* ms_info, /* MS stereo information */ BsBitStream* fixedStream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int bit_count=0; if (writeFlag) { /* write ID_CPE, single_element_channel() identifier */ BsPutBit(fixedStream,ID_CPE,LEN_SE_ID); /* write the element_identifier_tag */ BsPutBit(fixedStream,tag,LEN_TAG); /* Currently, this is zero */ /* common_window? */ BsPutBit(fixedStream,commonWindow,LEN_COM_WIN); } bit_count += LEN_SE_ID; bit_count += LEN_TAG; bit_count += LEN_COM_WIN; /* if common_window, write ics_info */ if (commonWindow) { int numWindows,maxSfb; bit_count += WriteICSInfo(quantInfoL,fixedStream,writeFlag); numWindows=quantInfoL->num_window_groups; maxSfb = quantInfoL->max_sfb; if (writeFlag) { BsPutBit(fixedStream,ms_info->is_present,LEN_MASK_PRES); if (ms_info->is_present==1) { int g; int b; for (g=0;g<numWindows;g++) { for (b=0;b<maxSfb;b++) { BsPutBit(fixedStream,ms_info->ms_used[g*maxSfb+b],LEN_MASK); } } } } bit_count += LEN_MASK_PRES; if (ms_info->is_present==1) bit_count += (numWindows*maxSfb*LEN_MASK); } /* Write individual_channel_stream elements */ bit_count += WriteICS(quantInfoL,commonWindow,fixedStream,writeFlag); bit_count += WriteICS(quantInfoR,commonWindow,fixedStream,writeFlag); return bit_count; } /*****************************************************************************/ /* WriteICS(...), write an individual_channel_stream element to the bitstream.*/ /*****************************************************************************/ int WriteICS(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ int commonWindow, /* Common window flag */ BsBitStream* fixed_stream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { /* this function writes out an individual_channel_stream to the bitstream and */ /* returns the number of bits written to the bitstream */ int bit_count = 0; // int output_book_vector[SFB_NUM_MAX*2]; writeFlag = ( writeFlag != 0 ); /* Write the 8-bit global_gain */ BsPutBit(fixed_stream,quantInfo->common_scalefac,writeFlag*LEN_GLOB_GAIN); bit_count += LEN_GLOB_GAIN; /* Write ics information */ if (!commonWindow) { bit_count += WriteICSInfo(quantInfo,fixed_stream,writeFlag); } /* Write section_data() information to the bitstream */ // bit_count += sort_book_numbers(quantInfo,output_book_vector,fixed_stream,writeFlag); bit_count += sort_book_numbers(quantInfo,fixed_stream,writeFlag); /* Write scale_factor_data() information */ bit_count += write_scalefactor_bitstream(fixed_stream,writeFlag,quantInfo); /* Write pulse_data() */ bit_count += WritePulseData(quantInfo,fixed_stream,writeFlag); /* Write TNS data */ bit_count += WriteTNSData(quantInfo,fixed_stream,writeFlag); /* Write gain control data */ bit_count += WriteGainControlData(fixed_stream,writeFlag); /* Write out spectral_data() */ bit_count += WriteSpectralData(quantInfo,fixed_stream,writeFlag); /* Return number of bits */ return(bit_count); } /*****************************************************************************/ /* WriteICSInfo(...), write individual_channel_stream information */ /* to the bitstream. */ /*****************************************************************************/ int WriteICSInfo(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ BsBitStream* fixed_stream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int grouping_bits; int max_sfb; int bit_count = 0; /* Compute number of scalefactor bands */ // if (quantInfo->max_sfb*quantInfo->num_window_groups != quantInfo->nr_of_sfb) //CommonExit(-1,"Wrong number of scalefactorbands"); max_sfb = quantInfo->max_sfb; if (writeFlag) { /* write out ics_info() information */ BsPutBit(fixed_stream,0,LEN_ICS_RESERV); /* reserved Bit*/ /* Write out window sequence */ BsPutBit(fixed_stream,quantInfo->block_type,LEN_WIN_SEQ); /* short window */ /* Write out window shape */ BsPutBit(fixed_stream,quantInfo->window_shape,LEN_WIN_SH); /* window shape */ } bit_count += LEN_ICS_RESERV; bit_count += LEN_WIN_SEQ; bit_count += LEN_WIN_SH; /* For short windows, write out max_sfb and scale_factor_grouping */ if (quantInfo -> block_type == ONLY_SHORT_WINDOW){ if (writeFlag) { BsPutBit(fixed_stream,max_sfb,LEN_MAX_SFBS); grouping_bits = find_grouping_bits(quantInfo->window_group_length,quantInfo->num_window_groups); BsPutBit(fixed_stream,grouping_bits,MAX_SHORT_IN_LONG_BLOCK - 1); /* the grouping bits */ } bit_count += LEN_MAX_SFBS; bit_count += MAX_SHORT_IN_LONG_BLOCK - 1; } /* Otherwise, write out max_sfb and predictor data */ else { /* block type is either start, stop, or long */ if (writeFlag) { BsPutBit(fixed_stream,max_sfb,LEN_MAX_SFBL); } bit_count += LEN_MAX_SFBL; bit_count += WriteLTP_PredictorData(quantInfo,fixed_stream,writeFlag); } return bit_count; } /*****************************************************************************/ /* WriteLTP_PredictorData(...), write LTP predictor data. */ /*****************************************************************************/ int WriteLTP_PredictorData(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ BsBitStream* fixed_stream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int bit_count = 0; bit_count += nok_ltp_encode (fixed_stream, quantInfo->block_type, quantInfo->nr_of_sfb, quantInfo->ltpInfo, writeFlag); return (bit_count); } /*****************************************************************************/ /* WritePulseData(...), write pulse data. */ /*****************************************************************************/ int WritePulseData(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ BsBitStream* fixed_stream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int i, bit_count = 0; if (quantInfo->pulseInfo.pulse_data_present) { if (writeFlag) { BsPutBit(fixed_stream,1,LEN_PULSE_PRES); /* no pulse_data_present */ BsPutBit(fixed_stream,quantInfo->pulseInfo.number_pulse,LEN_NEC_NPULSE); /* no pulse_data_present */ BsPutBit(fixed_stream,quantInfo->pulseInfo.pulse_start_sfb,LEN_NEC_ST_SFB); /* no pulse_data_present */ } bit_count += (LEN_NEC_NPULSE + LEN_NEC_ST_SFB); for (i = 0; i < quantInfo->pulseInfo.number_pulse+1; i++) { if (writeFlag) { BsPutBit(fixed_stream,quantInfo->pulseInfo.pulse_offset[i],LEN_NEC_POFF); BsPutBit(fixed_stream,quantInfo->pulseInfo.pulse_amp[i],LEN_NEC_PAMP); } bit_count += (LEN_NEC_POFF + LEN_NEC_PAMP); } } else { if (writeFlag) { BsPutBit(fixed_stream,0,LEN_PULSE_PRES); /* no pulse_data_present */ } } bit_count += LEN_PULSE_PRES; return bit_count; } /*****************************************************************************/ /* WriteTNSData(...), write TNS data. */ /*****************************************************************************/ int WriteTNSData(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ BsBitStream* fixed_stream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int bit_count = 0; int numWindows; int len_tns_nfilt; int len_tns_length; int len_tns_order; int filtNumber; int resInBits; int bitsToTransmit; unsigned long unsignedIndex; int w; TNS_INFO* tnsInfoPtr = quantInfo->tnsInfo; if (writeFlag) { BsPutBit(fixed_stream,tnsInfoPtr->tnsDataPresent,LEN_TNS_PRES); } bit_count += LEN_TNS_PRES; /* If TNS is not present, bail */ if (!tnsInfoPtr->tnsDataPresent) { return bit_count; } /* Set window-dependent TNS parameters */ if (quantInfo->block_type == ONLY_SHORT_WINDOW) { numWindows = MAX_SHORT_IN_LONG_BLOCK; len_tns_nfilt = LEN_TNS_NFILTS; len_tns_length = LEN_TNS_LENGTHS; len_tns_order = LEN_TNS_ORDERS; } else { numWindows = 1; len_tns_nfilt = LEN_TNS_NFILTL; len_tns_length = LEN_TNS_LENGTHL; len_tns_order = LEN_TNS_ORDERL; } /* Write TNS data */ bit_count += (numWindows * len_tns_nfilt); for (w=0;w<numWindows;w++) { TNS_WINDOW_DATA* windowDataPtr = &tnsInfoPtr->windowData[w]; int numFilters = windowDataPtr->numFilters; if (writeFlag) { BsPutBit(fixed_stream,numFilters,len_tns_nfilt); /* n_filt[] = 0 */ } if (numFilters) { bit_count += LEN_TNS_COEFF_RES; resInBits = windowDataPtr->coefResolution; if (writeFlag) { BsPutBit(fixed_stream,resInBits-DEF_TNS_RES_OFFSET,LEN_TNS_COEFF_RES); } bit_count += numFilters * (len_tns_length+len_tns_order); for (filtNumber=0;filtNumber<numFilters;filtNumber++) { TNS_FILTER_DATA* tnsFilterPtr=&windowDataPtr->tnsFilter[filtNumber]; int order = tnsFilterPtr->order; if (writeFlag) { BsPutBit(fixed_stream,tnsFilterPtr->length,len_tns_length); BsPutBit(fixed_stream,order,len_tns_order); } if (order) { bit_count += (LEN_TNS_DIRECTION + LEN_TNS_COMPRESS); if (writeFlag) { BsPutBit(fixed_stream,tnsFilterPtr->direction,LEN_TNS_DIRECTION); BsPutBit(fixed_stream,tnsFilterPtr->coefCompress,LEN_TNS_COMPRESS); } bitsToTransmit = resInBits - tnsFilterPtr->coefCompress; bit_count += order * bitsToTransmit; if (writeFlag) { int i; for (i=1;i<=order;i++) { unsignedIndex = (unsigned long) (tnsFilterPtr->index[i])&(~(~0<<bitsToTransmit)); BsPutBit(fixed_stream,unsignedIndex,bitsToTransmit); } } } } } } return bit_count; } /*****************************************************************************/ /* WriteGainControlData(...), write gain control data. */ /*****************************************************************************/ int WriteGainControlData(BsBitStream* fixed_stream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int bit_count = 0; bit_count += LEN_GAIN_PRES; if (writeFlag) { BsPutBit(fixed_stream,0,LEN_GAIN_PRES); } return bit_count; } /*****************************************************************************/ /* WriteSpectralData(...), write spectral data. */ /*****************************************************************************/ int WriteSpectralData(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ BsBitStream* fixed_stream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int bit_count = 0; int numSpectral = quantInfo->spectralCount; /* set up local pointers to data and len */ /* data array contains data to be written */ /* len array contains lengths of data words */ int* data = quantInfo -> data; int* len = quantInfo -> len; if (writeFlag) { int i; for(i=0;i<numSpectral;i++) { if (len[i] > 0) { /* only send out non-zero codebook data */ BsPutBit(fixed_stream,data[i],len[i]); /* write data */ bit_count += len[i]; /* update bit_count */ } } } else { int i; for(i=0;i<numSpectral;i++) { bit_count += len[i]; /* update bit_count */ } } return bit_count; }