/** * \brief Apply decoded SBR header for one element. * \param self SBR decoder instance handle * \param hSbrHeader SBR header handle to be processed. * \param hSbrChannel pointer array to the SBR element channels corresponding to the SBR header. * \param headerStatus header status value returned from SBR header parser. * \param numElementChannels amount of channels for the SBR element whos header is to be processed. */ static SBR_ERROR sbrDecoder_HeaderUpdate( HANDLE_SBRDECODER self, HANDLE_SBR_HEADER_DATA hSbrHeader, SBR_HEADER_STATUS headerStatus, HANDLE_SBR_CHANNEL hSbrChannel[], const int numElementChannels ) { SBR_ERROR errorStatus = SBRDEC_OK; /* change of control data, reset decoder */ errorStatus = resetFreqBandTables(hSbrHeader, self->flags); if (errorStatus == SBRDEC_OK) { if (hSbrHeader->syncState == UPSAMPLING && headerStatus != HEADER_RESET) { /* As the default header would limit the frequency range, lowSubband and highSubband must be patched. */ hSbrHeader->freqBandData.lowSubband = hSbrHeader->numberOfAnalysisBands; hSbrHeader->freqBandData.highSubband = hSbrHeader->numberOfAnalysisBands; } /* Trigger a reset before processing this slot */ hSbrHeader->status |= SBRDEC_HDR_STAT_RESET; } return errorStatus; }
/*! \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; } }