void
sbr_dec ( HANDLE_SBR_DEC hSbrDec,            /*!< handle to Decoder channel */
          INT_PCM *timeIn,                   /*!< pointer to input time signal */
          INT_PCM *timeOut,                  /*!< pointer to output time signal */
          HANDLE_SBR_DEC hSbrDecRight,       /*!< handle to Decoder channel right */
          INT_PCM *timeOutRight,             /*!< pointer to output time signal */
          const int strideIn,                /*!< Time data traversal strideIn */
          const int strideOut,               /*!< Time data traversal strideOut */
          HANDLE_SBR_HEADER_DATA hHeaderData,/*!< Static control data */
          HANDLE_SBR_FRAME_DATA hFrameData,  /*!< Control data of current frame */
          HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData,  /*!< Some control data of last frame */
          const int applyProcessing,         /*!< Flag for SBR operation */
          HANDLE_PS_DEC h_ps_d,
          const UINT flags
        )
{
    int i, slot, reserve;
    int saveLbScale;
    int ov_len;
    int lastSlotOffs;
    FIXP_DBL maxVal;

    /* 1+1/3 frames of spectral data: */
    FIXP_DBL **QmfBufferReal = hSbrDec->QmfBufferReal;
    FIXP_DBL **QmfBufferImag = hSbrDec->QmfBufferImag;

    /* Number of QMF timeslots in the overlap buffer: */
    ov_len = hSbrDec->LppTrans.pSettings->overlap;

    /* Number of QMF slots per frame */
    int noCols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;

    /* assign qmf time slots */
    if ( ((flags & SBRDEC_LOW_POWER ) ? 1 : 0) != ((hSbrDec->SynthesisQMF.flags & QMF_FLAG_LP) ? 1 : 0) ) {
        assignTimeSlots( hSbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, flags & SBRDEC_LOW_POWER);
    }

    if (flags & SBRDEC_ELD_GRID) {
        /* Choose the right low delay filter bank */
        changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 );
    }

    /*
      low band codec signal subband filtering
     */

    {
        C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2*(64));

        qmfAnalysisFiltering( &hSbrDec->AnalysiscQMF,
                              QmfBufferReal + ov_len,
                              QmfBufferImag + ov_len,
                              &hSbrDec->sbrScaleFactor,
                              timeIn,
                              strideIn,
                              qmfTemp
                            );

        C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2*(64));
    }

    /*
      Clear upper half of spectrum
    */
    {
        int nAnalysisBands = hHeaderData->numberOfAnalysisBands;

        if (! (flags & SBRDEC_LOW_POWER)) {
            for (slot = ov_len; slot < noCols+ov_len; slot++) {
                FDKmemclear(&QmfBufferReal[slot][nAnalysisBands],((64)-nAnalysisBands)*sizeof(FIXP_DBL));
                FDKmemclear(&QmfBufferImag[slot][nAnalysisBands],((64)-nAnalysisBands)*sizeof(FIXP_DBL));
            }
        } else
            for (slot = ov_len; slot < noCols+ov_len; slot++) {
                FDKmemclear(&QmfBufferReal[slot][nAnalysisBands],((64)-nAnalysisBands)*sizeof(FIXP_DBL));
            }
    }



    /*
      Shift spectral data left to gain accuracy in transposer and adjustor
    */
    maxVal = maxSubbandSample( QmfBufferReal,
                               (flags & SBRDEC_LOW_POWER) ? NULL : QmfBufferImag,
                               0,
                               hSbrDec->AnalysiscQMF.lsb,
                               ov_len,
                               noCols+ov_len );

    reserve = fixMax(0,CntLeadingZeros(maxVal)-1) ;
    reserve = fixMin(reserve,DFRACT_BITS-1-hSbrDec->sbrScaleFactor.lb_scale);

    /* If all data is zero, lb_scale could become too large */
    rescaleSubbandSamples( QmfBufferReal,
                           (flags & SBRDEC_LOW_POWER) ? NULL : QmfBufferImag,
                           0,
                           hSbrDec->AnalysiscQMF.lsb,
                           ov_len,
                           noCols+ov_len,
                           reserve);

    hSbrDec->sbrScaleFactor.lb_scale += reserve;

    /*
      save low band scale, wavecoding or parametric stereo may modify it
    */
    saveLbScale = hSbrDec->sbrScaleFactor.lb_scale;


    if (applyProcessing)
    {
        UCHAR * borders = hFrameData->frameInfo.borders;
        lastSlotOffs =  borders[hFrameData->frameInfo.nEnvelopes] - hHeaderData->numberTimeSlots;

        FIXP_DBL degreeAlias[(64)];

        /* The transposer will override most values in degreeAlias[].
           The array needs to be cleared at least from lowSubband to highSubband before. */
        if (flags & SBRDEC_LOW_POWER)
            FDKmemclear(&degreeAlias[hHeaderData->freqBandData.lowSubband], (hHeaderData->freqBandData.highSubband-hHeaderData->freqBandData.lowSubband)*sizeof(FIXP_DBL));

        /*
          Inverse filtering of lowband and transposition into the SBR-frequency range
        */

        lppTransposer ( &hSbrDec->LppTrans,
                        &hSbrDec->sbrScaleFactor,
                        QmfBufferReal,
                        degreeAlias,                  // only used if useLP = 1
                        QmfBufferImag,
                        flags & SBRDEC_LOW_POWER,
                        hHeaderData->timeStep,
                        borders[0],
                        lastSlotOffs,
                        hHeaderData->freqBandData.nInvfBands,
                        hFrameData->sbr_invf_mode,
                        hPrevFrameData->sbr_invf_mode );





        /*
          Adjust envelope of current frame.
        */

        calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
                              &hSbrDec->SbrCalculateEnvelope,
                              hHeaderData,
                              hFrameData,
                              QmfBufferReal,
                              QmfBufferImag,
                              flags & SBRDEC_LOW_POWER,

                              degreeAlias,
                              flags,
                              (hHeaderData->frameErrorFlag || hPrevFrameData->frameErrorFlag));


        /*
          Update hPrevFrameData (to be used in the next frame)
        */
        for (i=0; i<hHeaderData->freqBandData.nInvfBands; i++) {
            hPrevFrameData->sbr_invf_mode[i] = hFrameData->sbr_invf_mode[i];
        }
        hPrevFrameData->coupling = hFrameData->coupling;
        hPrevFrameData->stopPos = borders[hFrameData->frameInfo.nEnvelopes];
        hPrevFrameData->ampRes = hFrameData->ampResolutionCurrentFrame;
    }
    else {
        /* Reset hb_scale if no highband is present, because hb_scale is considered in the QMF-synthesis */
        hSbrDec->sbrScaleFactor.hb_scale = saveLbScale;
    }


    for (i=0; i<LPC_ORDER; i++) {
        /*
          Store the unmodified qmf Slots values (required for LPC filtering)
        */
        if (! (flags & SBRDEC_LOW_POWER)) {
            FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesReal[i], QmfBufferReal[noCols-LPC_ORDER+i], hSbrDec->AnalysiscQMF.lsb*sizeof(FIXP_DBL));
            FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImag[i], QmfBufferImag[noCols-LPC_ORDER+i], hSbrDec->AnalysiscQMF.lsb*sizeof(FIXP_DBL));
        } else
            FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesReal[i], QmfBufferReal[noCols-LPC_ORDER+i], hSbrDec->AnalysiscQMF.lsb*sizeof(FIXP_DBL));
    }

    /*
      Synthesis subband filtering.
    */

    if ( ! (flags & SBRDEC_PS_DECODED) ) {

        {
            int outScalefactor = 0;

            if (h_ps_d != NULL) {
                h_ps_d->procFrameBased = 1;  /* we here do frame based processing */
            }


            sbrDecoder_drcApply(&hSbrDec->sbrDrcChannel,
                                QmfBufferReal,
                                (flags & SBRDEC_LOW_POWER) ? NULL : QmfBufferImag,
                                hSbrDec->SynthesisQMF.no_col,
                                &outScalefactor
                               );



            qmfChangeOutScalefactor(&hSbrDec->SynthesisQMF, outScalefactor );

            {
                C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2*(64));

                qmfSynthesisFiltering( &hSbrDec->SynthesisQMF,
                                       QmfBufferReal,
                                       (flags & SBRDEC_LOW_POWER) ? NULL : QmfBufferImag,
                                       &hSbrDec->sbrScaleFactor,
                                       hSbrDec->LppTrans.pSettings->overlap,
                                       timeOut,
                                       strideOut,
                                       qmfTemp);

                C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2*(64));
            }

        }

    } else { /* (flags & SBRDEC_PS_DECODED) */
        INT i, sdiff, outScalefactor, scaleFactorLowBand, scaleFactorHighBand;
        SCHAR scaleFactorLowBand_ov, scaleFactorLowBand_no_ov;

        HANDLE_QMF_FILTER_BANK synQmf      = &hSbrDec->SynthesisQMF;
        HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->SynthesisQMF;

        /* adapt scaling */
        sdiff = hSbrDec->sbrScaleFactor.lb_scale - reserve;                  /* Scaling difference         */
        scaleFactorHighBand   = sdiff - hSbrDec->sbrScaleFactor.hb_scale;    /* Scale of current high band */
        scaleFactorLowBand_ov = sdiff - hSbrDec->sbrScaleFactor.ov_lb_scale; /* Scale of low band overlapping QMF data */
        scaleFactorLowBand_no_ov = sdiff - hSbrDec->sbrScaleFactor.lb_scale; /* Scale of low band current QMF data     */
        outScalefactor  = 0;                                                 /* Initial output scale */

        if (h_ps_d->procFrameBased == 1)    /* If we have switched from frame to slot based processing copy filter states */
        {   /* procFrameBased will be unset later */
            /* copy filter states from left to right */
            FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates, ((640)-(64))*sizeof(FIXP_QSS));
        }

        /* scale ALL qmf vales ( real and imag ) of mono / left channel to the
           same scale factor ( ov_lb_sf, lb_sf and hq_sf )                      */
        scalFilterBankValues( h_ps_d,                             /* parametric stereo decoder handle     */
                              QmfBufferReal,                      /* qmf filterbank values                */
                              QmfBufferImag,                      /* qmf filterbank values                */
                              synQmf->lsb,                        /* sbr start subband                    */
                              hSbrDec->sbrScaleFactor.ov_lb_scale,
                              hSbrDec->sbrScaleFactor.lb_scale,
                              &scaleFactorLowBand_ov,              /* adapt scaling values */
                              &scaleFactorLowBand_no_ov,           /* adapt scaling values */
                              hSbrDec->sbrScaleFactor.hb_scale,   /* current frame ( highband ) */
                              &scaleFactorHighBand,
                              synQmf->no_col);

        /* use the same synthese qmf values for left and right channel */
        synQmfRight->no_col = synQmf->no_col;
        synQmfRight->lsb    = synQmf->lsb;
        synQmfRight->usb    = synQmf->usb;

        int env=0;

        outScalefactor += (SCAL_HEADROOM+1); /* psDiffScale! */

        {
            C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, 2*(64));

            int maxShift = 0;

            if (hSbrDec->sbrDrcChannel.enable != 0) {
                if (hSbrDec->sbrDrcChannel.prevFact_exp > maxShift) {
                    maxShift = hSbrDec->sbrDrcChannel.prevFact_exp;
                }
                if (hSbrDec->sbrDrcChannel.currFact_exp > maxShift) {
                    maxShift = hSbrDec->sbrDrcChannel.currFact_exp;
                }
                if (hSbrDec->sbrDrcChannel.nextFact_exp > maxShift) {
                    maxShift = hSbrDec->sbrDrcChannel.nextFact_exp;
                }
            }

            /* copy DRC data to right channel (with PS both channels use the same DRC gains) */
            FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel, sizeof(SBRDEC_DRC_CHANNEL));

            for (i = 0; i < synQmf->no_col; i++) {  /* ----- no_col loop ----- */

                INT outScalefactorR, outScalefactorL;
                outScalefactorR = outScalefactorL = outScalefactor;

                /* qmf timeslot of right channel */
                FIXP_DBL* rQmfReal = pWorkBuffer;
                FIXP_DBL* rQmfImag = pWorkBuffer + 64;


                {
                    if ( i == h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env] ) {
                        initSlotBasedRotation( h_ps_d, env, hHeaderData->freqBandData.highSubband );
                        env++;
                    }

                    ApplyPsSlot( h_ps_d,                   /* parametric stereo decoder handle  */
                                 (QmfBufferReal + i),       /* one timeslot of left/mono channel */
                                 (QmfBufferImag + i),       /* one timeslot of left/mono channel */
                                 rQmfReal,                 /* one timeslot or right channel     */
                                 rQmfImag);                /* one timeslot or right channel     */
                }


                scaleFactorLowBand = (i<(6)) ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov;


                sbrDecoder_drcApplySlot ( /* right channel */
                    &hSbrDecRight->sbrDrcChannel,
                    rQmfReal,
                    rQmfImag,
                    i,
                    synQmfRight->no_col,
                    maxShift
                );

                outScalefactorR += maxShift;

                sbrDecoder_drcApplySlot ( /* left channel */
                    &hSbrDec->sbrDrcChannel,
                    *(QmfBufferReal + i),
                    *(QmfBufferImag + i),
                    i,
                    synQmf->no_col,
                    maxShift
                );

                outScalefactorL += maxShift;


                /* scale filter states for left and right channel */
                qmfChangeOutScalefactor( synQmf, outScalefactorL );
                qmfChangeOutScalefactor( synQmfRight, outScalefactorR );

                {

                    qmfSynthesisFilteringSlot( synQmfRight,
                                               rQmfReal,                /* QMF real buffer */
                                               rQmfImag,                /* QMF imag buffer */
                                               scaleFactorLowBand,
                                               scaleFactorHighBand,
                                               timeOutRight+(i*synQmf->no_channels*strideOut),
                                               strideOut,
                                               pWorkBuffer);

                    qmfSynthesisFilteringSlot( synQmf,
                                               *(QmfBufferReal + i),      /* QMF real buffer */
                                               *(QmfBufferImag + i),      /* QMF imag buffer */
                                               scaleFactorLowBand,
                                               scaleFactorHighBand,
                                               timeOut+(i*synQmf->no_channels*strideOut),
                                               strideOut,
                                               pWorkBuffer);

                }
            } /* no_col loop  i  */

            /* scale back (6) timeslots look ahead for hybrid filterbank to original value */
            rescalFilterBankValues( h_ps_d,
                                    QmfBufferReal,
                                    QmfBufferImag,
                                    synQmf->lsb,
                                    synQmf->no_col );

            C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 2*(64));
        }
    }

    sbrDecoder_drcUpdateChannel( &hSbrDec->sbrDrcChannel );


    /*
      Update overlap buffer
      Even bands above usb are copied to avoid outdated spectral data in case
      the stop frequency raises.
    */

    if (hSbrDec->LppTrans.pSettings->overlap > 0)
    {
        if (! (flags & SBRDEC_LOW_POWER)) {
            for ( i=0; i<hSbrDec->LppTrans.pSettings->overlap; i++ ) {
                FDKmemcpy(QmfBufferReal[i], QmfBufferReal[i+noCols], (64)*sizeof(FIXP_DBL));
                FDKmemcpy(QmfBufferImag[i], QmfBufferImag[i+noCols], (64)*sizeof(FIXP_DBL));
            }
        } else
            for ( i=0; i<hSbrDec->LppTrans.pSettings->overlap; i++ ) {
                FDKmemcpy(QmfBufferReal[i], QmfBufferReal[i+noCols], (64)*sizeof(FIXP_DBL));
            }
    }

    hSbrDec->sbrScaleFactor.ov_lb_scale = saveLbScale;

    /* Save current frame status */
    hPrevFrameData->frameErrorFlag = hHeaderData->frameErrorFlag;

} // sbr_dec()
Exemple #2
0
/*
 *
 *
 * \brief Perform complex-valued subband synthesis of the
 *        low band and the high band and store the
 *        time domain data in timeOut
 *
*/
void
cplxSynthesisQmfFiltering( float **qmfReal,
#ifndef LP_SBR_ONLY
                           float **qmfImag,
#endif
                           float *timeOut,
                           HANDLE_SBR_QMF_FILTER_BANK synQmf,
                           int   bUseLP,
                           HANDLE_PS_DEC h_ps_dec,
                           int   active
                           )
{
  int i, j;
  float *ptr_time_out;

  float *filterStates;

  float accu;
  int p;
  float qmfReal2[NO_ACTUAL_SYNTHESIS_CHANNELS];

  float *imagSlot;

  int no_synthesis_channels;
  int qmf_filter_state_syn_size;

  float qmfRealTmp[NO_ACTUAL_SYNTHESIS_CHANNELS];
  float qmfImagTmp[NO_ACTUAL_SYNTHESIS_CHANNELS];

  int env;

  COUNT_sub_start("cplxSynthesisQmfFiltering");

  MOVE(1);
  env = 0;

  FUNC(3); LOOP(1); PTR_INIT(1); MOVE(1); STORE(NO_ACTUAL_SYNTHESIS_CHANNELS);
  memset(qmfRealTmp,0,NO_ACTUAL_SYNTHESIS_CHANNELS*sizeof(float));

  FUNC(3); LOOP(1); PTR_INIT(1); MOVE(1); STORE(NO_ACTUAL_SYNTHESIS_CHANNELS);
  memset(qmfImagTmp,0,NO_ACTUAL_SYNTHESIS_CHANNELS*sizeof(float));

  INDIRECT(1); MOVE(1);
  no_synthesis_channels = synQmf->no_channels;

  INDIRECT(1); MOVE(1);
  qmf_filter_state_syn_size = synQmf->qmf_filter_state_size;

  INDIRECT(1); PTR_INIT(1);
  filterStates = synQmf->FilterStatesSyn;

  PTR_INIT(1);
  ptr_time_out = timeOut;

  INDIRECT(1); LOOP(1);
  for (i = 0; i < synQmf->no_col; i++) {

    const float *p_filter = synQmf->p_filter;
    INDIRECT(1); PTR_INIT(1);

    BRANCH(1);
    if (bUseLP) {

      PTR_INIT(1);
      imagSlot = qmfReal2;
    }
#ifndef LP_SBR_ONLY
    else {

      PTR_INIT(1);
      imagSlot = *(qmfImag + i);
    }
#endif


#ifndef MONO_ONLY
    BRANCH(1);
    if(active){

      ADD(1); INDIRECT(1); BRANCH(1);
      if(i == h_ps_dec-> aEnvStartStop[env]){

        FUNC(3); INDIRECT(1);
        InitRotationEnvelope(h_ps_dec,env,synQmf->usb);
        env++;
      }

      FUNC(5);
      ApplyPsSlot(h_ps_dec,
                  &qmfReal[i],
                  &qmfImag[i],
                  qmfRealTmp,
                  qmfImagTmp);
    }
#endif



#ifndef  LP_SBR_ONLY
    BRANCH(1);
    if(!bUseLP) {

      BRANCH(1);
      if(no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED){

        PTR_INIT(4);  /* pointers for qmfReal[i][j],
                                      imagSlot[j],
                                      synQmf->cos_twiddle_ds[j],
                                      synQmf->sin_twiddle_ds[j]  */
        LOOP(1);
        for (j = 0; j < no_synthesis_channels; j++){
          float temp;

          MOVE(1);
          temp = qmfReal[i][j];

          MULT(1); MAC(1); STORE(1);
          qmfReal[i][j] = synQmf->t_cos[j] * qmfReal[i][j] + synQmf->t_sin[j] * imagSlot[j];

          MULT(2); ADD(1); STORE(1);
          imagSlot[j]   = synQmf->t_cos[j] * imagSlot[j]   - synQmf->t_sin[j] * temp;
        }
      }

      PTR_INIT(2);  /* pointers for qmfReal[i][j],
                                    imagSlot[j],   */
      INDIRECT(1); LOOP(1);
      for (j = 0; j < synQmf->usb; j++) {

        MULT(2); STORE(2);
        qmfReal[i][j] *= -1.0;
        imagSlot[j]   *= -1.0;
      }
    }
#endif

    BRANCH(1);
    if (bUseLP) {

      FUNC(3);
      inverseModulationLP (qmfReal[i], imagSlot, synQmf);
    }
#ifndef  LP_SBR_ONLY
    else {

      FUNC(3);
      inverseModulation (qmfReal[i], imagSlot, synQmf);
    }
#endif

    BRANCH(1);
    if (bUseLP) {

      PTR_INIT(2);  /* pointers for qmfReal[i][j],
                                    imagSlot[j],   */
      LOOP(1);
      for (j = 0; j < no_synthesis_channels; j++) {

        MULT(2); STORE(2);
        qmfReal[i][j] =  qmfReal[i][j] * 0.0625f;
        imagSlot[j]   =  imagSlot[j]   * 0.0625f;
      }
    }
#ifndef  LP_SBR_ONLY
    else {

      PTR_INIT(2);  /* pointers for qmfReal[i][j],
                                    imagSlot[j],   */
      LOOP(1);
      for (j = 0; j < no_synthesis_channels; j++) {

        MULT(2); STORE(2);
        qmfReal[i][j] =  qmfReal[i][j] * 0.03125f;
        imagSlot[j]   =  imagSlot[j]   * 0.03125f;
      }
    }
#endif

    COUNT_sub_start("SynthesisPolyphaseFiltering");

    MULT(1); PTR_INIT(2);  /* pointers for filterStates[p * 2*no_synthesis_channels + j],
                                           imagSlot[no_synthesis_channels -1 - j]         */
    LOOP(1);
    for (j = 0; j < no_synthesis_channels; j++){
      float newSample;
      MOVE(1);
      newSample = imagSlot[no_synthesis_channels -1 - j];

      if(no_synthesis_channels == 32){
        p_filter += NO_POLY;
      }

      LOOP(1);
      for (p = 0; p < NO_POLY; p++) {

        MAC(1); STORE(1);
        accu = filterStates[p * 2*no_synthesis_channels + j] + (*p_filter++) * newSample;
        filterStates[p * 2*no_synthesis_channels + j] = accu;

      }

    }


    MULT(2); PTR_INIT(1);  /* pointer for filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + (no_synthesis_channels-1)] */
    LOOP(1);
    for (p = 0; p < NO_POLY; p++) {

      MAC(1); STORE(1);
      accu =  filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + (no_synthesis_channels-1) ] +  (*p_filter++) * qmfReal[i][0];
      filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + (no_synthesis_channels-1)] = accu;

    }
    MOVE(1);
    ptr_time_out[0] = accu;

    p_filter -= NO_POLY*2;

    MULT(2); PTR_INIT(2);  /* pointers for filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + j],
                                           qmfReal[no_synthesis_channels -1 - j]                                  */
    ADD(1); LOOP(1);
    for (j = 0; j < no_synthesis_channels-1; j++){
      float newSample;

      MOVE(1);
      newSample = qmfReal[i][no_synthesis_channels -1 - j];

      if(no_synthesis_channels == 32){

        p_filter -= NO_POLY;
      }

      LOOP(1);
      for (p = 0; p < NO_POLY; p++) {

        MAC(1); STORE(1);
        accu =  filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + j] + (*--p_filter) * newSample;
        filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + j] = accu;

      }

      MOVE(1);
      ptr_time_out[no_synthesis_channels - 1 - j] = accu;
    }


    ptr_time_out += no_synthesis_channels;

    /*
      Shift filter states
      Should be replaces by modulo operation if available
    */
    /* FUNC(2); LOOP(1); PTR_INIT(2); MOVE(1); STORE((qmf_filter_state_syn_size - no_synthesis_channels)); */
    memmove (filterStates + no_synthesis_channels, filterStates,
             (qmf_filter_state_syn_size - no_synthesis_channels) * sizeof (float));

    /* FUNC(2); LOOP(1); PTR_INIT(1); MOVE(1); STORE(no_synthesis_channels); */
    memset (filterStates, 0, no_synthesis_channels * sizeof (float));

    BRANCH(1);
    if(active){
      FUNC(2); LOOP(1); PTR_INIT(2); MOVE(1); STORE(no_synthesis_channels);
      memcpy(qmfReal[i],qmfRealTmp,sizeof(float)*no_synthesis_channels);

#ifndef  LP_SBR_ONLY
      FUNC(2); LOOP(1); PTR_INIT(2); MOVE(1); STORE(no_synthesis_channels);
      memcpy(qmfImag[i],qmfImagTmp,sizeof(float)*no_synthesis_channels);
#endif
    }

    COUNT_sub_end();

  }

  COUNT_sub_end();
}