ref: bc807920e3d52f57993e1dc34f9c0f23bb6847c0
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 "aac_qc.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 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; 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; 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; 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; BsPutBit(ptrBs,escCount,LEN_BYTE); for (i=0;i<numberOfBytes-1;i++) { BsPutBit(ptrBs,0,LEN_BYTE); } } numberOfBitsLeft -= LEN_BYTE*numberOfBytes; } return numberOfBitsLeft; } /*****************************************************************************/ /* 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; bit_count += (ms_info->is_present==1)*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); /* 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(quantInfo,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 += WritePredictorData(quantInfo,fixed_stream,writeFlag); } return bit_count; } /*****************************************************************************/ /* WritePredictorData(...), write predictor data. */ /*****************************************************************************/ int WritePredictorData(AACQuantInfo* quantInfo, /* AACQuantInfo structure */ BsBitStream* fixed_stream, /* Pointer to bitstream */ int writeFlag) /* 1 means write, 0 means count only */ { int bit_count = 0; /* Write global predictor data present */ short predictorDataPresent = quantInfo->pred_global_flag; int numBands = min(max_pred_sfb,quantInfo->nr_of_sfb); if (writeFlag) { BsPutBit(fixed_stream,predictorDataPresent,LEN_PRED_PRES); /* predictor_data_present */ if (predictorDataPresent) { int b; /* Code segment added by JB */ if (quantInfo->reset_group_number == -1) BsPutBit(fixed_stream,0,LEN_PRED_RST); /* No prediction reset */ else { BsPutBit(fixed_stream,1,LEN_PRED_RST); BsPutBit(fixed_stream,(unsigned long)quantInfo->reset_group_number, LEN_PRED_RSTGRP); } /* End of code segment */ for (b=0;b<numBands;b++) { BsPutBit(fixed_stream,quantInfo->pred_sfb_flag[b],LEN_PRED_ENAB); } } } bit_count = LEN_PRED_PRES; bit_count += (predictorDataPresent) ? (LEN_PRED_RST + ((quantInfo->reset_group_number)!=-1)*LEN_PRED_RSTGRP + numBands*LEN_PRED_ENAB) : 0; 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 = 1; 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; 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(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 += 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; }