/*! \brief resets sbr decoder structure \return errorCode, 0 if successful */ SBR_ERROR resetSbrDec (HANDLE_SBR_DEC hSbrDec, HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, const int useLP, const int downsampleFac ) { SBR_ERROR sbrError = SBRDEC_OK; int old_lsb = hSbrDec->SynthesisQMF.lsb; int new_lsb = hHeaderData->freqBandData.lowSubband; int l, startBand, stopBand, startSlot, size; int source_scale, target_scale, delta_scale, target_lsb, target_usb, reserve; FIXP_DBL maxVal; /* overlapBuffer point to first (6) slots */ FIXP_DBL **OverlapBufferReal = hSbrDec->QmfBufferReal; FIXP_DBL **OverlapBufferImag = hSbrDec->QmfBufferImag; /* assign qmf time slots */ assignTimeSlots( hSbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, useLP); resetSbrEnvelopeCalc (&hSbrDec->SbrCalculateEnvelope); hSbrDec->SynthesisQMF.lsb = hHeaderData->freqBandData.lowSubband; hSbrDec->SynthesisQMF.usb = fixMin((INT)hSbrDec->SynthesisQMF.no_channels, (INT)hHeaderData->freqBandData.highSubband); hSbrDec->AnalysiscQMF.lsb = hSbrDec->SynthesisQMF.lsb; hSbrDec->AnalysiscQMF.usb = hSbrDec->SynthesisQMF.usb; /* The following initialization of spectral data in the overlap buffer is required for dynamic x-over or a change of the start-freq for 2 reasons: 1. If the lowband gets _wider_, unadjusted data would remain 2. If the lowband becomes _smaller_, the highest bands of the old lowband must be cleared because the whitening would be affected */ startBand = old_lsb; stopBand = new_lsb; startSlot = hHeaderData->timeStep * (hPrevFrameData->stopPos - hHeaderData->numberTimeSlots); size = fixMax(0,stopBand-startBand); /* keep already adjusted data in the x-over-area */ if (!useLP) { for (l=startSlot; l<hSbrDec->LppTrans.pSettings->overlap; l++) { FDKmemclear(&OverlapBufferReal[l][startBand], size*sizeof(FIXP_DBL)); FDKmemclear(&OverlapBufferImag[l][startBand], size*sizeof(FIXP_DBL)); } } else for (l=startSlot; l<hSbrDec->LppTrans.pSettings->overlap ; l++) { FDKmemclear(&OverlapBufferReal[l][startBand], size*sizeof(FIXP_DBL)); } /* reset LPC filter states */ startBand = fixMin(old_lsb,new_lsb); stopBand = fixMax(old_lsb,new_lsb); size = fixMax(0,stopBand-startBand); FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesReal[0][startBand], size*sizeof(FIXP_DBL)); FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesReal[1][startBand], size*sizeof(FIXP_DBL)); if (!useLP) { FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImag[0][startBand], size*sizeof(FIXP_DBL)); FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImag[1][startBand], size*sizeof(FIXP_DBL)); } /* Rescale already processed spectral data between old and new x-over frequency. This must be done because of the separate scalefactors for lowband and highband. */ startBand = fixMin(old_lsb,new_lsb); stopBand = fixMax(old_lsb,new_lsb); if (new_lsb > old_lsb) { /* The x-over-area was part of the highband before and will now belong to the lowband */ source_scale = hSbrDec->sbrScaleFactor.ov_hb_scale; target_scale = hSbrDec->sbrScaleFactor.ov_lb_scale; target_lsb = 0; target_usb = old_lsb; } else { /* The x-over-area was part of the lowband before and will now belong to the highband */ source_scale = hSbrDec->sbrScaleFactor.ov_lb_scale; target_scale = hSbrDec->sbrScaleFactor.ov_hb_scale; /* jdr: The values old_lsb and old_usb might be wrong because the previous frame might have been "upsamling". */ target_lsb = hSbrDec->SynthesisQMF.lsb; target_usb = hSbrDec->SynthesisQMF.usb; } /* Shift left all samples of the x-over-area as much as possible An unnecessary coarse scale could cause ov_lb_scale or ov_hb_scale to be adapted and the accuracy in the next frame would seriously suffer! */ maxVal = maxSubbandSample( OverlapBufferReal, (useLP) ? NULL : OverlapBufferImag, startBand, stopBand, 0, startSlot); reserve = CntLeadingZeros(maxVal)-1; reserve = fixMin(reserve,DFRACT_BITS-1-source_scale); rescaleSubbandSamples( OverlapBufferReal, (useLP) ? NULL : OverlapBufferImag, startBand, stopBand, 0, startSlot, reserve); source_scale += reserve; delta_scale = target_scale - source_scale; if (delta_scale > 0) { /* x-over-area is dominant */ delta_scale = -delta_scale; startBand = target_lsb; stopBand = target_usb; if (new_lsb > old_lsb) { /* The lowband has to be rescaled */ hSbrDec->sbrScaleFactor.ov_lb_scale = source_scale; } else { /* The highband has be be rescaled */ hSbrDec->sbrScaleFactor.ov_hb_scale = source_scale; } } FDK_ASSERT(startBand <= stopBand); if (!useLP) { for (l=0; l<startSlot; l++) { scaleValues( OverlapBufferReal[l] + startBand, stopBand-startBand, delta_scale ); scaleValues( OverlapBufferImag[l] + startBand, stopBand-startBand, delta_scale ); } } else for (l=0; l<startSlot; l++) { scaleValues( OverlapBufferReal[l] + startBand, stopBand-startBand, delta_scale ); } /* Initialize transposer and limiter */ sbrError = resetLppTransposer (&hSbrDec->LppTrans, hHeaderData->freqBandData.lowSubband, hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster, hHeaderData->freqBandData.freqBandTableNoise, hHeaderData->freqBandData.nNfb, hHeaderData->freqBandData.highSubband, hHeaderData->sbrProcSmplRate); if (sbrError != SBRDEC_OK) return sbrError; sbrError = ResetLimiterBands ( hHeaderData->freqBandData.limiterBandTable, &hHeaderData->freqBandData.noLimiterBands, hHeaderData->freqBandData.freqBandTable[0], hHeaderData->freqBandData.nSfb[0], hSbrDec->LppTrans.pSettings->patchParam, hSbrDec->LppTrans.pSettings->noOfPatches, hHeaderData->bs_data.limiterBands); return sbrError; }
/*! \brief SBR decoder processing \return SBRDEC_OK if successfull, else error code */ SBR_ERROR applySBR (SBRDECODER self, SBRBITSTREAM * Bitstr, float *timeData, float *workBufferCore, int *numChannels, int SbrFrameOK, int bDownSample, int bBitstreamDownMix ) { unsigned char i; unsigned char dualMono = 0; int stereo = 0; int CRCLen = 0; int crcEnable = 0; int readHeader = 0; int err = 0; SBR_CHANNEL *SbrChannel = &self->SbrChannel[0]; BIT_BUFFER bitBuf; HANDLE_SBR_HEADER_DATA_DEC hHeaderData = &self->sbr_header; SBR_HEADER_STATUS headerStatus = HEADER_NOT_INITIALIZED; int codecFrameSize = hHeaderData->codecFrameSize; SBR_SYNC_STATE initialSyncState = hHeaderData->syncState; HANDLE_SBR_CONCEAL_DATA hConcealData = &self->SbrConcealData; float * pWorkBuffer1 = &timeData[2*codecFrameSize]; SBR_FRAME_DATA *hFrameDataLeft = (SBR_FRAME_DATA*) pWorkBuffer1; SBR_FRAME_DATA *hFrameDataRight = (SBR_FRAME_DATA*) self->InterimResult; assert( sizeof(SBR_FRAME_DATA) <= MAX_FRAME_SIZE*sizeof(float)); self->SbrChannel->SbrDec.workBuffer2 = workBufferCore; FLC_sub_start("applySBR"); INDIRECT(5); MOVE(9); PTR_INIT(6); /* counting previous operations */ PTR_INIT(1); FUNC(3); DelaySbrBitstr(hConcealData, Bitstr, &SbrFrameOK); INDIRECT(1); BRANCH(1); if (Bitstr->NrElements) { PTR_INIT(6); /* Bitstr->sbrElement[] SbrChannel[] hHeaderData hFrameDataLeft hFrameDataRight bitBuf */ INDIRECT(1); LOOP(1); for (i=0; i<Bitstr->NrElements; i++) { /* Save last error flag */ MOVE(1); hHeaderData->prevFrameErrorFlag = hHeaderData->frameErrorFlag; ADD(1); BRANCH(1); if (Bitstr->NrElements == 2) { MOVE(1); dualMono = 1; } else { BRANCH(2); switch (Bitstr->sbrElement[i].ElementID) { case SBR_ID_SCE: MOVE(1); stereo = 0; break; case SBR_ID_CPE: MOVE(1); stereo = 1; break; default: MOVE(1); SbrFrameOK = 0; } } MULT(1); FUNC(3); initBitBuffer (&bitBuf, Bitstr->sbrElement[i].Data, Bitstr->sbrElement[i].Payload * 8) ; FUNC(2); getbits (&bitBuf, LEN_NIBBLE); BRANCH(1); if (SbrFrameOK) { ADD(1); BRANCH(1); if (Bitstr->sbrElement[i].ExtensionType == SBR_EXTENSION_CRC) { MOVE(1); crcEnable = 1; ADD(2); MULT(1); CRCLen = 8*(Bitstr->sbrElement[i].Payload-1)+4 - SI_SBR_CRC_BITS; BRANCH(1); if (CRCLen < 0) { MOVE(2); crcEnable = 0; SbrFrameOK = 0; } } BRANCH(1); if (crcEnable) { FUNC(2); SbrFrameOK = SbrCrcCheck (&bitBuf, CRCLen); } FUNC(2); readHeader = getbits (&bitBuf, 1); BRANCH(1); if (SbrFrameOK){ int lr; FUNC(1); if (readHeader) { FUNC(3); headerStatus = sbrGetHeaderData (hHeaderData, &bitBuf, (SBR_ELEMENT_ID)Bitstr->sbrElement[i].ElementID); ADD(1); BRANCH(1); if (headerStatus == HEADER_NOT_INITIALIZED) { FLC_sub_end(); return SBRDEC_NOT_INITIALIZED; } ADD(1); BRANCH(1); if (headerStatus == HEADER_RESET) { FUNC(1); err = resetFreqBandTables(hHeaderData); PTR_INIT(1); /* SbrChannel[] */ LOOP(1); for (lr = 0 ; lr < MAXNRSBRCHANNELS; lr++) { INDIRECT(1); PTR_INIT(1); FUNC(1); resetSbrEnvelopeCalc (&(SbrChannel[lr].SbrDec.SbrCalculateEnvelope)); } PTR_INIT(1); /* SbrChannel[] */ LOOP(1); for (lr = 0 ; lr < MAXNRQMFCHANNELS; lr++) { #ifdef NON_BE_BUGFIX PTR_INIT(1); FUNC(5); #else PTR_INIT(1); FUNC(4); #endif err |= resetSbrQMF (&(SbrChannel[lr].SbrDec), hHeaderData, lr, #ifdef NON_BE_BUGFIX *numChannels, #endif SbrChannel[lr].hPrevFrameData); } BRANCH(1); if (err==0) { MOVE(1); hHeaderData->syncState = SBR_ACTIVE; } } } // if (readHeader) ADD(1); LOGIC(1); BRANCH(1); if (err || hHeaderData->syncState == SBR_NOT_INITIALIZED) { ADD(1); LOGIC(1); BRANCH(1); if (err && hHeaderData->syncState == SBR_NOT_INITIALIZED) { FLC_sub_end(); return SBRDEC_NOT_INITIALIZED; } SHIFT(1); FUNC(3); initHeaderData( hHeaderData, hHeaderData->outSampleRate >> 1, codecFrameSize); FUNC(1); err = resetFreqBandTables(hHeaderData); MOVE(2); hHeaderData->FreqBandData.lowSubband = NO_ANALYSIS_CHANNELS; hHeaderData->FreqBandData.highSubband = NO_ANALYSIS_CHANNELS; PTR_INIT(1); /* SbrChannel[lr] */ LOOP(1); for (lr = 0 ; lr < MAXNRSBRCHANNELS; lr++) { INDIRECT(1); PTR_INIT(1); FUNC(1); resetSbrEnvelopeCalc (&(SbrChannel[lr].SbrDec.SbrCalculateEnvelope)); } PTR_INIT(1); /* SbrChannel[lr] */ LOOP(1); for (lr = 0 ; lr < MAXNRQMFCHANNELS; lr++) { #ifdef NON_BE_BUGFIX PTR_INIT(1); FUNC(5); #else PTR_INIT(1); FUNC(4); #endif err |= resetSbrQMF (&(SbrChannel[lr].SbrDec), hHeaderData, lr, #ifdef NON_BE_BUGFIX *numChannels, #endif SbrChannel[lr].hPrevFrameData); } MOVE(1); hHeaderData->syncState = UPSAMPLING; } ADD(1); BRANCH(1); if (hHeaderData->syncState == SBR_ACTIVE) { BRANCH(1); if (dualMono) { BRANCH(1); if (i == 0) { BRANCH(1); MOVE(1); hFrameDataLeft->xposCtrl = max(0, SbrChannel[i].hPrevFrameData->xposCtrl); FUNC(4); SbrFrameOK = sbrGetSingleChannelElement(hHeaderData, hFrameDataLeft, NULL, &bitBuf); } else { BRANCH(1); MOVE(1); hFrameDataRight->xposCtrl = max(0, SbrChannel[i].hPrevFrameData->xposCtrl); FUNC(4); SbrFrameOK = sbrGetSingleChannelElement(hHeaderData, hFrameDataRight, NULL, &bitBuf); } } else { BRANCH(1); MOVE(1); hFrameDataLeft->xposCtrl = max(0, SbrChannel[i].hPrevFrameData->xposCtrl); BRANCH(1); if (stereo) { BRANCH(1); MOVE(1); hFrameDataRight->xposCtrl = max(0, SbrChannel[i+1].hPrevFrameData->xposCtrl); FUNC(4); SbrFrameOK = sbrGetChannelPairElement(hHeaderData, hFrameDataLeft, hFrameDataRight, &bitBuf); } else { BRANCH(1); if (bBitstreamDownMix) { MOVE(1); self->ParametricStereoDec.bForceMono = 1; } else { MOVE(1); self->ParametricStereoDec.bForceMono = 0; } FUNC(4); SbrFrameOK = sbrGetSingleChannelElement(hHeaderData, hFrameDataLeft, &self->ParametricStereoDec, &bitBuf); } } { int payloadbits = GetNrBitsRead (&bitBuf); int fillbits = (8 - (payloadbits & 7)) & 7; FUNC(1); ADD(1); LOGIC(2); /* counting previous operations */ ADD(2); MULT(1); BRANCH(1); if ((payloadbits + fillbits) != 8 * Bitstr->sbrElement[i].Payload) { MOVE(1); SbrFrameOK = 0; } } } } } ADD(1); LOGIC(1); BRANCH(1); if (!SbrFrameOK || headerStatus == CONCEALMENT) { MOVE(1); hHeaderData->frameErrorFlag = 1; } }