static void changeQmfType( HANDLE_SBR_DEC hSbrDec,                     /*!< handle to Decoder channel */
                           int useLdTimeAlign )
{
    UINT synQmfFlags = hSbrDec->SynthesisQMF.flags;
    UINT anaQmfFlags = hSbrDec->AnalysiscQMF.flags;
    int  resetSynQmf = 0;
    int  resetAnaQmf = 0;

    /* assign qmf type */
    if (useLdTimeAlign) {
        if (synQmfFlags & QMF_FLAG_CLDFB) {
            /* change the type to MPSLD */
            synQmfFlags &= ~QMF_FLAG_CLDFB;
            synQmfFlags |=  QMF_FLAG_MPSLDFB;
            resetSynQmf = 1;
        }
        if (anaQmfFlags & QMF_FLAG_CLDFB) {
            /* change the type to MPSLD */
            anaQmfFlags &= ~QMF_FLAG_CLDFB;
            anaQmfFlags |=  QMF_FLAG_MPSLDFB;
            resetAnaQmf = 1;
        }
    } else {
        if (synQmfFlags & QMF_FLAG_MPSLDFB) {
            /* change the type to CLDFB */
            synQmfFlags &= ~QMF_FLAG_MPSLDFB;
            synQmfFlags |=  QMF_FLAG_CLDFB;
            resetSynQmf = 1;
        }
        if (anaQmfFlags & QMF_FLAG_MPSLDFB) {
            /* change the type to CLDFB */
            anaQmfFlags &= ~QMF_FLAG_MPSLDFB;
            anaQmfFlags |=  QMF_FLAG_CLDFB;
            resetAnaQmf = 1;
        }
    }

    if (resetAnaQmf) {
        int qmfErr = qmfInitAnalysisFilterBank (
                         &hSbrDec->AnalysiscQMF,
                         hSbrDec->anaQmfStates,
                         hSbrDec->AnalysiscQMF.no_col,
                         hSbrDec->AnalysiscQMF.lsb,
                         hSbrDec->AnalysiscQMF.usb,
                         hSbrDec->AnalysiscQMF.no_channels,
                         anaQmfFlags | QMF_FLAG_KEEP_STATES
                     );
        if (qmfErr != 0) {
            FDK_ASSERT(0);
        }
    }

    if (resetSynQmf) {
        int qmfErr = qmfInitSynthesisFilterBank (
                         &hSbrDec->SynthesisQMF,
                         hSbrDec->pSynQmfStates,
                         hSbrDec->SynthesisQMF.no_col,
                         hSbrDec->SynthesisQMF.lsb,
                         hSbrDec->SynthesisQMF.usb,
                         hSbrDec->SynthesisQMF.no_channels,
                         synQmfFlags | QMF_FLAG_KEEP_STATES
                     );

        if (qmfErr != 0) {
            FDK_ASSERT(0);
        }
    }
}
/*!
  \brief     Creates sbr decoder structure
  \return    errorCode, 0 if successful
*/
SBR_ERROR
createSbrDec (SBR_CHANNEL * hSbrChannel,
              HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
              TRANSPOSER_SETTINGS *pSettings,
              const int     downsampleFac,        /*!< Downsampling factor */
              const UINT    qmfFlags,             /*!< flags -> 1: HQ/LP selector, 2: CLDFB */
              const UINT    flags,
              const int     overlap,
              int           chan)                 /*!< Channel for which to assign buffers etc. */

{
    SBR_ERROR err = SBRDEC_OK;
    int timeSlots = hHeaderData->numberTimeSlots;   /* Number of SBR slots per frame */
    int noCols = timeSlots * hHeaderData->timeStep; /* Number of QMF slots per frame */
    HANDLE_SBR_DEC hs = &(hSbrChannel->SbrDec);

    /* Initialize scale factors */
    hs->sbrScaleFactor.ov_lb_scale  = 0;
    hs->sbrScaleFactor.ov_hb_scale  = 0;
    hs->sbrScaleFactor.hb_scale     = 0;


    /*
      create envelope calculator
    */
    err = createSbrEnvelopeCalc (&hs->SbrCalculateEnvelope,
                                 hHeaderData,
                                 chan,
                                 flags);
    if (err != SBRDEC_OK) {
        return err;
    }

    /*
      create QMF filter banks
    */
    {
        int qmfErr;

        qmfErr = qmfInitAnalysisFilterBank (
                     &hs->AnalysiscQMF,
                     hs->anaQmfStates,
                     noCols,
                     hHeaderData->freqBandData.lowSubband,
                     hHeaderData->freqBandData.highSubband,
                     hHeaderData->numberOfAnalysisBands,
                     qmfFlags & (~QMF_FLAG_KEEP_STATES)
                 );
        if (qmfErr != 0) {
            return SBRDEC_UNSUPPORTED_CONFIG;
        }
    }
    if (hs->pSynQmfStates == NULL) {
        hs->pSynQmfStates = GetRam_sbr_QmfStatesSynthesis(chan);
        if (hs->pSynQmfStates == NULL)
            return SBRDEC_MEM_ALLOC_FAILED;
    }

    {
        int qmfErr;

        qmfErr = qmfInitSynthesisFilterBank (
                     &hs->SynthesisQMF,
                     hs->pSynQmfStates,
                     noCols,
                     hHeaderData->freqBandData.lowSubband,
                     hHeaderData->freqBandData.highSubband,
                     (64) / downsampleFac,
                     qmfFlags & (~QMF_FLAG_KEEP_STATES)
                 );

        if (qmfErr != 0) {
            return SBRDEC_UNSUPPORTED_CONFIG;
        }
    }
    initSbrPrevFrameData (&hSbrChannel->prevFrameData, timeSlots);

    /*
      create transposer
    */
    err = createLppTransposer (&hs->LppTrans,
                               pSettings,
                               hHeaderData->freqBandData.lowSubband,
                               hHeaderData->freqBandData.v_k_master,
                               hHeaderData->freqBandData.numMaster,
                               hs->SynthesisQMF.usb,
                               timeSlots,
                               hs->AnalysiscQMF.no_col,
                               hHeaderData->freqBandData.freqBandTableNoise,
                               hHeaderData->freqBandData.nNfb,
                               hHeaderData->sbrProcSmplRate,
                               chan,
                               overlap );
    if (err != SBRDEC_OK) {
        return err;
    }

    /* The CLDFB does not have overlap */
    if ((qmfFlags & QMF_FLAG_CLDFB) == 0) {
        if (hs->pSbrOverlapBuffer == NULL) {
            hs->pSbrOverlapBuffer = GetRam_sbr_OverlapBuffer(chan);
            if (hs->pSbrOverlapBuffer == NULL)  {
                return SBRDEC_MEM_ALLOC_FAILED;
            }
        } else {
            /* Clear overlap buffer */
            FDKmemclear( hs->pSbrOverlapBuffer,
                         sizeof(FIXP_DBL) * 2 * (6) * (64)
                       );
        }
    }

    /* assign qmf time slots */
    assignTimeSlots( &hSbrChannel->SbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, qmfFlags & QMF_FLAG_LP);

    return err;
}
Exemple #3
0
int FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd, UINT extra_flags) {
  FDK_ASSERT(qd != NULL);
  int err = 0;
  int ch, ts;
  HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
  int noCols = gc->nQmfTimeSlots;
  int lsb = gc->nBandsAnalysis;
  int usb = fMin((INT)gc->nBandsSynthesis, 64);
  int nProcBands = gc->nQmfProcBands;
  FDK_ASSERT(nProcBands % ALIGNMENT_DEFAULT == 0);

  if (extra_flags & QMF_FLAG_MPSLDFB) {
    gc->flags &= ~QMF_FLAG_CLDFB;
    gc->flags |= QMF_FLAG_MPSLDFB;
  }
  for (ch = 0; ch < gc->nInputChannels; ch++) {
    /* distribute memory to slots array */
    FIXP_DBL *ptrOv =
        qd->QmfDomainIn[ch].pOverlapBuffer; /* persistent memory for overlap */
    if ((ptrOv == NULL) && (gc->nQmfOvTimeSlots != 0)) {
      err = 1;
      return err;
    }
    /* This assumes the workbuffer defined for ch0 is the big one being used to
     * hold one full frame of QMF data. */
    FIXP_DBL **ptr =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .pWorkBuffer; /* non-persistent workbuffer */
    USHORT workBufferOffset =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .workBufferOffset;
    USHORT workBufferSectSize =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .workBufferSectSize;

    if ((ptr == NULL) && (gc->nQmfTimeSlots != 0)) {
      err = 1;
      return err;
    }

    qd->QmfDomainIn[ch].pGlobalConf = gc;
    for (ts = 0; ts < gc->nQmfOvTimeSlots; ts++) {
      qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = ptrOv;
      ptrOv += nProcBands;
      qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = ptrOv;
      ptrOv += nProcBands;
    }
    for (; ts < (gc->nQmfOvTimeSlots + gc->nQmfTimeSlots); ts++) {
      qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = FDK_getWorkBuffer(
          ptr, workBufferOffset, workBufferSectSize, nProcBands);
      workBufferOffset += nProcBands;
      qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = FDK_getWorkBuffer(
          ptr, workBufferOffset, workBufferSectSize, nProcBands);
      workBufferOffset += nProcBands;
    }
    err |= qmfInitAnalysisFilterBank(
        &qd->QmfDomainIn[ch].fb, qd->QmfDomainIn[ch].pAnaQmfStates, noCols,
        (qd->QmfDomainIn[ch].fb.lsb == 0) ? lsb : qd->QmfDomainIn[ch].fb.lsb,
        (qd->QmfDomainIn[ch].fb.usb == 0) ? usb : qd->QmfDomainIn[ch].fb.usb,
        gc->nBandsAnalysis, gc->flags | extra_flags);
  }

  for (ch = 0; ch < gc->nOutputChannels; ch++) {
    FIXP_DBL outGain_m = qd->QmfDomainOut[ch].fb.outGain_m;
    int outGain_e = qd->QmfDomainOut[ch].fb.outGain_e;
    int outScale = qmfGetOutScalefactor(&qd->QmfDomainOut[ch].fb);
    err |= qmfInitSynthesisFilterBank(
        &qd->QmfDomainOut[ch].fb, qd->QmfDomainOut[ch].pSynQmfStates, noCols,
        (qd->QmfDomainOut[ch].fb.lsb == 0) ? lsb : qd->QmfDomainOut[ch].fb.lsb,
        (qd->QmfDomainOut[ch].fb.usb == 0) ? usb : qd->QmfDomainOut[ch].fb.usb,
        gc->nBandsSynthesis, gc->flags | extra_flags);
    if (outGain_m != (FIXP_DBL)0) {
      qmfChangeOutGain(&qd->QmfDomainOut[ch].fb, outGain_m, outGain_e);
    }
    if (outScale) {
      qmfChangeOutScalefactor(&qd->QmfDomainOut[ch].fb, outScale);
    }
  }

  return err;
}