Int get_adif_header( tDec_Int_File *pVars, ProgConfig *pScratchPCE) { Int i; UInt32 temp; Int numConfigElementsMinus1; Int bitStreamType; UInt32 theIDFromFile; BITS *pInputStream = &pVars->inputStream; ADIF_Header *pHeader = &pVars->scratch.adif_header; Int status = SUCCESS; /* * The ADIF_ID field is 32 bits long, one more than what getbits() can * do, so read the field in two parts. There is no point in saving the * string - it either matches or it does not. If it matches, it must * have been 'ADIF' */ theIDFromFile = get17_n_lessbits((2 * LEN_BYTE), pInputStream); temp = get17_n_lessbits((2 * LEN_BYTE), pInputStream); theIDFromFile = (theIDFromFile << (2 * LEN_BYTE)) | temp; if (theIDFromFile != ADIF_ID) { /* * Rewind the bit stream pointer so a search for ADTS header * can start at the beginning. */ pInputStream->usedBits -= (4 * LEN_BYTE); /* * The constant in the next line needs to be updated when * error handling method is determined. */ status = -1; } else { /* * To save space, the unused fields are read in, but not saved. */ /* copyright string */ temp = get1bits(/* LEN_COPYRT_PRES,*/ pInputStream); if (temp != FALSE) { /* * Read in and ignore the copyright string. If restoring * watch out for count down loop. */ for (i = LEN_COPYRT_ID; i > 0; i--) { get9_n_lessbits(LEN_BYTE, pInputStream); } /* end for */ /* * Make sure to terminate the string with '\0' if restoring * the the copyright string. */ } /* end if */ /* Combine the original/copy and fields into one call */ get9_n_lessbits( LEN_ORIG + LEN_HOME, pInputStream); bitStreamType = get1bits(/* LEN_BS_TYPE,*/ pInputStream); pHeader->bitrate = getbits( LEN_BIT_RATE, pInputStream); /* * Read in all the Program Configuration Elements. * For this library, only one of the up to 16 possible PCE's will be * saved. Since each PCE must be read, a temporary PCE structure is * used, and if that PCE is the one to use, it is copied into the * single PCE. This is done inside of get_prog_config() */ numConfigElementsMinus1 = get9_n_lessbits(LEN_NUM_PCE, pInputStream); for (i = numConfigElementsMinus1; (i >= 0) && (status == SUCCESS); i--) { /* * For ADIF contant bit rate streams, the _encoder_ buffer * fullness is transmitted. This version of an AAC decoder has * no use for this variable; yet it must be read in to move * the bitstream pointers. */ if (bitStreamType == CONSTANT_RATE_BITSTREAM) { getbits( LEN_ADIF_BF, pInputStream); } /* end if */ pVars->adif_test = 1; /* Get one program configuration element */ status = get_prog_config( pVars, pScratchPCE); #ifdef AAC_PLUS /* * For implicit signalling, no hint that sbr or ps is used, so we need to * check the sampling frequency of the aac content, if lesser or equal to * 24 KHz, by defualt upsample, otherwise, do nothing */ if ((pVars->prog_config.sampling_rate_idx >= 6) && (pVars->aacPlusEnabled == true) && pVars->mc_info.audioObjectType == MP4AUDIO_AAC_LC) { pVars->mc_info.upsamplingFactor = 2; pVars->prog_config.sampling_rate_idx -= 3; pVars->mc_info.sbrPresentFlag = 1; pVars->sbrDecoderData.SbrChannel[0].syncState = UPSAMPLING; pVars->sbrDecoderData.SbrChannel[1].syncState = UPSAMPLING; } #endif } /* end for */ } /* end 'else' of --> if (theIDFromFile != ADIF_ID) */ return status; } /* end get_adif_header */
/*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ void lt_decode( const WINDOW_SEQUENCE win_type, BITS *pInputStream, const Int max_sfb, LT_PRED_STATUS *pLt_pred) { Int wnd_num; Int k; Int last_band; Int prev_subblock; Int prev_subblock_nonzero; Int temp_reg; Bool *pWinPredictionUsed = pLt_pred->win_prediction_used; Bool *pSfbPredictionUsed = pLt_pred->sfb_prediction_used; Int *pTempPtr; Int *pDelay = pLt_pred->delay; pDelay[0] = (Int) get17_n_lessbits( LEN_LTP_LAG, /* 11 bits */ pInputStream); pLt_pred->weight_index = (Int) get9_n_lessbits( LEN_LTP_COEF, /* 3 bits */ pInputStream); last_band = max_sfb; if (win_type != EIGHT_SHORT_SEQUENCE) { /* last_band = min(MAX_LT_PRED_LONG_SFB, max_sfb) MAX_SCFAC_BANDS */ if (last_band > MAX_LT_PRED_LONG_SFB) { last_band = MAX_LT_PRED_LONG_SFB; } for (k = last_band; k > 0; k--) { *(pSfbPredictionUsed++) = (Int) get1bits(pInputStream); } /* * This is not a call to memset, because * (max_sfb - last_band) should typically be a small value. */ for (k = (max_sfb - last_band); k > 0; k--) { *(pSfbPredictionUsed++) = FALSE; } } else /* (win_type == EIGHT_SHORT_SEQUENCE) */ { /* last_band = min(MAX_LT_PRED_SHORT_SFB, max_sfb) */ if (last_band > MAX_LT_PRED_SHORT_SFB) { last_band = MAX_LT_PRED_SHORT_SFB; } /* * The following two coding constructs are equivalent... * * first_time == 1 * for (wnd_num=NUM_SHORT_WINDOWS; wnd_num > 0; wnd_num--) * { * if (condition) * { * if (first_time == 1) * { * CODE SECTION A * first_time = 0; * } * else * { * CODE SECTION B * } * } * } * * -----------------------------------EQUIVALENT TO------------ * * wnd_num=NUM_SHORT_WINDOWS; * * do * { * wnd_num--; * if (condition) * { * CODE SECTION A * break; * } * } while( wnd_num > 0) * * while (wnd_num > 0) * { * if (condition) * { * CODE SECTION B * } * wnd_num--; * } * */ prev_subblock = pDelay[0]; pTempPtr = &pSfbPredictionUsed[0]; wnd_num = NUM_SHORT_WINDOWS; prev_subblock_nonzero = prev_subblock; prev_subblock += LTP_LAG_OFFSET; do { /* * Place decrement of wnd_num here, to insure * that the decrement occurs before the * break out of the do-while loop. */ wnd_num--; temp_reg = (Int) get1bits(pInputStream); *(pWinPredictionUsed++) = temp_reg; if (temp_reg != FALSE) { *(pDelay++) = prev_subblock_nonzero; for (k = last_band; k > 0; k--) { *(pTempPtr++) = TRUE; } for (k = (max_sfb - last_band); k > 0; k--) { *(pTempPtr++) = FALSE; } break; } /* if(pWinPredictionUsed) */ else { pDelay++; pTempPtr += max_sfb; } } while (wnd_num > 0); /* * This while loop picks up where the previous one left off. * Notice that the code functions differently inside the loop */ while (wnd_num > 0) { temp_reg = (Int) get1bits(pInputStream); *(pWinPredictionUsed++) = temp_reg; if (temp_reg != FALSE) { temp_reg = (Int) get1bits(pInputStream); if (temp_reg != 0) { temp_reg = (Int) get9_n_lessbits( LEN_LTP_SHORT_LAG, pInputStream); *(pDelay++) = prev_subblock - temp_reg; } else { *(pDelay++) = prev_subblock_nonzero; } for (k = last_band; k > 0; k--) { *(pTempPtr++) = TRUE; } for (k = (max_sfb - last_band); k > 0; k--) { *(pTempPtr++) = FALSE; } } /* if (temp_reg) */ else { pDelay++; pTempPtr += max_sfb; } wnd_num--; } /* while(wnd_num) */ } /* else (win_type == EIGHT_SHORT_SEQUENCE) */ } /* lt_decode */
/*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ Int get_audio_specific_config(tDec_Int_File * const pVars) { UInt temp; tMP4AudioObjectType audioObjectType; //UInt32 sampling_rate; UInt channel_config; UInt syncExtensionType; UInt extensionAudioObjectType = 0; UInt extensionSamplingFrequencyIndex = 0; BITS *pInputStream; Int status; status = SUCCESS; pInputStream = &(pVars->inputStream); pVars->mc_info.upsamplingFactor = 1; /* default to regular AAC */ temp = get9_n_lessbits(LEN_OBJ_TYPE + LEN_SAMP_RATE_IDX, pInputStream); /* * The following code can directly set the values of elements in * MC_Info, rather than first setting the values in pVars->prog_config * and then copy these values to MC_Info by calling set_mc_info. * In order to keep consistent with get_prog_config (ADIF) and * get_adts_header (ADTS), the code here is still copying * the info, and set the pVars->current_program = 0 */ /* AudioObjectType */ audioObjectType = (tMP4AudioObjectType)((temp & 0x1f0) >> 4); pVars->mc_info.ExtendedAudioObjectType = audioObjectType; /* default */ /* saving an audioObjectType into a profile field */ /* pVars->prog_config.profile = audioObjectType; */ /* sampling rate index */ pVars->prog_config.sampling_rate_idx = temp & 0xf; if (pVars->prog_config.sampling_rate_idx > 0xb) { /* * Only support 12 sampling frequencies from array samp_rate_info ( see sfb.cpp) * 7350 Hz (index 0xc) is not supported, the other indexes are reserved or escape */ if (pVars->prog_config.sampling_rate_idx == 0xf) /* escape sequence */ { /* * sampling rate not listed in Table 1.6.2, * this release does not support this */ /*sampling_rate = getbits( LEN_SAMP_RATE, pInputStream);*/ getbits(LEN_SAMP_RATE, pInputStream); /* future use */ } status = 1; } channel_config = get9_n_lessbits(LEN_CHAN_CONFIG, pInputStream); if ((channel_config > 2) && (!pVars->aacConfigUtilityEnabled)) { /* * AAC lib does not support more than two channels * signal error when in decoder mode * do not test when in utility mode */ status = 1; } if (audioObjectType == MP4AUDIO_SBR || audioObjectType == MP4AUDIO_PS) { /* to disable explicit backward compatiblity check */ pVars->mc_info.ExtendedAudioObjectType = MP4AUDIO_SBR; pVars->mc_info.sbrPresentFlag = 1; if (audioObjectType == MP4AUDIO_PS) { pVars->mc_info.psPresentFlag = 1; pVars->mc_info.ExtendedAudioObjectType = MP4AUDIO_PS; } extensionSamplingFrequencyIndex = /* extensionSamplingFrequencyIndex */ get9_n_lessbits(LEN_SAMP_RATE_IDX, pInputStream); if (extensionSamplingFrequencyIndex == 0x0f) { /* * sampling rate not listed in Table 1.6.2, * this release does not support this */ /*sampling_rate = getbits( LEN_SAMP_RATE, pInputStream);*/ getbits(LEN_SAMP_RATE, pInputStream); } audioObjectType = (tMP4AudioObjectType) get9_n_lessbits(LEN_OBJ_TYPE , pInputStream); } if ((/*(audioObjectType == MP4AUDIO_AAC_MAIN) ||*/ (audioObjectType == MP4AUDIO_AAC_LC) || /*(audioObjectType == MP4AUDIO_AAC_SSR) ||*/ (audioObjectType == MP4AUDIO_LTP) /*||*/ /*(audioObjectType == MP4AUDIO_AAC_SCALABLE) ||*/ /*(audioObjectType == MP4AUDIO_TWINVQ)*/) && (status == SUCCESS)) { status = get_GA_specific_config(pVars, pInputStream, channel_config, audioObjectType); /* * verify that Program config returned a supported audio object type */ if ((pVars->mc_info.audioObjectType != MP4AUDIO_AAC_LC) && (pVars->mc_info.audioObjectType != MP4AUDIO_LTP)) { return 1; /* status != SUCCESS invalid aot */ } } else { return 1; /* status != SUCCESS invalid aot or invalid parameter */ } /* * SBR tool explicit signaling ( backward compatible ) */ if (extensionAudioObjectType != MP4AUDIO_SBR) { syncExtensionType = (UInt)get17_n_lessbits(LEN_SYNC_EXTENSION_TYPE, pInputStream); printf("%s(): syncExtensionType:%d\n", __FUNCTION__, syncExtensionType); if (syncExtensionType == 0x2b7) { extensionAudioObjectType = get9_n_lessbits( /* extensionAudioObjectType */ LEN_OBJ_TYPE, pInputStream); if (extensionAudioObjectType == MP4AUDIO_SBR) { printf("%s(): extensionAudioObjectType is MP4AUDIO_SBR\n", __FUNCTION__); pVars->mc_info.sbrPresentFlag = get1bits(pInputStream); /* sbrPresentFlag */ if (pVars->mc_info.sbrPresentFlag == 1) { printf("%s(): sbrPresent\n", __FUNCTION__); extensionSamplingFrequencyIndex = get9_n_lessbits( /* extensionSamplingFrequencyIndex */ LEN_SAMP_RATE_IDX, pInputStream); if (pVars->aacPlusEnabled == true) { #ifdef AAC_PLUS if (extensionSamplingFrequencyIndex < 3) { /* * Disable SBR/PS for any sampling freq. > 48 KHz * 3GPP request support up to Level 2, == max AAC/SBR present * 24/48 KHz */ pVars->aacPlusEnabled = false; printf("%s(): diasable\n", __FUNCTION__); } else { pVars->mc_info.upsamplingFactor = (samp_rate_info[extensionSamplingFrequencyIndex].samp_rate >> 1) == samp_rate_info[pVars->prog_config.sampling_rate_idx].samp_rate ? 2 : 1; printf("%s(): upsamplingFactor : %d\n", __FUNCTION__, pVars->mc_info.upsamplingFactor); if ((Int)extensionSamplingFrequencyIndex == pVars->prog_config.sampling_rate_idx) { /* * Disable SBR decoding for any sbr-downsampled file whose SF is >= 24 KHz */ if (pVars->prog_config.sampling_rate_idx < 6) { pVars->aacPlusEnabled = false; printf("%s(): diasable\n", __FUNCTION__); } pVars->mc_info.bDownSampledSbr = true; } pVars->prog_config.sampling_rate_idx = extensionSamplingFrequencyIndex; } #endif } else printf("pVars->aacPlusEnabled is false\n");