/* * Function : dtx_dec_amr_wb_reset */ int16 dtx_dec_amr_wb_reset(dtx_decState * st, const int16 isf_init[]) { int16 i; if (st == (dtx_decState *) NULL) { /* dtx_dec_amr_wb_reset invalid parameter */ return (-1); } st->since_last_sid = 0; st->true_sid_period_inv = (1 << 13); /* 0.25 in Q15 */ st->log_en = 3500; st->old_log_en = 3500; /* low level noise for better performance in DTX handover cases */ st->cng_seed = RANDOM_INITSEED; st->hist_ptr = 0; /* Init isf_hist[] and decoder log frame energy */ pv_memcpy((void *)st->isf, (void *)isf_init, M*sizeof(*isf_init)); pv_memcpy((void *)st->isf_old, (void *)isf_init, M*sizeof(*isf_init)); for (i = 0; i < DTX_HIST_SIZE; i++) { pv_memcpy((void *)&st->isf_hist[i * M], (void *)isf_init, M*sizeof(*isf_init)); st->log_en_hist[i] = st->log_en; } st->dtxHangoverCount = DTX_HANG_CONST; st->decAnaElapsedCount = 32767; st->sid_frame = 0; st->valid_data = 0; st->dtxHangoverAdded = 0; st->dtxGlobalState = SPEECH; st->data_updated = 0; st->dither_seed = RANDOM_INITSEED; st->CN_dith = 0; return 0; }
void sbr_open(Int32 sampleRate, SBR_DEC *sbrDec, SBRDECODER_DATA * self, Bool bDownSampledSbr) { Int16 i ; SBR_CHANNEL *SbrChannel; SbrChannel = self->SbrChannel; for (i = 0; i < MAX_NUM_CHANNELS; i++) { pv_memset((void *)&(SbrChannel[i]), 0, sizeof(SBR_CHANNEL)); /* init a default header such that we can at least do upsampling later */ pv_memcpy(&(SbrChannel[i].frameData.sbr_header), &defaultHeader, sizeof(SBR_HEADER_DATA)); /* should be handled by sample rate mode bit */ if (sampleRate > 24000 || bDownSampledSbr) { SbrChannel[i].frameData.sbr_header.sampleRateMode = SINGLE_RATE; } SbrChannel[i].outFrameSize = init_sbr_dec(sampleRate, self->SbrChannel[0].frameData.sbr_header.sampleRateMode, sbrDec, &(SbrChannel[i].frameData)); SbrChannel[i].syncState = UPSAMPLING; SbrChannel[i].frameData.sUp = 1; /* reset mode */ } }
/* * Function : dtx_dec_amr_wb */ int16 dtx_dec_amr_wb( dtx_decState * st, /* i/o : State struct */ int16 * exc2, /* o : CN excitation */ int16 new_state, /* i : New DTX state */ int16 isf[], /* o : CN ISF vector */ int16 ** prms ) { int16 log_en_index; int16 ind[7]; int16 i, j; int16 int_fac; int16 gain; int32 L_isf[M], L_log_en_int, level32, ener32; int16 ptr; int16 tmp_int_length; int16 tmp, exp, exp0, log_en_int_e, log_en_int_m, level; /* This function is called if synthesis state is not SPEECH the globally passed inputs to this function * are st->sid_frame st->valid_data st->dtxHangoverAdded new_state (SPEECH, DTX, DTX_MUTE) */ if ((st->dtxHangoverAdded != 0) && (st->sid_frame != 0)) { /* sid_first after dtx hangover period */ /* or sid_upd after dtxhangover */ /* consider twice the last frame */ ptr = st->hist_ptr + 1; if (ptr == DTX_HIST_SIZE) ptr = 0; pv_memcpy((void *)&st->isf_hist[ptr * M], (void *)&st->isf_hist[st->hist_ptr * M], M*sizeof(*st->isf_hist)); st->log_en_hist[ptr] = st->log_en_hist[st->hist_ptr]; /* compute mean log energy and isf from decoded signal (SID_FIRST) */ st->log_en = 0; for (i = 0; i < M; i++) { L_isf[i] = 0; } /* average energy and isf */ for (i = 0; i < DTX_HIST_SIZE; i++) { /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer log_en is in Q10 */ st->log_en = add_int16(st->log_en, st->log_en_hist[i]); for (j = 0; j < M; j++) { L_isf[j] = add_int32(L_isf[j], (int32)(st->isf_hist[i * M + j])); } } /* st->log_en in Q9 */ st->log_en >>= 1; /* Add 2 in Q9, in order to have only positive values for Pow2 */ /* this value is subtracted back after Pow2 function */ st->log_en += 1024; if (st->log_en < 0) st->log_en = 0; for (j = 0; j < M; j++) { st->isf[j] = (int16)(L_isf[j] >> 3); /* divide by 8 */ } }
SBR_ERROR sbr_read_data(SBRDECODER_DATA * self, SBR_DEC * sbrDec, SBRBITSTREAM *stream) { SBR_ERROR sbr_err = SBRDEC_OK; int32_t SbrFrameOK = 1; int32_t sbrCRCAlwaysOn = 0; UInt32 bs_header_flag = 0; SBR_HEADER_STATUS headerStatus = HEADER_OK; SBR_CHANNEL *SbrChannel = self->SbrChannel; int32_t zeropadding_bits; BIT_BUFFER bitBuf ; /* * evaluate Bitstream */ bitBuf.buffer_word = 0; bitBuf.buffered_bits = 0; bitBuf.nrBitsRead = 0; bitBuf.char_ptr = stream->sbrElement[0].Data; bitBuf.bufferLen = (stream->sbrElement[0].Payload) << 3; /* * we have to skip a nibble because the first element of Data only * contains a nibble of data ! */ buf_getbits(&bitBuf, LEN_NIBBLE); if ((stream->sbrElement[0].ExtensionType == SBR_EXTENSION_CRC) || sbrCRCAlwaysOn) { int32_t CRCLen = ((stream->sbrElement[0].Payload - 1) << 3) + 4 - SI_SBR_CRC_BITS; SbrFrameOK = sbr_crc_check(&bitBuf, CRCLen); } if (SbrFrameOK) { /* * The sbr data seems ok, if the header flag is set we read the header * and check if vital parameters have changed since the previous frame. * If the syncState equals UPSAMPLING, the SBR Tool has not been * initialised by SBR header data, and can only do upsampling */ bs_header_flag = buf_getbits(&bitBuf, 1); /* read Header flag */ if (bs_header_flag) { /* * If syncState == SBR_ACTIVE, it means that we've had a SBR header * before, and we will compare with the previous header to see if a * reset is required. If the syncState equals UPSAMPLING this means * that the SBR-Tool so far is only initialised to do upsampling * and hence we need to do a reset, and initialise the system * according to the present header. */ headerStatus = sbr_get_header_data(&(SbrChannel[0].frameData.sbr_header), &bitBuf, SbrChannel[0].syncState); } /* if (bs_header_flag) */ switch (stream->sbrElement[0].ElementID) { case SBR_ID_SCE : /* change of control data, reset decoder */ if (headerStatus == HEADER_RESET) { sbr_err = sbr_reset_dec(&(SbrChannel[0].frameData), sbrDec, self->SbrChannel[0].frameData.sbr_header.sampleRateMode); if (sbr_err != SBRDEC_OK) { break; } /* * At this point we have a header and the system has been reset, * hence syncState from now on will be SBR_ACTIVE. */ SbrChannel[0].syncState = SBR_ACTIVE; } if ((SbrChannel[0].syncState == SBR_ACTIVE)) { sbr_err = sbr_get_sce(&(SbrChannel[0].frameData), &bitBuf #ifdef PARAMETRICSTEREO , self->hParametricStereoDec #endif ); if (sbr_err != SBRDEC_OK) { break; } } break; case SBR_ID_CPE : if (bs_header_flag) { pv_memcpy(&(SbrChannel[1].frameData.sbr_header), &(SbrChannel[0].frameData.sbr_header), sizeof(SBR_HEADER_DATA)); } /* change of control data, reset decoder */ if (headerStatus == HEADER_RESET) { for (int32_t lr = 0 ; lr < 2 ; lr++) { sbr_err = sbr_reset_dec(&(SbrChannel[lr].frameData), sbrDec, self->SbrChannel[0].frameData.sbr_header.sampleRateMode); if (sbr_err != SBRDEC_OK) { break; } SbrChannel[lr].syncState = SBR_ACTIVE; } } if (SbrChannel[0].syncState == SBR_ACTIVE) { sbr_err = sbr_get_cpe(&(SbrChannel[0].frameData), &(SbrChannel[1].frameData), &bitBuf); if (sbr_err != SBRDEC_OK) { break; } } break; default: sbr_err = SBRDEC_ILLEGAL_PLUS_ELE_ID; break; } } /* if (SbrFrameOK) */ /* * Check that the bits read did not go beyond SBR frame boundaries */ zeropadding_bits = (8 - (bitBuf.nrBitsRead & 0x7)) & 0x7; if ((bitBuf.nrBitsRead + zeropadding_bits) > bitBuf.bufferLen) { sbr_err = SBRDEC_INVALID_BITSTREAM; } return sbr_err; }
SBR_ERROR extractFrameInfo(BIT_BUFFER * hBitBuf, SBR_FRAME_DATA * h_frame_data) { Int32 absBordLead = 0; Int32 nRelLead = 0; Int32 nRelTrail = 0; Int32 bs_num_env = 0; Int32 bs_num_rel = 0; Int32 bs_var_bord = 0; Int32 bs_var_bord_0 = 0; Int32 bs_var_bord_1 = 0; Int32 bs_pointer = 0; Int32 bs_pointer_bits; Int32 frameClass; Int32 temp; Int32 env; Int32 k; Int32 bs_num_rel_0 = 0; Int32 bs_num_rel_1 = 0; Int32 absBordTrail = 0; Int32 middleBorder = 0; Int32 bs_num_noise; Int32 lA = 0; Int32 tE[MAX_ENVELOPES + 1]; Int32 tQ[2 + 1]; Int32 f[MAX_ENVELOPES + 1]; Int32 bs_rel_bord[3]; Int32 bs_rel_bord_0[3]; Int32 bs_rel_bord_1[3]; Int32 relBordLead[3]; Int32 relBordTrail[3]; Int32 *v_frame_info = h_frame_data->frameInfo; SBR_ERROR err = SBRDEC_OK; /* * First read from the bitstream. */ /* Read frame class */ h_frame_data->frameClass = frameClass = buf_getbits(hBitBuf, SBR_CLA_BITS); switch (frameClass) { case FIXFIX: temp = buf_getbits(hBitBuf, SBR_ENV_BITS); /* 2 bits */ bs_num_env = 1 << temp; f[0] = buf_getbits(hBitBuf, SBR_RES_BITS); /* 1 bit */ for (env = 1; env < bs_num_env; env++) { f[env] = f[0]; } nRelLead = bs_num_env - 1; absBordTrail = 16; break; case FIXVAR: bs_var_bord = buf_getbits(hBitBuf, SBR_ABS_BITS); /* 2 bits */ bs_num_rel = buf_getbits(hBitBuf, SBR_NUM_BITS); /* 2 bits */ bs_num_env = bs_num_rel + 1; for (k = 0; k < bs_num_env - 1; k++) { bs_rel_bord[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1; } bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env]; bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits); for (env = 0; env < bs_num_env; env++) { /* 1 bit */ f[bs_num_env - 1 - env] = buf_getbits(hBitBuf, SBR_RES_BITS); } absBordTrail = 16 + bs_var_bord; nRelTrail = bs_num_rel; break; case VARFIX: bs_var_bord = buf_getbits(hBitBuf, SBR_ABS_BITS); /* 2 bits */ bs_num_rel = buf_getbits(hBitBuf, SBR_NUM_BITS); /* 2 bits */ bs_num_env = bs_num_rel + 1; for (k = 0; k < bs_num_env - 1; k++) { bs_rel_bord[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1; } bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env]; bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits); for (env = 0; env < bs_num_env; env++) { /* 1 bit */ f[env] = buf_getbits(hBitBuf, SBR_RES_BITS); } absBordTrail = 16; absBordLead = bs_var_bord; nRelLead = bs_num_rel; break; case VARVAR: bs_var_bord_0 = buf_getbits(hBitBuf, SBR_ABS_BITS); /* 2 bits */ bs_var_bord_1 = buf_getbits(hBitBuf, SBR_ABS_BITS); bs_num_rel_0 = buf_getbits(hBitBuf, SBR_NUM_BITS); /* 2 bits */ bs_num_rel_1 = buf_getbits(hBitBuf, SBR_NUM_BITS); bs_num_env = bs_num_rel_0 + bs_num_rel_1 + 1; for (k = 0; k < bs_num_rel_0; k++) { /* 2 bits */ bs_rel_bord_0[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1; } for (k = 0; k < bs_num_rel_1; k++) { /* 2 bits */ bs_rel_bord_1[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1; } bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env]; bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits); for (env = 0; env < bs_num_env; env++) { /* 1 bit */ f[env] = buf_getbits(hBitBuf, SBR_RES_BITS); } absBordLead = bs_var_bord_0; absBordTrail = 16 + bs_var_bord_1; nRelLead = bs_num_rel_0; nRelTrail = bs_num_rel_1; break; }; /* * Calculate the framing. */ switch (frameClass) { case FIXFIX: for (k = 0; k < nRelLead; k++) { relBordLead[k] = T_16_ov_bs_num_env_tbl[bs_num_env]; } break; case VARFIX: for (k = 0; k < nRelLead; k++) { relBordLead[k] = bs_rel_bord[k]; } break; case VARVAR: for (k = 0; k < nRelLead; k++) { relBordLead[k] = bs_rel_bord_0[k]; } for (k = 0; k < nRelTrail; k++) { relBordTrail[k] = bs_rel_bord_1[k]; } break; case FIXVAR: for (k = 0; k < nRelTrail; k++) { relBordTrail[k] = bs_rel_bord[k]; } break; } tE[0] = absBordLead; tE[bs_num_env] = absBordTrail; for (env = 1; env <= nRelLead; env++) { tE[env] = absBordLead; for (k = 0; k <= env - 1; k++) { tE[env] += relBordLead[k]; } } for (env = nRelLead + 1; env < bs_num_env; env++) { tE[env] = absBordTrail; for (k = 0; k <= bs_num_env - env - 1; k++) { tE[env] -= relBordTrail[k]; } } switch (frameClass) { case FIXFIX: middleBorder = bs_num_env >> 1; break; case VARFIX: switch (bs_pointer) { case 0: middleBorder = 1; break; case 1: middleBorder = bs_num_env - 1; break; default: middleBorder = bs_pointer - 1; break; }; break; case FIXVAR: case VARVAR: switch (bs_pointer) { case 0: case 1: middleBorder = bs_num_env - 1; break; default: middleBorder = bs_num_env + 1 - bs_pointer; break; }; break; }; tQ[0] = tE[0]; if (bs_num_env > 1) { tQ[1] = tE[middleBorder]; tQ[2] = tE[bs_num_env]; bs_num_noise = 2; } else { tQ[1] = tE[bs_num_env]; bs_num_noise = 1; } /* * Check consistency on freq bands */ if ((tE[bs_num_env] < tE[0]) || (tE[0] < 0)) { err = SBRDEC_INVALID_BITSTREAM; } switch (frameClass) { case FIXFIX: lA = -1; break; case VARFIX: switch (bs_pointer) { case 0: case 1: lA = -1; break; default: lA = bs_pointer - 1; break; }; break; case FIXVAR: case VARVAR: switch (bs_pointer) { case 0: lA = - 1; break; default: lA = bs_num_env + 1 - bs_pointer; break; }; break; }; /* * Build the frameInfo vector... */ v_frame_info[0] = bs_num_env; /* Number of envelopes*/ pv_memcpy(v_frame_info + 1, tE, (bs_num_env + 1)*sizeof(Int32)); /* time borders*/ /* frequency resolution */ pv_memcpy(v_frame_info + 1 + bs_num_env + 1, f, bs_num_env*sizeof(Int32)); temp = (1 + bs_num_env) << 1; v_frame_info[temp] = lA; /* transient envelope*/ v_frame_info[temp + 1] = bs_num_noise; /* Number of noise envelopes */ /* noise borders */ pv_memcpy(v_frame_info + temp + 2, tQ, (bs_num_noise + 1)*sizeof(Int32)); return (err); }
SBR_ERROR sbr_get_cpe(SBR_FRAME_DATA * hFrameDataLeft, SBR_FRAME_DATA * hFrameDataRight, BIT_BUFFER * hBitBuf) { Int32 i; Int32 bits; SBR_ERROR err = SBRDEC_OK; /* reserved bits */ bits = buf_getbits(hBitBuf, SI_SBR_RESERVED_PRESENT); if (bits) { buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_DATA); buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_DATA); } /* Read coupling flag */ bits = buf_getbits(hBitBuf, SI_SBR_COUPLING_BITS); if (bits) { hFrameDataLeft->coupling = COUPLING_LEVEL; hFrameDataRight->coupling = COUPLING_BAL; } else { hFrameDataLeft->coupling = COUPLING_OFF; hFrameDataRight->coupling = COUPLING_OFF; } err = extractFrameInfo(hBitBuf, hFrameDataLeft); if (err != SBRDEC_OK) { return err; } if (hFrameDataLeft->coupling) { pv_memcpy(hFrameDataRight->frameInfo, hFrameDataLeft->frameInfo, LENGTH_FRAME_INFO * sizeof(Int32)); hFrameDataRight->nNoiseFloorEnvelopes = hFrameDataLeft->nNoiseFloorEnvelopes; hFrameDataRight->frameClass = hFrameDataLeft->frameClass; sbr_get_dir_control_data(hFrameDataLeft, hBitBuf); sbr_get_dir_control_data(hFrameDataRight, hBitBuf); for (i = 0; i < hFrameDataLeft->nNfb; i++) { hFrameDataLeft->sbr_invf_mode_prev[i] = hFrameDataLeft->sbr_invf_mode[i]; hFrameDataRight->sbr_invf_mode_prev[i] = hFrameDataRight->sbr_invf_mode[i]; hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS); hFrameDataRight->sbr_invf_mode[i] = hFrameDataLeft->sbr_invf_mode[i]; } sbr_get_envelope(hFrameDataLeft, hBitBuf); sbr_get_noise_floor_data(hFrameDataLeft, hBitBuf); sbr_get_envelope(hFrameDataRight, hBitBuf); } else { err = extractFrameInfo(hBitBuf, hFrameDataRight); if (err != SBRDEC_OK) { return err; } sbr_get_dir_control_data(hFrameDataLeft, hBitBuf); sbr_get_dir_control_data(hFrameDataRight, hBitBuf); for (i = 0; i < hFrameDataLeft->nNfb; i++) { hFrameDataLeft->sbr_invf_mode_prev[i] = hFrameDataLeft->sbr_invf_mode[i]; hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS); } for (i = 0; i < hFrameDataRight->nNfb; i++) { hFrameDataRight->sbr_invf_mode_prev[i] = hFrameDataRight->sbr_invf_mode[i]; hFrameDataRight->sbr_invf_mode[i] = (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS); } sbr_get_envelope(hFrameDataLeft, hBitBuf); sbr_get_envelope(hFrameDataRight, hBitBuf); sbr_get_noise_floor_data(hFrameDataLeft, hBitBuf); } sbr_get_noise_floor_data(hFrameDataRight, hBitBuf); pv_memset((void *)hFrameDataLeft->addHarmonics, 0, hFrameDataLeft->nSfb[HI]*sizeof(Int32)); pv_memset((void *)hFrameDataRight->addHarmonics, 0, hFrameDataRight->nSfb[HI]*sizeof(Int32)); sbr_get_additional_data(hFrameDataLeft, hBitBuf); sbr_get_additional_data(hFrameDataRight, hBitBuf); sbr_extract_extended_data(hBitBuf // 2010.01.26 : // in order to detect ps tag in adts/adif but decoding it // we remove this definition ////#ifdef PARAMETRICSTEREO , NULL ////#endif ); return SBRDEC_OK; }
SBR_HEADER_STATUS sbr_get_header_data(SBR_HEADER_DATA * h_sbr_header, BIT_BUFFER * hBitBuf, SBR_SYNC_STATE syncState) { SBR_HEADER_DATA lastHeader; Int32 headerExtra1, headerExtra2; /* Copy header to temporary header */ if (syncState == SBR_ACTIVE) { pv_memcpy(&lastHeader, h_sbr_header, sizeof(SBR_HEADER_DATA)); } else { pv_memset((void *)&lastHeader, 0, sizeof(SBR_HEADER_DATA)); } /* Read new header from bitstream */ h_sbr_header->ampResolution = buf_getbits(hBitBuf, SI_SBR_AMP_RES_BITS); h_sbr_header->startFreq = buf_getbits(hBitBuf, SI_SBR_START_FREQ_BITS); h_sbr_header->stopFreq = buf_getbits(hBitBuf, SI_SBR_STOP_FREQ_BITS); h_sbr_header->xover_band = buf_getbits(hBitBuf, SI_SBR_XOVER_BAND_BITS); buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_HDR); headerExtra1 = buf_getbits(hBitBuf, SI_SBR_HEADER_EXTRA_1_BITS); headerExtra2 = buf_getbits(hBitBuf, SI_SBR_HEADER_EXTRA_2_BITS); /* handle extra header information */ if (headerExtra1) { h_sbr_header->freqScale = buf_getbits(hBitBuf, SI_SBR_FREQ_SCALE_BITS); h_sbr_header->alterScale = buf_getbits(hBitBuf, SI_SBR_ALTER_SCALE_BITS); h_sbr_header->noise_bands = buf_getbits(hBitBuf, SI_SBR_NOISE_BANDS_BITS); } else { /* Set default values.*/ h_sbr_header->freqScale = SBR_FREQ_SCALE_DEFAULT; h_sbr_header->alterScale = SBR_ALTER_SCALE_DEFAULT; h_sbr_header->noise_bands = SBR_NOISE_BANDS_DEFAULT; } if (headerExtra2) { h_sbr_header->limiterBands = buf_getbits(hBitBuf, SI_SBR_LIMITER_BANDS_BITS); h_sbr_header->limiterGains = buf_getbits(hBitBuf, SI_SBR_LIMITER_GAINS_BITS); h_sbr_header->interpolFreq = buf_getbits(hBitBuf, SI_SBR_INTERPOL_FREQ_BITS); h_sbr_header->smoothingLength = buf_getbits(hBitBuf, SI_SBR_SMOOTHING_LENGTH_BITS); } else { /* Set default values.*/ h_sbr_header->limiterBands = SBR_LIMITER_BANDS_DEFAULT; h_sbr_header->limiterGains = SBR_LIMITER_GAINS_DEFAULT; h_sbr_header->interpolFreq = SBR_INTERPOL_FREQ_DEFAULT; h_sbr_header->smoothingLength = SBR_SMOOTHING_LENGTH_DEFAULT; } if (syncState == SBR_ACTIVE) { h_sbr_header->status = HEADER_OK; /* look for new settings */ if (lastHeader.startFreq != h_sbr_header->startFreq || lastHeader.stopFreq != h_sbr_header->stopFreq || lastHeader.xover_band != h_sbr_header->xover_band || lastHeader.freqScale != h_sbr_header->freqScale || lastHeader.alterScale != h_sbr_header->alterScale || lastHeader.noise_bands != h_sbr_header->noise_bands) { h_sbr_header->status = HEADER_RESET; } } else { h_sbr_header->status = HEADER_RESET; } return h_sbr_header->status; }
Int get_prog_config( tDec_Int_File *pVars, ProgConfig *pScratchPCE) { Int i; UInt tag; Int numChars; UInt temp; Bool flag; Int status = SUCCESS; BITS *pInputStream = &(pVars->inputStream); /* * The tag is used at the very end to see if this PCE is * the one to be used. Otherwise it does not need to be saved for the * the simple configurations to be used in this version of an AAC * decoder. * * All of the bits of this PCE must be read even if this PCE will not * be used. They are read into a temporary PCE, then later it is decided * whether to keep this PCE. * * To allow quick removal of the fields from the ProgConfig structure * that will probably not be used at a later date, * while still advancing the bitstream pointer,the return value of * getbits is saved into a temporary variable, then transfered to * the structure item. */ tag = get9_n_lessbits(LEN_TAG, pInputStream); pScratchPCE->profile = get9_n_lessbits(LEN_PROFILE, pInputStream); pScratchPCE->sampling_rate_idx = get9_n_lessbits(LEN_SAMP_IDX, pInputStream); if (!pVars->adif_test && (pScratchPCE->sampling_rate_idx != pVars->prog_config.sampling_rate_idx)) { #ifdef AAC_PLUS /* * PCE carries the baseline frequency, if SBR or PS are used, the frequencies will not match * so check for this unique case, and let decoding continue if this is a redundant PCE */ if ((pScratchPCE->sampling_rate_idx != (pVars->prog_config.sampling_rate_idx + 3)) || (pVars->mc_info.upsamplingFactor != 2)) #endif { /* rewind the pointer as implicit channel configuration maybe the case */ pInputStream->usedBits -= (LEN_TAG + LEN_PROFILE + LEN_SAMP_IDX); return (1); /* mismatch cannot happen */ } } /* * Retrieve the number of element lists for each of * front, side, back, lfe, data, and coupling. * * For two-channel stereo or mono, only the data in the front needs * to be saved. However, ALL fields need to be skipped over in some * fashion. Also, the number of elements needs to be temporarily saved * to call get_ele_list(). If that function was changed to pass in * the number of points to be read, the memory set aside inside the * ProgConfig structure could be removed. */ /* * The next six function calls could be combined into one, then use * shifts and masks to retrieve the individual fields. */ temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream); pScratchPCE->front.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream); pScratchPCE->side.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream); pScratchPCE->back.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_LFE, pInputStream); pScratchPCE->lfe.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_DAT, pInputStream); pScratchPCE->data.num_ele = temp; /* Needed only to read in the element list. */ temp = get9_n_lessbits(LEN_NUM_CCE, pInputStream); pScratchPCE->coupling.num_ele = temp; /* * Read in mix down data. * * Whether these fields can be removed and have proper operation * will be determined at a later date. */ /* Read presence of mono_mix */ flag = get1bits(pInputStream);/* LEN_MIX_PRES,*/ pScratchPCE->mono_mix.present = flag; if (flag != FALSE) { temp = get9_n_lessbits(LEN_TAG, pInputStream); pScratchPCE->mono_mix.ele_tag = temp; } /* end if (flag != FALSE) */ /* Read presence of stereo mix */ flag = get1bits(pInputStream); /* LEN_MIX_PRES,*/ pScratchPCE->stereo_mix.present = flag; if (flag != FALSE) { temp = get9_n_lessbits(LEN_TAG, pInputStream); pScratchPCE->stereo_mix.ele_tag = temp; } /* end if (flag != FALSE) */ /* Read presence of matrix mix */ flag = get1bits(pInputStream); /* LEN_MIX_PRES,*/ pScratchPCE->matrix_mix.present = flag; if (flag != FALSE) { temp = get9_n_lessbits(LEN_MMIX_IDX, pInputStream); pScratchPCE->matrix_mix.ele_tag = temp; temp = get1bits(pInputStream); /* LEN_PSUR_ENAB,*/ pScratchPCE->matrix_mix.pseudo_enab = temp; } /* end if (flag != FALSE) */ /* * Get each of the element lists. Only the front information will be * used for the PV decoder, but the usedBits field of pInputStream must * be advanced appropriately. * * This could be optimized by advancing the bit stream for the * elements that do not need to be read. */ get_ele_list(&pScratchPCE->front, pInputStream, TRUE); get_ele_list(&pScratchPCE->side, pInputStream, TRUE); get_ele_list(&pScratchPCE->back, pInputStream, TRUE); get_ele_list(&pScratchPCE->lfe, pInputStream, FALSE); get_ele_list(&pScratchPCE->data, pInputStream, FALSE); get_ele_list(&pScratchPCE->coupling, pInputStream, TRUE); /* * The standard requests a byte alignment before reading in the * comment. This can be done because LEN_COMMENT_BYTES == 8. */ byte_align(pInputStream); numChars = get9_n_lessbits(LEN_COMMENT_BYTES, pInputStream); /* * Ignore the comment - it requires 65 bytes to store (or worse on DSP). * If this field is restored, make sure to append a trailing '\0' */ for (i = numChars; i > 0; i--) { pScratchPCE->comments[i] = (Char) get9_n_lessbits(LEN_BYTE, pInputStream); } /* end for */ if (pVars->current_program < 0) { /* * If this is the first PCE, it becomes the current, regardless of * its tag number. */ pVars->current_program = tag; pVars->mc_info.ch_info[0].tag = 0; } /* end if (pVars->current_program < 0) */ if (tag == (UInt)pVars->current_program) { /* * This branch is reached under two conditions: * 1) This is the first PCE found, it was selected in the above if * block. In all encoders found thus far, the tag value has been * zero. * 2) A PCE has been sent by the encoder with a tag that matches the * the first one sent. It will then be re-read. No encoder found * * Regardless, the temporary PCE will now be copied into the * the one official program configuration. */ /* * Keep adts setting in case of a redundant PCE (only applicable when * using aac-lib own adts parser) */ pScratchPCE->file_is_adts = pVars->prog_config.file_is_adts; pScratchPCE->headerless_frames = pVars->prog_config.headerless_frames; pv_memcpy(&pVars->prog_config, pScratchPCE, sizeof(ProgConfig)); tag = 0; /* * Check that dual-mono does not carry more than 2 tracks, otherwise flag an non-supported error */ if ((pVars->prog_config.front.num_ele > 2) && !(pVars->prog_config.front.ele_is_cpe[tag])) { status = 1; } /* * Check that stereo does not carry more than 1 track, otherwise flag an non-supported error */ if ((pVars->prog_config.front.num_ele > 1) && (pVars->prog_config.front.ele_is_cpe[tag])) { status = 1; } if (!status) { /* enter configuration into MC_Info structure */ status = set_mc_info(&pVars->mc_info, (tMP4AudioObjectType)(pVars->prog_config.profile + 1), pVars->prog_config.sampling_rate_idx, pVars->prog_config.front.ele_tag[tag], pVars->prog_config.front.ele_is_cpe[tag], pVars->winmap, pVars->SFBWidth128); if (pVars->mc_info.upsamplingFactor == 2) { /* * prog_config.sampling_rate_idx corresponds to the aac base layer, * if the upsampling factor is active, then the output frequency needs * to be adjusted accordingly */ pVars->prog_config.sampling_rate_idx -= 3; } } } /* end if (tag == pVars->current_program) */ return (status); }
/*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ Int huffdecode( Int id_syn_ele, BITS *pInputStream, tDec_Int_File *pVars, tDec_Int_Chan *pChVars[]) { /*---------------------------------------------------------------------------- ; Define all local variables ----------------------------------------------------------------------------*/ Int ch; Int common_window; Int hasmask; Int status = SUCCESS; Int num_channels = 0; MC_Info *pMcInfo; per_chan_share_w_fxpCoef *pChLeftShare; /* Helper pointer */ per_chan_share_w_fxpCoef *pChRightShare; /* Helper pointer */ /*---------------------------------------------------------------------------- ; Function body here ----------------------------------------------------------------------------*/ get9_n_lessbits( LEN_TAG, pInputStream); /* suppose an un-supported id_syn_ele will never be passed */ common_window = 0; if (id_syn_ele == ID_CPE) { common_window = get1bits(pInputStream); } pMcInfo = &pVars->mc_info; /* * check if provided info (num of channels) on audio config, * matches read bitstream data, if not, allow update only once. * In almost all cases it should match. */ #if 0 if ((pMcInfo->ch_info[0].cpe != id_syn_ele)) { if (pVars->mc_info.implicit_channeling) /* check done only once */ { pMcInfo->ch_info[0].cpe = id_syn_ele & 1; /* collect info from bitstream * implicit_channeling flag is locked * after 1st frame, to avoid toggling * parameter in the middle of the clip */ pMcInfo->nch = (id_syn_ele & 1) + 1; /* update number of channels */ } else { status = 1; /* ERROR break if syntax error persist */ } } #endif if (status == SUCCESS) { if (id_syn_ele == ID_SCE) { num_channels = 1; pVars->hasmask = 0; } else if (id_syn_ele == ID_CPE) { pChLeftShare = pChVars[LEFT]->pShareWfxpCoef; pChRightShare = pChVars[RIGHT]->pShareWfxpCoef; num_channels = 2; if (common_window != FALSE) { status = get_ics_info( (tMP4AudioObjectType) pVars->mc_info.audioObjectType, pInputStream, (Bool)common_window, (WINDOW_SEQUENCE *) & pChVars[LEFT]->wnd, (WINDOW_SHAPE *) & pChVars[LEFT]->wnd_shape_this_bk, pChLeftShare->group, (Int *) & pChLeftShare->max_sfb, pVars->winmap, (LT_PRED_STATUS *) & pChLeftShare->lt_status, (LT_PRED_STATUS *) & pChRightShare->lt_status); if (status == SUCCESS) { /* copy left channel info to right channel */ pChVars[RIGHT]->wnd = pChVars[LEFT]->wnd; pChVars[RIGHT]->wnd_shape_this_bk = pChVars[LEFT]->wnd_shape_this_bk; pChRightShare->max_sfb = pChLeftShare->max_sfb; pv_memcpy( pChRightShare->group, pChLeftShare->group, NSHORT*sizeof(pChLeftShare->group[0])); hasmask = getmask( pVars->winmap[pChVars[LEFT]->wnd], pInputStream, pChLeftShare->group, pChLeftShare->max_sfb, pVars->mask); if (hasmask == MASK_ERROR) { status = 1; /* ERROR code */ } pVars->hasmask = hasmask; } /* if (status == 0) */ } else { pVars->hasmask = 0; } /* if (common_window) */ } /* if (id_syn_ele) */ else if (id_syn_ele == ID_LFE) { num_channels = 1; pVars->hasmask = 0; } /* if (id_syn_ele) == ID_LFE */ } /* if (status) */ ch = 0; while ((ch < num_channels) && (status == SUCCESS)) { pChLeftShare = pChVars[ch]->pShareWfxpCoef; status = getics( pInputStream, common_window, pVars, pChVars[ch], pChLeftShare->group, &pChLeftShare->max_sfb, pChLeftShare->cb_map, &pChLeftShare->tns, pVars->winmap, &pVars->share.a.pulseInfo, pVars->share.a.sect); ch++; } /* while (ch) */ /*---------------------------------------------------------------------------- ; Return status ----------------------------------------------------------------------------*/ return status; } /* huffdecode */
void pvmp3_reorder(int32 xr[SUBBANDS_NUMBER*FILTERBANK_BANDS], granuleInfo *gr_info, int32 *used_freq_lines, mp3Header *info, int32 Scratch_mem[168]) { int32 sfreq = info->version_x + (info->version_x << 1); sfreq += info->sampling_frequency; if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { int32 sfb_lines; int32 freq; int32 src_line; int32 sfb; if (gr_info->mixed_block_flag) { /* REORDERING FOR REST SWITCHED SHORT */ sfb = 3; /* no reorder for low 2 subbands */ src_line = 36; } else { /* pure short */ sfb = 0; src_line = 0; } int16 ct = src_line; for (; sfb < 13; sfb++) { if (*used_freq_lines > 3*mp3_sfBandIndex[sfreq].s[sfb+1]) { sfb_lines = mp3_sfBandIndex[sfreq].s[sfb+1] - mp3_sfBandIndex[sfreq].s[sfb]; for (freq = 0; freq < 3*sfb_lines; freq += 3) { int32 tmp1 = xr[src_line]; int32 tmp2 = xr[src_line+(sfb_lines)]; int32 tmp3 = xr[src_line+(sfb_lines<<1)]; src_line++; Scratch_mem[freq ] = tmp1; Scratch_mem[freq+1] = tmp2; Scratch_mem[freq+2] = tmp3; } src_line += (sfb_lines << 1); pv_memcpy(&xr[ct], Scratch_mem, sfb_lines*3*sizeof(int32)); ct += sfb_lines + (sfb_lines << 1); } else { sfb_lines = mp3_sfBandIndex[sfreq].s[sfb+1] - mp3_sfBandIndex[sfreq].s[sfb]; for (freq = 0; freq < 3*sfb_lines; freq += 3) { int32 tmp1 = xr[src_line]; int32 tmp2 = xr[src_line+(sfb_lines)]; int32 tmp3 = xr[src_line+(sfb_lines<<1)]; src_line++; Scratch_mem[freq ] = tmp1; Scratch_mem[freq+1] = tmp2; Scratch_mem[freq+2] = tmp3; } pv_memcpy(&xr[ct], Scratch_mem, sfb_lines*3*sizeof(int32)); *used_freq_lines = mp3_sfBandIndex[sfreq].s[sfb+1] * 3; sfb = 13; /* force out of the for-loop */ } } } }
void low_pass_filt_7k( int16 signal[], /* input: signal */ int16 lg, /* input: length of input */ int16 mem[], /* in/out: memory (size=30) */ int16 x[] ) { int16 i, j; int32 L_tmp1; int32 L_tmp2; int32 L_tmp3; int32 L_tmp4; pv_memcpy((void *)x, (void *)mem, (L_FIR)*sizeof(*x)); for (i = 0; i < lg >> 2; i++) { x[(i<<2) + L_FIR ] = signal[(i<<2)]; x[(i<<2) + L_FIR + 1] = signal[(i<<2)+1]; x[(i<<2) + L_FIR + 2] = signal[(i<<2)+2]; x[(i<<2) + L_FIR + 3] = signal[(i<<2)+3]; L_tmp1 = fxp_mac_16by16(x[(i<<2)] + signal[(i<<2)], fir_7k[0], 0x00004000); L_tmp2 = fxp_mac_16by16(x[(i<<2)+1] + signal[(i<<2)+1], fir_7k[0], 0x00004000); L_tmp3 = fxp_mac_16by16(x[(i<<2)+2] + signal[(i<<2)+2], fir_7k[0], 0x00004000); L_tmp4 = fxp_mac_16by16(x[(i<<2)+3] + signal[(i<<2)+3], fir_7k[0], 0x00004000); for (j = 1; j < L_FIR - 1; j += 4) { int16 tmp1 = x[(i<<2)+j ]; int16 tmp2 = x[(i<<2)+j+1]; int16 tmp3 = x[(i<<2)+j+2]; L_tmp1 = fxp_mac_16by16(tmp1, fir_7k[j ], L_tmp1); L_tmp2 = fxp_mac_16by16(tmp2, fir_7k[j ], L_tmp2); L_tmp1 = fxp_mac_16by16(tmp2, fir_7k[j+1], L_tmp1); L_tmp2 = fxp_mac_16by16(tmp3, fir_7k[j+1], L_tmp2); L_tmp3 = fxp_mac_16by16(tmp3, fir_7k[j ], L_tmp3); L_tmp1 = fxp_mac_16by16(tmp3, fir_7k[j+2], L_tmp1); tmp1 = x[(i<<2)+j+3]; tmp2 = x[(i<<2)+j+4]; L_tmp2 = fxp_mac_16by16(tmp1, fir_7k[j+2], L_tmp2); L_tmp4 = fxp_mac_16by16(tmp1, fir_7k[j ], L_tmp4); L_tmp3 = fxp_mac_16by16(tmp1, fir_7k[j+1], L_tmp3); L_tmp1 = fxp_mac_16by16(tmp1, fir_7k[j+3], L_tmp1); L_tmp2 = fxp_mac_16by16(tmp2, fir_7k[j+3], L_tmp2); L_tmp4 = fxp_mac_16by16(tmp2, fir_7k[j+1], L_tmp4); L_tmp3 = fxp_mac_16by16(tmp2, fir_7k[j+2], L_tmp3); tmp1 = x[(i<<2)+j+5]; tmp2 = x[(i<<2)+j+6]; L_tmp4 = fxp_mac_16by16(tmp1, fir_7k[j+2], L_tmp4); L_tmp3 = fxp_mac_16by16(tmp1, fir_7k[j+3], L_tmp3); L_tmp4 = fxp_mac_16by16(tmp2, fir_7k[j+3], L_tmp4); } L_tmp1 = fxp_mac_16by16(x[(i<<2)+j ], fir_7k[j ], L_tmp1); L_tmp2 = fxp_mac_16by16(x[(i<<2)+j+1], fir_7k[j ], L_tmp2); L_tmp3 = fxp_mac_16by16(x[(i<<2)+j+2], fir_7k[j ], L_tmp3); L_tmp4 = fxp_mac_16by16(x[(i<<2)+j+3], fir_7k[j ], L_tmp4); signal[(i<<2)] = (int16)(L_tmp1 >> 15); signal[(i<<2)+1] = (int16)(L_tmp2 >> 15); signal[(i<<2)+2] = (int16)(L_tmp3 >> 15); signal[(i<<2)+3] = (int16)(L_tmp4 >> 15); } pv_memcpy((void *)mem, (void *)(x + lg), (L_FIR)*sizeof(*mem)); return; }
void sbr_dec(Int16 *inPcmData, Int16 *ftimeOutPtr, SBR_FRAME_DATA * hFrameData, int32_t applyProcessing, SBR_DEC *sbrDec, #ifdef HQ_SBR #ifdef PARAMETRICSTEREO Int16 * ftimeOutPtrPS, HANDLE_PS_DEC hParametricStereoDec, #endif #endif tDec_Int_File *pVars) { int32_t i; int32_t j; int32_t m; int32_t *frameInfo = hFrameData->frameInfo; Int num_qmf_bands; #ifdef HQ_SBR #ifdef PARAMETRICSTEREO int32_t env; int32_t *qmf_PS_generated_Real; int32_t *qmf_PS_generated_Imag; int32_t *Sr_x; int32_t *Si_x; #endif #endif int32_t(*scratch_mem)[64]; Int16 *circular_buffer_s; int32_t k; int32_t *Sr; int32_t *Si; int32_t *ptr_tmp1; int32_t *ptr_tmp2; scratch_mem = pVars->scratch.scratch_mem; if (applyProcessing) { num_qmf_bands = sbrDec->lowSubband; } else { num_qmf_bands = 32; /* becomes a resampler by 2 */ } /* -------------------------------------------------- */ /* * Re-Load Buffers */ pv_memmove(&hFrameData->sbrQmfBufferReal[0], &hFrameData->HistsbrQmfBufferReal[0], 6*SBR_NUM_BANDS*sizeof(*hFrameData->sbrQmfBufferReal)); #ifdef HQ_SBR if (sbrDec->LC_aacP_DecoderFlag == OFF) { pv_memmove(&hFrameData->sbrQmfBufferImag[0], &hFrameData->HistsbrQmfBufferImag[0], 6*SBR_NUM_BANDS*sizeof(*hFrameData->sbrQmfBufferImag)); } #endif /* -------------------------------------------------- */ /* * low band codec signal subband filtering */ for (i = 0; i < 32; i++) { if (sbrDec->LC_aacP_DecoderFlag == ON) { calc_sbr_anafilterbank_LC(hFrameData->codecQmfBufferReal[sbrDec->bufWriteOffs + i], &inPcmData[319] + (i << 5), scratch_mem, num_qmf_bands); } #ifdef HQ_SBR else { calc_sbr_anafilterbank(hFrameData->codecQmfBufferReal[sbrDec->bufWriteOffs + i], hFrameData->codecQmfBufferImag[sbrDec->bufWriteOffs + i], &inPcmData[319] + (i << 5), scratch_mem, num_qmf_bands); } #endif } if (pVars->ltp_buffer_state) { pv_memcpy(&inPcmData[-1024-288], &inPcmData[1024], 288*sizeof(*inPcmData)); } else { pv_memcpy(&inPcmData[1024 + 288], &inPcmData[1024], 288*sizeof(*inPcmData)); } if (applyProcessing) { /* * Inverse filtering of lowband + HF generation */ if (sbrDec->LC_aacP_DecoderFlag == ON) { sbr_generate_high_freq((int32_t(*)[32])(hFrameData->codecQmfBufferReal + sbrDec->bufReadOffs), NULL, (int32_t *)(hFrameData->sbrQmfBufferReal), NULL, hFrameData->sbr_invf_mode, hFrameData->sbr_invf_mode_prev, &(sbrDec->FreqBandTableNoise[1]), sbrDec->NoNoiseBands, sbrDec->lowSubband, sbrDec->V_k_master, sbrDec->Num_Master, sbrDec->outSampleRate, frameInfo, hFrameData->degreeAlias, scratch_mem, hFrameData->BwVector,/* */ hFrameData->BwVectorOld, &(sbrDec->Patch), sbrDec->LC_aacP_DecoderFlag, &(sbrDec->highSubband)); /* * Adjust envelope of current frame. */ calc_sbr_envelope(hFrameData, (int32_t *)(hFrameData->sbrQmfBufferReal), NULL, sbrDec->FreqBandTable, sbrDec->NSfb, sbrDec->FreqBandTableNoise, sbrDec->NoNoiseBands, hFrameData->reset_flag, hFrameData->degreeAlias, &(hFrameData->harm_index), &(hFrameData->phase_index), hFrameData->hFp, &(hFrameData->sUp), sbrDec->limSbc, sbrDec->gateMode, #ifdef HQ_SBR NULL, NULL, NULL, NULL, #endif scratch_mem, sbrDec->Patch, sbrDec->sqrt_cache, sbrDec->LC_aacP_DecoderFlag); } #ifdef HQ_SBR else { sbr_generate_high_freq((int32_t(*)[32])(hFrameData->codecQmfBufferReal + sbrDec->bufReadOffs), (int32_t(*)[32])(hFrameData->codecQmfBufferImag + sbrDec->bufReadOffs), (int32_t *)(hFrameData->sbrQmfBufferReal), (int32_t *)(hFrameData->sbrQmfBufferImag), hFrameData->sbr_invf_mode, hFrameData->sbr_invf_mode_prev, &(sbrDec->FreqBandTableNoise[1]), sbrDec->NoNoiseBands, sbrDec->lowSubband, sbrDec->V_k_master, sbrDec->Num_Master, sbrDec->outSampleRate, frameInfo, NULL, scratch_mem, hFrameData->BwVector, hFrameData->BwVectorOld, &(sbrDec->Patch), sbrDec->LC_aacP_DecoderFlag, &(sbrDec->highSubband)); /* * Adjust envelope of current frame. */ calc_sbr_envelope(hFrameData, (int32_t *)(hFrameData->sbrQmfBufferReal), (int32_t *)(hFrameData->sbrQmfBufferImag), sbrDec->FreqBandTable, sbrDec->NSfb, sbrDec->FreqBandTableNoise, sbrDec->NoNoiseBands, hFrameData->reset_flag, NULL, &(hFrameData->harm_index), &(hFrameData->phase_index), hFrameData->hFp, &(hFrameData->sUp), sbrDec->limSbc, sbrDec->gateMode, hFrameData->fBuf_man, hFrameData->fBuf_exp, hFrameData->fBufN_man, hFrameData->fBufN_exp, scratch_mem, sbrDec->Patch, sbrDec->sqrt_cache, sbrDec->LC_aacP_DecoderFlag); } #endif } else /* else for applyProcessing */ { /* no sbr, set high band buffers to zero */ for (i = 0; i < SBR_NUM_COLUMNS; i++) { pv_memset((void *)&hFrameData->sbrQmfBufferReal[i*SBR_NUM_BANDS], 0, SBR_NUM_BANDS*sizeof(*hFrameData->sbrQmfBufferReal)); #ifdef HQ_SBR pv_memset((void *)&hFrameData->sbrQmfBufferImag[i*SBR_NUM_BANDS], 0, SBR_NUM_BANDS*sizeof(*hFrameData->sbrQmfBufferImag)); #endif } } /* * Synthesis subband filtering. */ #ifdef HQ_SBR #ifdef PARAMETRICSTEREO /* * psPresentFlag set implies hParametricStereoDec !=NULL, second condition is * is just here to prevent CodeSonar warnings. */ if ((pVars->mc_info.psPresentFlag) && (applyProcessing) && (hParametricStereoDec != NULL)) { /* * qmfBufferReal uses the rigth aac channel ( perChan[1] is not used) * followed by the buffer fxpCoef[2][2048] which makes a total of * 2349 + 2048*2 = 6445 * These 2 matrices (qmfBufferReal & qmfBufferImag) are * [2][38][64] == 4864 int32_t */ tDec_Int_Chan *tmpx = &pVars->perChan[1]; /* * dereferencing type-punned pointer avoid * breaking strict-aliasing rules */ int32_t *tmp = (int32_t *)tmpx; hParametricStereoDec->qmfBufferReal = (int32_t(*)[64]) tmp; tmp = (int32_t *) & hParametricStereoDec->qmfBufferReal[38][0]; hParametricStereoDec->qmfBufferImag = (int32_t(*)[64]) tmp; for (i = 0; i < 32; i++) { Int xoverBand; if (i < ((hFrameData->frameInfo[1]) << 1)) { xoverBand = sbrDec->prevLowSubband; } else { xoverBand = sbrDec->lowSubband; } if (xoverBand > sbrDec->highSubband) { xoverBand = 32; /* error condition, default to upsampling mode */ } m = sbrDec->bufReadOffs + i; /* 2 + i */ Sr_x = hParametricStereoDec->qmfBufferReal[i]; Si_x = hParametricStereoDec->qmfBufferImag[i]; for (int32_t j = 0; j < xoverBand; j++) { Sr_x[j] = shft_lft_1(hFrameData->codecQmfBufferReal[m][j]); Si_x[j] = shft_lft_1(hFrameData->codecQmfBufferImag[m][j]); } pv_memcpy(&Sr_x[xoverBand], &hFrameData->sbrQmfBufferReal[i*SBR_NUM_BANDS], (sbrDec->highSubband - xoverBand)*sizeof(*Sr_x)); pv_memcpy(&Si_x[xoverBand], &hFrameData->sbrQmfBufferImag[i*SBR_NUM_BANDS], (sbrDec->highSubband - xoverBand)*sizeof(*Si_x)); pv_memset((void *)&Sr_x[sbrDec->highSubband], 0, (64 - sbrDec->highSubband)*sizeof(*Sr_x)); pv_memset((void *)&Si_x[sbrDec->highSubband], 0, (64 - sbrDec->highSubband)*sizeof(*Si_x)); } for (i = 32; i < 32 + 6; i++) { m = sbrDec->bufReadOffs + i; /* 2 + i */ for (int32_t j = 0; j < 5; j++) { hParametricStereoDec->qmfBufferReal[i][j] = shft_lft_1(hFrameData->codecQmfBufferReal[m][j]); hParametricStereoDec->qmfBufferImag[i][j] = shft_lft_1(hFrameData->codecQmfBufferImag[m][j]); } } /* * Update Buffers */ for (i = 0; i < sbrDec->bufWriteOffs; i++) /* sbrDec->bufWriteOffs set to 8 and unchanged */ { j = sbrDec->noCols + i; /* sbrDec->noCols set to 32 and unchanged */ pv_memmove(hFrameData->codecQmfBufferReal[i], /* to */ hFrameData->codecQmfBufferReal[j], /* from */ sizeof(*hFrameData->codecQmfBufferReal[i]) << 5); pv_memmove(hFrameData->codecQmfBufferImag[i], hFrameData->codecQmfBufferImag[j], sizeof(*hFrameData->codecQmfBufferImag[i]) << 5); } pv_memmove(&hFrameData->HistsbrQmfBufferReal[0], &hFrameData->sbrQmfBufferReal[32*SBR_NUM_BANDS], 6*SBR_NUM_BANDS*sizeof(*hFrameData->sbrQmfBufferReal)); pv_memmove(&hFrameData->HistsbrQmfBufferImag[0], &hFrameData->sbrQmfBufferImag[32*SBR_NUM_BANDS], 6*SBR_NUM_BANDS*sizeof(*hFrameData->sbrQmfBufferImag)); /* * Needs whole QMF matrix formed before applying * Parametric stereo processing. */ qmf_PS_generated_Real = scratch_mem[0]; qmf_PS_generated_Imag = scratch_mem[1]; env = 0; /* * Set circular buffer for Left channel */ circular_buffer_s = (Int16 *)scratch_mem[7]; if (pVars->mc_info.bDownSampledSbr) { pv_memmove(&circular_buffer_s[2048], hFrameData->V, 640*sizeof(*circular_buffer_s)); } else { pv_memmove(&circular_buffer_s[4096], hFrameData->V, 1152*sizeof(*circular_buffer_s)); } /* * Set Circular buffer for PS hybrid analysis */ for (i = 0, j = 0; i < 3; i++) { pv_memmove(&scratch_mem[2][32 + j ], hParametricStereoDec->hHybrid->mQmfBufferReal[i], HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferReal)); pv_memmove(&scratch_mem[2][32 + j + 44], hParametricStereoDec->hHybrid->mQmfBufferImag[i], HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferImag)); j += 88; } pv_memset((void *)&qmf_PS_generated_Real[hParametricStereoDec->usb], 0, (64 - hParametricStereoDec->usb)*sizeof(*qmf_PS_generated_Real)); pv_memset((void *)&qmf_PS_generated_Imag[hParametricStereoDec->usb], 0, (64 - hParametricStereoDec->usb)*sizeof(*qmf_PS_generated_Imag)); for (i = 0; i < 32; i++) { if (i == (Int)hParametricStereoDec-> aEnvStartStop[env]) { ps_init_stereo_mixing(hParametricStereoDec, env, sbrDec->highSubband); env++; } ps_applied(hParametricStereoDec, &hParametricStereoDec->qmfBufferReal[i], &hParametricStereoDec->qmfBufferImag[i], qmf_PS_generated_Real, qmf_PS_generated_Imag, scratch_mem[2], i); /* Create time samples for regular mono channel */ if (pVars->mc_info.bDownSampledSbr) { calc_sbr_synfilterbank(hParametricStereoDec->qmfBufferReal[i], /* realSamples */ hParametricStereoDec->qmfBufferImag[i], /* imagSamples */ ftimeOutPtr + (i << 6), &circular_buffer_s[1984 - (i<<6)], pVars->mc_info.bDownSampledSbr); } else { calc_sbr_synfilterbank(hParametricStereoDec->qmfBufferReal[i], /* realSamples */ hParametricStereoDec->qmfBufferImag[i], /* imagSamples */ ftimeOutPtr + (i << 7), &circular_buffer_s[3968 - (i<<7)], pVars->mc_info.bDownSampledSbr); } pv_memmove(hParametricStereoDec->qmfBufferReal[i], qmf_PS_generated_Real, 64*sizeof(*qmf_PS_generated_Real)); pv_memmove(hParametricStereoDec->qmfBufferImag[i], qmf_PS_generated_Imag, 64*sizeof(*qmf_PS_generated_Real)); } /* * Save Circular buffer history used on PS hybrid analysis */ for (i = 0, j = 0; i < 3; i++) { pv_memmove(hParametricStereoDec->hHybrid->mQmfBufferReal[i], &scratch_mem[2][ 64 + j ], HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferReal)); pv_memmove(hParametricStereoDec->hHybrid->mQmfBufferImag[i], &scratch_mem[2][ 64 + j + 44], HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferImag)); j += 88; } pv_memmove(hFrameData->V, &circular_buffer_s[0], 1152*sizeof(*circular_buffer_s)); /* * Set circular buffer for Right channel */ circular_buffer_s = (Int16 *)scratch_mem[5]; if (pVars->mc_info.bDownSampledSbr) { pv_memmove(&circular_buffer_s[2048], (int32_t *)hParametricStereoDec->R_ch_qmf_filter_history, 640*sizeof(*circular_buffer_s)); } else { pv_memmove(&circular_buffer_s[4096], (int32_t *)hParametricStereoDec->R_ch_qmf_filter_history, 1152*sizeof(*circular_buffer_s)); } for (i = 0; i < 32; i++) { if (pVars->mc_info.bDownSampledSbr) { calc_sbr_synfilterbank(hParametricStereoDec->qmfBufferReal[i], /* realSamples */ hParametricStereoDec->qmfBufferImag[i], /* imagSamples */ ftimeOutPtrPS + (i << 6), &circular_buffer_s[1984 - (i<<6)], pVars->mc_info.bDownSampledSbr); } else { calc_sbr_synfilterbank(hParametricStereoDec->qmfBufferReal[i], /* realSamples */ hParametricStereoDec->qmfBufferImag[i], /* imagSamples */ ftimeOutPtrPS + (i << 7), &circular_buffer_s[3968 - (i<<7)], pVars->mc_info.bDownSampledSbr); } } if (pVars->mc_info.bDownSampledSbr) { pv_memmove((int32_t *)hParametricStereoDec->R_ch_qmf_filter_history, &circular_buffer_s[0], 640*sizeof(*circular_buffer_s)); } else { pv_memmove((int32_t *)hParametricStereoDec->R_ch_qmf_filter_history, &circular_buffer_s[0], 1152*sizeof(*circular_buffer_s)); } } else /* else -- sbrEnablePS */ { #endif /* PARAMETRICSTEREO */ #endif /* HQ_SBR */ /* * Use shared aac memory as continuous buffer */ Sr = scratch_mem[0]; Si = scratch_mem[1]; circular_buffer_s = (Int16*)scratch_mem[2]; if (pVars->mc_info.bDownSampledSbr) { pv_memmove(&circular_buffer_s[2048], hFrameData->V, 640*sizeof(*circular_buffer_s)); } else { pv_memmove(&circular_buffer_s[4096], hFrameData->V, 1152*sizeof(*circular_buffer_s)); } for (i = 0; i < 32; i++) { Int xoverBand; if (applyProcessing) { if (i < ((hFrameData->frameInfo[1]) << 1)) { xoverBand = sbrDec->prevLowSubband; } else { xoverBand = sbrDec->lowSubband; } if (xoverBand > sbrDec->highSubband) { xoverBand = 32; /* error condition, default to upsampling mode */ } } else { xoverBand = 32; sbrDec->highSubband = 32; } m = sbrDec->bufReadOffs + i; /* sbrDec->bufReadOffs == 2 */ ptr_tmp1 = (hFrameData->codecQmfBufferReal[m]); ptr_tmp2 = Sr; if (sbrDec->LC_aacP_DecoderFlag == ON) { for (k = (xoverBand >> 1); k != 0; k--) { *(ptr_tmp2++) = (*(ptr_tmp1++)) >> 9; *(ptr_tmp2++) = (*(ptr_tmp1++)) >> 9; } if (xoverBand & 1) { *(ptr_tmp2++) = (*(ptr_tmp1)) >> 9; } ptr_tmp1 = &hFrameData->sbrQmfBufferReal[i*SBR_NUM_BANDS]; for (k = xoverBand; k < sbrDec->highSubband; k++) { *(ptr_tmp2++) = (*(ptr_tmp1++)) << 1; } pv_memset((void *)ptr_tmp2, 0, (64 - sbrDec->highSubband)*sizeof(*ptr_tmp2)); if (pVars->mc_info.bDownSampledSbr) { calc_sbr_synfilterbank_LC(Sr, /* realSamples */ ftimeOutPtr + (i << 6), &circular_buffer_s[1984 - (i<<6)], pVars->mc_info.bDownSampledSbr); } else { calc_sbr_synfilterbank_LC(Sr, /* realSamples */ ftimeOutPtr + (i << 7), &circular_buffer_s[3968 - (i<<7)], pVars->mc_info.bDownSampledSbr); } } #ifdef HQ_SBR else { for (k = xoverBand; k != 0; k--) { *(ptr_tmp2++) = shft_lft_1(*(ptr_tmp1++)); } ptr_tmp1 = &hFrameData->sbrQmfBufferReal[i*SBR_NUM_BANDS]; ptr_tmp2 = &Sr[xoverBand]; for (k = xoverBand; k < sbrDec->highSubband; k++) { *(ptr_tmp2++) = (*(ptr_tmp1++)); } pv_memset((void *)ptr_tmp2, 0, (64 - sbrDec->highSubband)*sizeof(*ptr_tmp2)); ptr_tmp1 = (hFrameData->codecQmfBufferImag[m]); ptr_tmp2 = Si; for (k = (xoverBand >> 1); k != 0; k--) { *(ptr_tmp2++) = shft_lft_1(*(ptr_tmp1++)); *(ptr_tmp2++) = shft_lft_1(*(ptr_tmp1++)); } if (xoverBand & 1) { *(ptr_tmp2) = shft_lft_1(*(ptr_tmp1)); } ptr_tmp1 = &hFrameData->sbrQmfBufferImag[i*SBR_NUM_BANDS]; ptr_tmp2 = &Si[xoverBand]; for (k = xoverBand; k < sbrDec->highSubband; k++) { *(ptr_tmp2++) = (*(ptr_tmp1++)); } pv_memset((void *)ptr_tmp2, 0, (64 - sbrDec->highSubband)*sizeof(*ptr_tmp2)); if (pVars->mc_info.bDownSampledSbr) { calc_sbr_synfilterbank(Sr, /* realSamples */ Si, /* imagSamples */ ftimeOutPtr + (i << 6), &circular_buffer_s[1984 - (i<<6)], pVars->mc_info.bDownSampledSbr); } else { calc_sbr_synfilterbank(Sr, /* realSamples */ Si, /* imagSamples */ ftimeOutPtr + (i << 7), &circular_buffer_s[3968 - (i<<7)], pVars->mc_info.bDownSampledSbr); } } #endif }
/*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ void deinterleave( Int16 interleaved[], Int16 deinterleaved[], FrameInfo *pFrameInfo) { Int group; /* group index */ Int sfb; /* scalefactor band index */ Int win; /* window index */ Int16 *pGroup; Int16 *pWin; Int16 *pStart; Int16 *pInterleaved; Int16 *pDeinterleaved; Int sfb_inc; Int ngroups; Int *pGroupLen; Int *pSfbPerWin; Int *pSfbWidth; pInterleaved = interleaved; pDeinterleaved = deinterleaved; pSfbPerWin = pFrameInfo->sfb_per_win; ngroups = pFrameInfo->num_groups; pGroupLen = pFrameInfo->group_len; pGroup = pDeinterleaved; for (group = ngroups; group > 0; group--) { pSfbWidth = pFrameInfo->sfb_width_128; sfb_inc = 0; pStart = pInterleaved; /* Perform the deinterleaving across all windows in a group */ for (sfb = pSfbPerWin[ngroups-group]; sfb > 0; sfb--) { pWin = pGroup; for (win = pGroupLen[ngroups-group]; win > 0; win--) { pDeinterleaved = pWin + sfb_inc; pv_memcpy( pDeinterleaved, pInterleaved, *pSfbWidth*sizeof(*pInterleaved)); pInterleaved += *pSfbWidth; pWin += SN2; } /* for (win) */ sfb_inc += *pSfbWidth++; } /* for (sfb) */ pGroup += (pInterleaved - pStart); } /* for (group) */ } /* deinterleave */