/*!
  \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;
}
Beispiel #2
0
/*!
  \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;
      }
    }