INT
FDKsbrEnc_initInvFiltDetector (HANDLE_SBR_INV_FILT_EST hInvFilt,   /*!< Pointer to a handle to the SBR_INV_FILT_EST struct. */
                       INT* freqBandTableDetector,          /*!< Frequency band table for the inverse filtering. */
                       INT numDetectorBands,                /*!< Number of inverse filtering bands. */
                       UINT useSpeechConfig         /*!< Flag: adapt tuning parameters according to speech*/
                       )
{
  INT i;

  FDKmemclear( hInvFilt,sizeof(SBR_INV_FILT_EST));

  hInvFilt->detectorParams = (useSpeechConfig) ? &detectorParamsAACSpeech
                                               : &detectorParamsAAC ;

  hInvFilt->noDetectorBandsMax = numDetectorBands;

  /*
     Memory initialisation
  */
  for(i=0;i<hInvFilt->noDetectorBandsMax;i++){
    FDKmemclear(&hInvFilt->detectorValues[i], sizeof(DETECTOR_VALUES));
    hInvFilt->prevInvfMode[i]   = INVF_OFF;
    hInvFilt->prevRegionOrig[i] = 0;
    hInvFilt->prevRegionSbr[i]  = 0;
  }

  /*
  Reset the inverse fltering detector.
  */
  FDKsbrEnc_resetInvFiltDetector(hInvFilt,
                       freqBandTableDetector,
                       hInvFilt->noDetectorBandsMax);

  return (0);
}
/*!
  \brief Reset tns data

  The function resets the tns data

  \return  none
*/
void CTns_Reset(CTnsData *pTnsData)
{
  /* Note: the following FDKmemclear should not be required. */
  FDKmemclear(pTnsData->Filter, TNS_MAX_WINDOWS*TNS_MAXIMUM_FILTERS*sizeof(CFilter));
  FDKmemclear(pTnsData->NumberOfFilters, TNS_MAX_WINDOWS*sizeof(UCHAR));
  pTnsData->DataPresent = 0;
  pTnsData->Active = 0;
}
Beispiel #3
0
static void FDK_QmfDomain_ClearFilterBank(HANDLE_FDK_QMF_DOMAIN hqd) {
  int ch;

  for (ch = 0; ch < ((8) + (1)); ch++) {
    FDKmemclear(&hqd->QmfDomainIn[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
  }

  for (ch = 0; ch < ((8) + (1)); ch++) {
    FDKmemclear(&hqd->QmfDomainOut[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
  }
}
/*!
  \brief Reset InterChannel and PNS data

  The function resets the InterChannel and PNS data
*/
void CPns_ResetData(CPnsData *pPnsData,
                    CPnsInterChannelData *pPnsInterChannelData) {
  FDK_ASSERT(pPnsData != NULL);
  FDK_ASSERT(pPnsInterChannelData != NULL);
  /* Assign pointer always, since pPnsData is not persistent data */
  pPnsData->pPnsInterChannelData = pPnsInterChannelData;
  pPnsData->PnsActive = 0;
  pPnsData->CurrentEnergy = 0;

  FDKmemclear(pPnsData->pnsUsed, (8 * 16) * sizeof(UCHAR));
  FDKmemclear(pPnsInterChannelData->correlated, (8 * 16) * sizeof(UCHAR));
}
Beispiel #5
0
void CProgramConfig_Init(CProgramConfig *pPce)
{
  FDKmemclear(pPce, sizeof(CProgramConfig));
#ifdef TP_PCE_ENABLE
  pPce->SamplingFrequencyIndex = 0xf;
#endif
}
Beispiel #6
0
void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo)
{
  int band;
  int window;
  const SHORT * RESTRICT pSfbScale  = pAacDecoderChannelInfo->pDynData->aSfbScale;
  SHORT * RESTRICT pSpecScale = pAacDecoderChannelInfo->specScale;
  int groupwin,group;
  const SHORT * RESTRICT BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
  SPECTRAL_PTR RESTRICT pSpectralCoefficient = pAacDecoderChannelInfo->pSpectralCoefficient;


  FDKmemclear(pSpecScale, 8*sizeof(SHORT));

  int max_band = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
  for (window=0, group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
  {
    for (groupwin=0; groupwin < GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); groupwin++, window++)
    {
      int SpecScale_window = pSpecScale[window];
      FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window,  pAacDecoderChannelInfo->granuleLength);

      /* find scaling for current window */
      for (band=0; band < max_band; band++)
      {
        SpecScale_window = fMax(SpecScale_window, (int)pSfbScale[window*16+band]);
      }

      if (pAacDecoderChannelInfo->pDynData->TnsData.Active) {
        SpecScale_window += TNS_SCALE;
      }

      /* store scaling of current window */
      pSpecScale[window] = SpecScale_window;

#ifdef FUNCTION_CBlock_ScaleSpectralData_func1

      CBlock_ScaleSpectralData_func1(pSpectrum, max_band, BandOffsets, SpecScale_window, pSfbScale, window);

#else /* FUNCTION_CBlock_ScaleSpectralData_func1 */
      for (band=0; band < max_band; band++)
      {
        int scale = SpecScale_window - pSfbScale[window*16+band];
        if (scale)
        {
          /* following relation can be used for optimizations: (BandOffsets[i]%4) == 0 for all i */
          int max_index = BandOffsets[band+1];
          for (int index = BandOffsets[band]; index < max_index; index++)
          {
            pSpectrum[index] >>= scale;
          }
        }
      }
#endif  /* FUNCTION_CBlock_ScaleSpectralData_func1 */
    }
  }

}
Beispiel #7
0
void AudioSpecificConfig_Init(CSAudioSpecificConfig *asc)
{
  FDKmemclear(asc, sizeof(CSAudioSpecificConfig));

  /* Init all values that should not be zero. */
  asc->m_aot                    = AOT_NONE;
  asc->m_samplingFrequencyIndex = 0xf;
  asc->m_epConfig               = -1;
  asc->m_extensionAudioObjectType        = AOT_NULL_OBJECT;
#ifdef TP_PCE_ENABLE
  CProgramConfig_Init(&asc->m_progrConfigElement);
#endif
}
Beispiel #8
0
int CJointStereo_Read(
        HANDLE_FDK_BITSTREAM bs,
        CJointStereoData *pJointStereoData,
        const int windowGroups,
        const int scaleFactorBandsTransmitted,
        const UINT flags
        )
{
  int group,band;

  pJointStereoData->MsMaskPresent = (UCHAR) FDKreadBits(bs,2);

  FDKmemclear(pJointStereoData->MsUsed, scaleFactorBandsTransmitted*sizeof(UCHAR));

  switch (pJointStereoData->MsMaskPresent)
  {
    case 0 : /* no M/S */
      /* all flags are already cleared */
      break ;

    case 1 : /* read ms_used */

      for (group=0; group<windowGroups; group++)
      {
        for (band=0; band<scaleFactorBandsTransmitted; band++)
        {
          pJointStereoData->MsUsed[band] |= (FDKreadBits(bs,1) << group);
        }
      }
      break ;

    case 2 : /* full spectrum M/S */

      for (band=0; band<scaleFactorBandsTransmitted; band++)
      {
        pJointStereoData->MsUsed[band] = 255 ;  /* set all flags to 1 */
      }
      break ;
  }

  return 0;
}
Beispiel #9
0
/*****************************************************************************

    functionname:FDKaacEnc_FDKaacEnc_noiseDetection
    description: wrapper for noisedet.c
    returns:
    input:       pns config structure
                 pns data structure (modified),
                 sfbActive
                 tns order and prediction gain
                 pointer to mdct Spectrumand Sfb Energy
                 pointer to Sfb tonality
    output:      noiseFuzzyMeasure in structure pnsData
                 flags tonal / nontonal

*****************************************************************************/
static void FDKaacEnc_FDKaacEnc_noiseDetection( PNS_CONFIG  *pnsConf,
                            PNS_DATA    *pnsData,
                            const INT   sfbActive,
                            const INT   *sfbOffset,
                            int          tnsOrder,
                            INT         tnsPredictionGain,
                            INT         tnsActive,
                            FIXP_DBL    *mdctSpectrum,
                            INT         *sfbMaxScaleSpec,
                            FIXP_SGL    *sfbtonality )
{
    INT condition = TRUE;
    if ( !(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMLEXITY) ) {
      condition = (tnsOrder > 3);
    }
    /*
    no PNS if heavy TNS activity
    clear pnsData->noiseFuzzyMeasure
    */
    if((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) &&
      (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition &&
      !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) && (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) && (tnsActive)) )
    {
        /* clear all noiseFuzzyMeasure */
        FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive*sizeof(FIXP_SGL));
    }
    else
    {
        /*
        call noise detection, output in pnsData->noiseFuzzyMeasure,
        use real mdct spectral data
        */
        FDKaacEnc_noiseDetect( mdctSpectrum,
            sfbMaxScaleSpec,
            sfbActive,
            sfbOffset,
            pnsData->noiseFuzzyMeasure,
            &pnsConf->np,
            sfbtonality);
    }
}
Beispiel #10
0
QMF_DOMAIN_ERROR FDK_QmfDomain_ClearPersistentMemory(
    HANDLE_FDK_QMF_DOMAIN hqd) {
  QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
  int ch, size;
  if (hqd) {
    HANDLE_FDK_QMF_DOMAIN_GC gc = &hqd->globalConf;

    size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
    for (ch = 0; ch < gc->nInputChannels; ch++) {
      if (hqd->QmfDomainIn[ch].pOverlapBuffer) {
        FDKmemclear(hqd->QmfDomainIn[ch].pOverlapBuffer,
                    size * sizeof(FIXP_DBL));
      }
    }
    if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
      err = QMF_DOMAIN_INIT_ERROR;
    }
  } else {
    err = QMF_DOMAIN_INIT_ERROR;
  }
  return err;
}
Beispiel #11
0
static void CFac_CalcFacSignal(FIXP_DBL *pOut, FIXP_DBL *pFac,
                               const int fac_scale, const int fac_length,
                               const FIXP_LPC A[M_LP_FILTER_ORDER],
                               const INT A_exp, const int fAddZir,
                               const int isFdFac) {
  FIXP_LPC wA[M_LP_FILTER_ORDER];
  FIXP_DBL tf_gain = (FIXP_DBL)0;
  int wlength;
  int scale = fac_scale;

  /* obtain tranform gain. */
  imdct_gain(&tf_gain, &scale, isFdFac ? 0 : fac_length);

  /* 4) Compute inverse DCT-IV of FAC data. Output scale of DCT IV is 16 bits.
   */
  dct_IV(pFac, fac_length, &scale);
  /* dct_IV scale = log2(fac_length). "- 7" is a factor of 2/128 */
  if (tf_gain != (FIXP_DBL)0) { /* non-radix 2 transform gain */
    int i;

    for (i = 0; i < fac_length; i++) {
      pFac[i] = fMult(tf_gain, pFac[i]);
    }
  }
  scaleValuesSaturate(pOut, pFac, fac_length,
                      scale); /* Avoid overflow issues and saturate. */

  E_LPC_a_weight(wA, A, M_LP_FILTER_ORDER);

  /* We need the output of the IIR filter to be longer than "fac_length".
  For this reason we run it with zero input appended to the end of the input
  sequence, i.e. we generate its ZIR and extend the output signal.*/
  FDKmemclear(pOut + fac_length, fac_length * sizeof(FIXP_DBL));
  wlength = 2 * fac_length;

  /* 5) Apply weighted synthesis filter to FAC data, including optional Zir (5.
   * item 4). */
  Syn_filt_zero(wA, A_exp, wlength, pOut);
}
Beispiel #12
0
INT FDKaacEnc_InitDownsampler(DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
                              int Wc,                   /*!< normalized cutoff freq * 1000*  */
                              int ratio)                /*!< downsampler ratio (only 2 supported at the momment) */

{
  UINT i;
  const struct FILTER_PARAM *currentSet=NULL;

  FDK_ASSERT(ratio == 2);
  FDKmemclear(DownSampler->downFilter.states, sizeof(DownSampler->downFilter.states));
  DownSampler->downFilter.ptr   =   0;

  /*
    find applicable parameter set
  */
  currentSet = filter_paramSet[0];
  for(i=1;i<sizeof(filter_paramSet)/sizeof(struct FILTER_PARAM *);i++){
    if (filter_paramSet[i]->Wc <= Wc) {
      break;
    }
    currentSet = filter_paramSet[i];
  }

  DownSampler->downFilter.coeffa = currentSet->coeffa;


  DownSampler->downFilter.gain = currentSet->g;
  FDK_ASSERT(currentSet->noCoeffs <= MAXNR_SECTIONS*2);

  DownSampler->downFilter.noCoeffs = currentSet->noCoeffs;
  DownSampler->delay = currentSet->delay;
  DownSampler->downFilter.Wc = currentSet->Wc;

  DownSampler->ratio =   ratio;
  DownSampler->pending = ratio-1;
  return(1);
}
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()
Beispiel #14
0
static
TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
        CSAudioSpecificConfig *asc,
        HANDLE_FDK_BITSTREAM hBs,
        CSTpCallBacks *cb
        )
{
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
  CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
  ASC_ELD_EXT_TYPE eldExtType;
  int eldExtLen, len, cnt;

  FDKmemclear(esc, sizeof(CSEldSpecificConfig));

  esc->m_frameLengthFlag = FDKreadBits(hBs, 1 );
  if (esc->m_frameLengthFlag) {
    asc->m_samplesPerFrame = 480;
  } else {
    asc->m_samplesPerFrame = 512;
  }

  asc->m_vcb11Flag = FDKreadBits(hBs, 1 );
  asc->m_rvlcFlag  = FDKreadBits(hBs, 1 );
  asc->m_hcrFlag   = FDKreadBits(hBs, 1 );

  esc->m_sbrPresentFlag     = FDKreadBits(hBs, 1 );

  if (esc->m_sbrPresentFlag == 1) {
    esc->m_sbrSamplingRate    = FDKreadBits(hBs, 1 ); /* 0: single rate, 1: dual rate */
    esc->m_sbrCrcFlag         = FDKreadBits(hBs, 1 );

    asc->m_extensionSamplingFrequency = asc->m_samplingFrequency << esc->m_sbrSamplingRate;

    if (cb->cbSbr != NULL){
      if ( 0 != ld_sbr_header(asc, hBs, cb) ) {
        return TRANSPORTDEC_PARSE_ERROR;
      }
    } else {
      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
    }
  }
  esc->m_useLdQmfTimeAlign = 0;

  /* new ELD syntax */
  /* parse ExtTypeConfigData */
  while ((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4 )) != ELDEXT_TERM) {
    eldExtLen = len = FDKreadBits(hBs, 4 );
    if ( len == 0xf ) {
      len = FDKreadBits(hBs, 8 );
      eldExtLen += len;

      if ( len == 0xff ) {
        len = FDKreadBits(hBs, 16 );
        eldExtLen += len;
      }
    }

    switch (eldExtType) {
      default:
        for(cnt=0; cnt<eldExtLen; cnt++) {
          FDKreadBits(hBs, 8 );
        }
        break;
      /* add future eld extension configs here */
    }
  }
bail:
  return (ErrorStatus);
}
Beispiel #15
0
static void CTns_Filter (FIXP_DBL *spec, int size, int inc, FIXP_TCC coeff [], int order)
{
  // - Simple all-pole filter of order "order" defined by
  //   y(n) =  x(n) - a(2)*y(n-1) - ... - a(order+1)*y(n-order)
  //
  // - The state variables of the filter are initialized to zero every time
  //
  // - The output data is written over the input data ("in-place operation")
  //
  // - An input vector of "size" samples is processed and the index increment
  //   to the next data sample is given by "inc"

  int i,j,N;
  FIXP_DBL *pSpec;
  FIXP_DBL maxVal=FL2FXCONST_DBL(0.0);
  INT s;

  FDK_ASSERT(order <= TNS_MAXIMUM_ORDER);
  C_ALLOC_SCRATCH_START(state, FIXP_DBL, TNS_MAXIMUM_ORDER);
  FDKmemclear(state, order*sizeof(FIXP_DBL));

  for (i=0; i<size; i++) {
    maxVal = fixMax(maxVal,fixp_abs(spec[i]));
  }

  if ( maxVal > FL2FXCONST_DBL(0.03125*0.70710678118) )
    s = fixMax(CntLeadingZeros(maxVal)-6,0);
  else
    s = fixMax(CntLeadingZeros(maxVal)-5,0);

  s = fixMin(s,2);
  s = s-1;

  if (inc == -1)
    pSpec = &spec[size - 1];
  else
    pSpec = &spec[0];

  FIXP_TCC *pCoeff;

#define FIRST_PART_FLTR                                              \
    FIXP_DBL x, *pState = state;                                     \
    pCoeff = coeff;                                                  \
                                                                     \
    if (s < 0)                                                       \
      x = (pSpec [0]>>1) + fMultDiv2 (*pCoeff++, pState [0]) ;       \
    else                                                             \
      x = (pSpec [0]<<s) + fMultDiv2 (*pCoeff++, pState [0]) ;

#define INNER_FLTR_INLINE                                            \
      x = fMultAddDiv2 (x, *pCoeff, pState [1]);                     \
      pState [0] = pState [1] - (fMultDiv2 (*pCoeff++, x) <<2) ;     \
      pState++;

#define LAST_PART_FLTR                                               \
      if (s < 0)                                                     \
        *pSpec = x << 1;                                             \
      else                                                           \
        *pSpec = x >> s;                                             \
      *pState =(-x) << 1;                                            \
      pSpec   += inc ;


   if (order>8)
   {
      N = (order-1)&7;

      for (i = size ; i != 0 ; i--)
      {
        FIRST_PART_FLTR

        for (j = N; j > 0 ; j--) { INNER_FLTR_INLINE }

        INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE
        INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE

        LAST_PART_FLTR
      }

   } else if (order>4) {
Beispiel #16
0
AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
                                         CAacDecoderChannelInfo *pAacDecoderChannelInfo,
                                         const SamplingRateInfo *pSamplingRateInfo,
                                         const UINT  flags)
{
  int top, band;
  int sect_len, sect_len_incr;
  int group;
  UCHAR sect_cb;
  UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
  /* HCR input (long) */
  SHORT *pNumLinesInSec    = pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
  int    numLinesInSecIdx  = 0;
  UCHAR *pHcrCodeBook      = pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
  const SHORT *BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
  pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection = 0;
  AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;

  FDKmemclear(pCodeBook, sizeof(UCHAR)*(8*16));

  const int nbits = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3;

  int sect_esc_val = (1 << nbits) - 1 ;

  UCHAR ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
  for (group=0; group<GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
  {
    for (band=0; band < ScaleFactorBandsTransmitted; )
    {
      sect_len = 0;
      if ( flags & AC_ER_VCB11 )  {
        sect_cb = (UCHAR) FDKreadBits(bs,5);
      }
      else
        sect_cb = (UCHAR) FDKreadBits(bs,4);

      if ( ((flags & AC_ER_VCB11) == 0) || ( sect_cb < 11 ) || ((sect_cb > 11) && (sect_cb < 16)) ) {
        sect_len_incr = FDKreadBits(bs, nbits);
        while (sect_len_incr == sect_esc_val)
        {
          sect_len += sect_esc_val;
          sect_len_incr = FDKreadBits(bs, nbits);
        }
      }
      else {
        sect_len_incr = 1;
      }

      sect_len += sect_len_incr;


      top = band + sect_len;

      if (flags & AC_ER_HCR) {
        /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
        if (numLinesInSecIdx >= MAX_SFB_HCR) {
          return AAC_DEC_PARSE_ERROR;
        }
        pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
        numLinesInSecIdx++;
        if (sect_cb == BOOKSCL)
        {
          return AAC_DEC_INVALID_CODE_BOOK;
        } else {
          *pHcrCodeBook++ = sect_cb;
        }
        pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection++;
      }

      /* Check spectral line limits */
      if (IsLongBlock( &(pAacDecoderChannelInfo->icsInfo) ))
      {
        if (top > 64) {
          return AAC_DEC_DECODE_FRAME_ERROR;
        }
      } else { /* short block */
        if (top + group*16 > (8 * 16)) {
          return AAC_DEC_DECODE_FRAME_ERROR;
        }
      }

      /* Check if decoded codebook index is feasible */
      if ( (sect_cb == BOOKSCL)
       || ( (sect_cb == INTENSITY_HCB || sect_cb == INTENSITY_HCB2) && pAacDecoderChannelInfo->pDynData->RawDataInfo.CommonWindow == 0)
         )
      {
        return AAC_DEC_INVALID_CODE_BOOK;
      }

      /* Store codebook index */
      for (; band < top; band++)
      {
        pCodeBook[group*16+band] = sect_cb;
      }
    }
  }


  return ErrorStatus;
}
Beispiel #17
0
int CJointStereo_Read(HANDLE_FDK_BITSTREAM bs,
                      CJointStereoData *pJointStereoData,
                      const int windowGroups,
                      const int scaleFactorBandsTransmitted,
                      const int max_sfb_ste_clear,
                      CJointStereoPersistentData *pJointStereoPersistentData,
                      CCplxPredictionData *cplxPredictionData,
                      int cplxPredictionActiv, int scaleFactorBandsTotal,
                      int windowSequence, const UINT flags) {
  int group, band;

  pJointStereoData->MsMaskPresent = (UCHAR)FDKreadBits(bs, 2);

  FDKmemclear(pJointStereoData->MsUsed,
              scaleFactorBandsTransmitted * sizeof(UCHAR));

  pJointStereoData->cplx_pred_flag = 0;
  if (cplxPredictionActiv) {
    cplxPredictionData->pred_dir = 0;
    cplxPredictionData->complex_coef = 0;
    cplxPredictionData->use_prev_frame = 0;
    cplxPredictionData->igf_pred_dir = 0;
  }

  switch (pJointStereoData->MsMaskPresent) {
    case 0: /* no M/S */
      /* all flags are already cleared */
      break;

    case 1: /* read ms_used */
      for (group = 0; group < windowGroups; group++) {
        for (band = 0; band < scaleFactorBandsTransmitted; band++) {
          pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
        }
      }
      break;

    case 2: /* full spectrum M/S */
      for (band = 0; band < scaleFactorBandsTransmitted; band++) {
        pJointStereoData->MsUsed[band] = 255; /* set all flags to 1 */
      }
      break;

    case 3:
      /* M/S coding is disabled, complex stereo prediction is enabled */
      if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
        if (cplxPredictionActiv) { /* 'if (stereoConfigIndex == 0)' */

          pJointStereoData->cplx_pred_flag = 1;

          /* cplx_pred_data()  cp. ISO/IEC FDIS 23003-3:2011(E)  Table 26 */
          int cplx_pred_all = 0; /* local use only */
          cplx_pred_all = FDKreadBits(bs, 1);

          if (cplx_pred_all) {
            for (group = 0; group < windowGroups; group++) {
              UCHAR groupmask = ((UCHAR)1 << group);
              for (band = 0; band < scaleFactorBandsTransmitted; band++) {
                pJointStereoData->MsUsed[band] |= groupmask;
              }
            }
          } else {
            for (group = 0; group < windowGroups; group++) {
              for (band = 0; band < scaleFactorBandsTransmitted;
                   band += SFB_PER_PRED_BAND) {
                pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
                if ((band + 1) < scaleFactorBandsTotal) {
                  pJointStereoData->MsUsed[band + 1] |=
                      (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group));
                }
              }
            }
          }
        } else {
          return -1;
        }
      }
      break;
  }

  if (cplxPredictionActiv) {
    /* If all sfb are MS-ed then no complex prediction */
    if (pJointStereoData->MsMaskPresent == 3) {
      if (pJointStereoData->cplx_pred_flag) {
        int delta_code_time = 0;

        /* set pointer to Huffman codebooks */
        const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL];
        /* set predictors to zero in case of a transition from long to short
         * window sequences and vice versa */
        if (((windowSequence == BLOCK_SHORT) &&
             (pJointStereoPersistentData->winSeqPrev != BLOCK_SHORT)) ||
            ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) &&
             (windowSequence != BLOCK_SHORT))) {
          FDKmemclear(pJointStereoPersistentData->alpha_q_re_prev,
                      JointStereoMaximumGroups * JointStereoMaximumBands *
                          sizeof(SHORT));
          FDKmemclear(pJointStereoPersistentData->alpha_q_im_prev,
                      JointStereoMaximumGroups * JointStereoMaximumBands *
                          sizeof(SHORT));
        }
        {
          FDKmemclear(cplxPredictionData->alpha_q_re,
                      JointStereoMaximumGroups * JointStereoMaximumBands *
                          sizeof(SHORT));
          FDKmemclear(cplxPredictionData->alpha_q_im,
                      JointStereoMaximumGroups * JointStereoMaximumBands *
                          sizeof(SHORT));
        }

        /* 0 = mid->side prediction, 1 = side->mid prediction */
        cplxPredictionData->pred_dir = FDKreadBits(bs, 1);
        cplxPredictionData->complex_coef = FDKreadBits(bs, 1);

        if (cplxPredictionData->complex_coef) {
          if (flags & AC_INDEP) {
            cplxPredictionData->use_prev_frame = 0;
          } else {
            cplxPredictionData->use_prev_frame = FDKreadBits(bs, 1);
          }
        }

        if (flags & AC_INDEP) {
          delta_code_time = 0;
        } else {
          delta_code_time = FDKreadBits(bs, 1);
        }

        {
          int last_alpha_q_re = 0, last_alpha_q_im = 0;

          for (group = 0; group < windowGroups; group++) {
            for (band = 0; band < scaleFactorBandsTransmitted;
                 band += SFB_PER_PRED_BAND) {
              if (delta_code_time == 1) {
                if (group > 0) {
                  last_alpha_q_re =
                      cplxPredictionData->alpha_q_re[group - 1][band];
                  last_alpha_q_im =
                      cplxPredictionData->alpha_q_im[group - 1][band];
                } else if ((windowSequence == BLOCK_SHORT) &&
                           (pJointStereoPersistentData->winSeqPrev ==
                            BLOCK_SHORT)) {
                  /* Included for error-robustness */
                  if (pJointStereoPersistentData->winGroupsPrev == 0) return -1;

                  last_alpha_q_re =
                      pJointStereoPersistentData->alpha_q_re_prev
                          [pJointStereoPersistentData->winGroupsPrev - 1][band];
                  last_alpha_q_im =
                      pJointStereoPersistentData->alpha_q_im_prev
                          [pJointStereoPersistentData->winGroupsPrev - 1][band];
                } else {
                  last_alpha_q_re =
                      pJointStereoPersistentData->alpha_q_re_prev[group][band];
                  last_alpha_q_im =
                      pJointStereoPersistentData->alpha_q_im_prev[group][band];
                }

              } else {
                if (band > 0) {
                  last_alpha_q_re =
                      cplxPredictionData->alpha_q_re[group][band - 1];
                  last_alpha_q_im =
                      cplxPredictionData->alpha_q_im[group][band - 1];
                } else {
                  last_alpha_q_re = 0;
                  last_alpha_q_im = 0;
                }

              } /* if (delta_code_time == 1) */

              if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) {
                int dpcm_alpha_re, dpcm_alpha_im;

                dpcm_alpha_re = CBlock_DecodeHuffmanWord(bs, hcb);
                dpcm_alpha_re -= 60;
                dpcm_alpha_re *= -1;

                cplxPredictionData->alpha_q_re[group][band] =
                    dpcm_alpha_re + last_alpha_q_re;

                if (cplxPredictionData->complex_coef) {
                  dpcm_alpha_im = CBlock_DecodeHuffmanWord(bs, hcb);
                  dpcm_alpha_im -= 60;
                  dpcm_alpha_im *= -1;

                  cplxPredictionData->alpha_q_im[group][band] =
                      dpcm_alpha_im + last_alpha_q_im;
                } else {
                  cplxPredictionData->alpha_q_im[group][band] = 0;
                }

              } else {
                cplxPredictionData->alpha_q_re[group][band] = 0;
                cplxPredictionData->alpha_q_im[group][band] = 0;
              } /* if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) */

              if ((band + 1) <
                  scaleFactorBandsTransmitted) { /* <= this should be the
                                                    correct way (cp.
                                                    ISO_IEC_FDIS_23003-0(E) */
                /*    7.7.2.3.2 Decoding of prediction coefficients) */
                cplxPredictionData->alpha_q_re[group][band + 1] =
                    cplxPredictionData->alpha_q_re[group][band];
                cplxPredictionData->alpha_q_im[group][band + 1] =
                    cplxPredictionData->alpha_q_im[group][band];
              } /* if ((band+1)<scaleFactorBandsTotal) */

              pJointStereoPersistentData->alpha_q_re_prev[group][band] =
                  cplxPredictionData->alpha_q_re[group][band];
              pJointStereoPersistentData->alpha_q_im_prev[group][band] =
                  cplxPredictionData->alpha_q_im[group][band];
            }

            for (band = scaleFactorBandsTransmitted; band < max_sfb_ste_clear;
                 band++) {
              cplxPredictionData->alpha_q_re[group][band] = 0;
              cplxPredictionData->alpha_q_im[group][band] = 0;
              pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
              pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
            }
          }
        }
      }
    } else {
      for (group = 0; group < windowGroups; group++) {
        for (band = 0; band < max_sfb_ste_clear; band++) {
          pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
          pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
        }
      }
    }

    pJointStereoPersistentData->winGroupsPrev = windowGroups;
  }

  return 0;
}
Beispiel #18
0
/*
 * Arbitrary order bitstream parser
 */
AAC_DECODER_ERROR CChannelElement_Read(
    HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
    const AUDIO_OBJECT_TYPE aot, SamplingRateInfo *pSamplingRateInfo,
    const UINT flags, const UINT elFlags, const UINT frame_length,
    const UCHAR numberOfChannels, const SCHAR epConfig,
    HANDLE_TRANSPORTDEC pTpDec) {
  AAC_DECODER_ERROR error = AAC_DEC_OK;
  const element_list_t *list;
  int i, ch, decision_bit;
  int crcReg1 = -1, crcReg2 = -1;
  int cplxPred;
  int ind_sw_cce_flag = 0, num_gain_element_lists = 0;

  FDK_ASSERT((numberOfChannels == 1) || (numberOfChannels == 2));

  /* Get channel element sequence table */
  list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, elFlags);
  if (list == NULL) {
    error = AAC_DEC_UNSUPPORTED_FORMAT;
    goto bail;
  }

  CTns_Reset(&pAacDecoderChannelInfo[0]->pDynData->TnsData);
  /* Set common window to 0 by default. If signalized in the bit stream it will
   * be overwritten later explicitely */
  pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 0;
  if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
    pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active = 0;
    pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr = 0;
  }
  if (numberOfChannels == 2) {
    CTns_Reset(&pAacDecoderChannelInfo[1]->pDynData->TnsData);
    pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = 0;
  }

  cplxPred = 0;
  if (pAacDecoderStaticChannelInfo != NULL) {
    if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
      pAacDecoderChannelInfo[0]->pComData->jointStereoData.cplx_pred_flag = 0;
      cplxPred = 1;
    }
  }

  if (0 || (flags & (AC_ELD | AC_SCALABLE))) {
    pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 1;
    if (numberOfChannels == 2) {
      pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow =
          pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow;
    }
  }

  /* Iterate through sequence table */
  i = 0;
  ch = 0;
  decision_bit = 0;
  do {
    switch (list->id[i]) {
      case element_instance_tag:
        pAacDecoderChannelInfo[0]->ElementInstanceTag = FDKreadBits(hBs, 4);
        if (numberOfChannels == 2) {
          pAacDecoderChannelInfo[1]->ElementInstanceTag =
              pAacDecoderChannelInfo[0]->ElementInstanceTag;
        }
        break;
      case common_window:
        decision_bit =
            pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.CommonWindow =
                FDKreadBits(hBs, 1);
        if (numberOfChannels == 2) {
          pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow =
              pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow;
        }
        break;
      case ics_info:
        /* store last window sequence (utilized in complex stereo prediction)
         * before reading new channel-info */
        if (cplxPred) {
          if (pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) {
            pAacDecoderStaticChannelInfo[0]
                ->pCpeStaticData->jointStereoPersistentData.winSeqPrev =
                pAacDecoderChannelInfo[0]->icsInfo.WindowSequence;
            pAacDecoderStaticChannelInfo[0]
                ->pCpeStaticData->jointStereoPersistentData.winShapePrev =
                pAacDecoderChannelInfo[0]->icsInfo.WindowShape;
          }
        }
        /* Read individual channel info */
        error = IcsRead(hBs, &pAacDecoderChannelInfo[ch]->icsInfo,
                        pSamplingRateInfo, flags);

        if (elFlags & AC_EL_LFE &&
            GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) !=
                BLOCK_LONG) {
          error = AAC_DEC_PARSE_ERROR;
          break;
        }

        if (numberOfChannels == 2 &&
            pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) {
          pAacDecoderChannelInfo[1]->icsInfo =
              pAacDecoderChannelInfo[0]->icsInfo;
        }
        break;

      case common_max_sfb:
        if (FDKreadBit(hBs) == 0) {
          error = IcsReadMaxSfb(hBs, &pAacDecoderChannelInfo[1]->icsInfo,
                                pSamplingRateInfo);
        }
        break;

      case ltp_data_present:
        if (FDKreadBits(hBs, 1) != 0) {
          error = AAC_DEC_UNSUPPORTED_PREDICTION;
        }
        break;

      case ms:

        INT max_sfb_ste;
        INT max_sfb_ste_clear;

        max_sfb_ste = GetScaleMaxFactorBandsTransmitted(
            &pAacDecoderChannelInfo[0]->icsInfo,
            &pAacDecoderChannelInfo[1]->icsInfo);

        max_sfb_ste_clear = 64;

        pAacDecoderChannelInfo[0]->icsInfo.max_sfb_ste = (UCHAR)max_sfb_ste;
        pAacDecoderChannelInfo[1]->icsInfo.max_sfb_ste = (UCHAR)max_sfb_ste;

        if (flags & (AC_USAC | AC_RSV603DA) &&
            pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.CommonWindow ==
                0) {
          Clean_Complex_Prediction_coefficients(
              &pAacDecoderStaticChannelInfo[0]
                   ->pCpeStaticData->jointStereoPersistentData,
              GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo), 0, 64);
        }

        if (CJointStereo_Read(
                hBs, &pAacDecoderChannelInfo[0]->pComData->jointStereoData,
                GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo),
                max_sfb_ste, max_sfb_ste_clear,
                /* jointStereoPersistentData and cplxPredictionData are only
                   available/allocated if cplxPred is active. */
                ((cplxPred == 0) || (pAacDecoderStaticChannelInfo == NULL))
                    ? NULL
                    : &pAacDecoderStaticChannelInfo[0]
                           ->pCpeStaticData->jointStereoPersistentData,
                ((cplxPred == 0) || (pAacDecoderChannelInfo[0] == NULL))
                    ? NULL
                    : pAacDecoderChannelInfo[0]
                          ->pComStaticData->cplxPredictionData,
                cplxPred,
                GetScaleFactorBandsTotal(&pAacDecoderChannelInfo[0]->icsInfo),
                GetWindowSequence(&pAacDecoderChannelInfo[0]->icsInfo),
                flags)) {
          error = AAC_DEC_PARSE_ERROR;
        }

        break;

      case global_gain:
        pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.GlobalGain =
            (UCHAR)FDKreadBits(hBs, 8);
        break;

      case section_data:
        error = CBlock_ReadSectionData(hBs, pAacDecoderChannelInfo[ch],
                                       pSamplingRateInfo, flags);
        break;

      case scale_factor_data_usac:
        pAacDecoderChannelInfo[ch]->currAliasingSymmetry = 0;
        /* Set active sfb codebook indexes to HCB_ESC to make them "active" */
        CChannel_CodebookTableInit(
            pAacDecoderChannelInfo[ch]); /*  equals ReadSectionData(self,
                                            bs) in float soft. block.c
                                            line: ~599 */
        /* Note: The missing "break" is intentional here, since we need to call
         * CBlock_ReadScaleFactorData(). */

      case scale_factor_data:
        if (flags & AC_ER_RVLC) {
          /* read RVLC data from bitstream (error sens. cat. 1) */
          CRvlc_Read(pAacDecoderChannelInfo[ch], hBs);
        } else {
          error = CBlock_ReadScaleFactorData(pAacDecoderChannelInfo[ch], hBs,
                                             flags);
        }
        break;

      case pulse:
        if (CPulseData_Read(
                hBs,
                &pAacDecoderChannelInfo[ch]->pDynData->specificTo.aac.PulseData,
                pSamplingRateInfo->ScaleFactorBands_Long, /* pulse data is only
                                                             allowed to be
                                                             present in long
                                                             blocks! */
                (void *)&pAacDecoderChannelInfo[ch]->icsInfo,
                frame_length) != 0) {
          error = AAC_DEC_DECODE_FRAME_ERROR;
        }
        break;
      case tns_data_present:
        CTns_ReadDataPresentFlag(
            hBs, &pAacDecoderChannelInfo[ch]->pDynData->TnsData);
        if (elFlags & AC_EL_LFE &&
            pAacDecoderChannelInfo[ch]->pDynData->TnsData.DataPresent) {
          error = AAC_DEC_PARSE_ERROR;
        }
        break;
      case tns_data:
        /* tns_data_present is checked inside CTns_Read(). */
        error = CTns_Read(hBs, &pAacDecoderChannelInfo[ch]->pDynData->TnsData,
                          &pAacDecoderChannelInfo[ch]->icsInfo, flags);

        break;

      case gain_control_data:
        break;

      case gain_control_data_present:
        if (FDKreadBits(hBs, 1)) {
          error = AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA;
        }
        break;

      case tw_data:
        break;
      case common_tw:
        break;
      case tns_data_present_usac:
        if (pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active) {
          CTns_ReadDataPresentUsac(
              hBs, &pAacDecoderChannelInfo[0]->pDynData->TnsData,
              &pAacDecoderChannelInfo[1]->pDynData->TnsData,
              &pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr,
              &pAacDecoderChannelInfo[0]->icsInfo, flags, elFlags,
              pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow);
        } else {
          pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr =
              (UCHAR)1;
        }
        break;
      case core_mode:
        decision_bit = FDKreadBits(hBs, 1);
        pAacDecoderChannelInfo[ch]->data.usac.core_mode = decision_bit;
        if ((ch == 1) && (pAacDecoderChannelInfo[0]->data.usac.core_mode !=
                          pAacDecoderChannelInfo[1]->data.usac.core_mode)) {
          /* StereoCoreToolInfo(core_mode[ch] ) */
          pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 0;
          pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = 0;
        }
        break;
      case tns_active:
        pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active =
            FDKreadBit(hBs);
        break;
      case noise:
        if (elFlags & AC_EL_USAC_NOISE) {
          pAacDecoderChannelInfo[ch]
              ->pDynData->specificTo.usac.fd_noise_level_and_offset =
              FDKreadBits(hBs, 3 + 5); /* Noise level */
        }
        break;
      case lpd_channel_stream:

      {
        error = CLpdChannelStream_Read(/* = lpd_channel_stream() */
                                       hBs, pAacDecoderChannelInfo[ch],
                                       pAacDecoderStaticChannelInfo[ch],
                                       pSamplingRateInfo, flags);
      }

        pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_LPD;
        break;
      case fac_data: {
        int fFacDatPresent = FDKreadBit(hBs);

        /* Wee need a valid fac_data[0] even if no FAC data is present (as
         * temporal buffer) */
        pAacDecoderChannelInfo[ch]->data.usac.fac_data[0] =
            pAacDecoderChannelInfo[ch]->data.usac.fac_data0;

        if (fFacDatPresent) {
          if (elFlags & AC_EL_LFE) {
            error = AAC_DEC_PARSE_ERROR;
            break;
          }
          /* FAC data present, this frame is FD, so the last mode had to be
           * ACELP. */
          if (pAacDecoderStaticChannelInfo[ch]->last_core_mode != LPD ||
              pAacDecoderStaticChannelInfo[ch]->last_lpd_mode != 0) {
            pAacDecoderChannelInfo[ch]->data.usac.core_mode_last = LPD;
            pAacDecoderChannelInfo[ch]->data.usac.lpd_mode_last = 0;
            /* We can't change the past! So look to the future and go ahead! */
          }
          CLpd_FAC_Read(hBs, pAacDecoderChannelInfo[ch]->data.usac.fac_data[0],
                        pAacDecoderChannelInfo[ch]->data.usac.fac_data_e,
                        CLpd_FAC_getLength(
                            IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo),
                            pAacDecoderChannelInfo[ch]->granuleLength),
                        1, 0);
        } else {
          if (pAacDecoderStaticChannelInfo[ch]->last_core_mode == LPD &&
              pAacDecoderStaticChannelInfo[ch]->last_lpd_mode == 0) {
            /* ACELP to FD transitons without FAC are possible. That is why we
            zero it out (i.e FAC will not be considered in the subsequent
            calculations */
            FDKmemclear(pAacDecoderChannelInfo[ch]->data.usac.fac_data0,
                        LFAC * sizeof(FIXP_DBL));
          }
        }
      } break;
      case esc2_rvlc:
        if (flags & AC_ER_RVLC) {
          CRvlc_Decode(pAacDecoderChannelInfo[ch],
                       pAacDecoderStaticChannelInfo[ch], hBs);
        }
        break;

      case esc1_hcr:
        if (flags & AC_ER_HCR) {
          CHcr_Read(hBs, pAacDecoderChannelInfo[ch],
                    numberOfChannels == 2 ? ID_CPE : ID_SCE);
        }
        break;

      case spectral_data:
        error = CBlock_ReadSpectralData(hBs, pAacDecoderChannelInfo[ch],
                                        pSamplingRateInfo, flags);
        if (flags & AC_ELD) {
          pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_ELDFB;
        } else {
          if (flags & AC_HDAAC) {
            pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_INTIMDCT;
          } else {
            pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_IMDCT;
          }
        }
        break;

      case ac_spectral_data:
        error = CBlock_ReadAcSpectralData(
            hBs, pAacDecoderChannelInfo[ch], pAacDecoderStaticChannelInfo[ch],
            pSamplingRateInfo, frame_length, flags);
        pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_IMDCT;
        break;

      case coupled_elements: {
        int num_coupled_elements, c;

        ind_sw_cce_flag = FDKreadBit(hBs);
        num_coupled_elements = FDKreadBits(hBs, 3);

        for (c = 0; c < (num_coupled_elements + 1); c++) {
          int cc_target_is_cpe;

          num_gain_element_lists++;
          cc_target_is_cpe = FDKreadBit(hBs); /* cc_target_is_cpe[c] */
          FDKreadBits(hBs, 4);                /* cc_target_tag_select[c] */

          if (cc_target_is_cpe) {
            int cc_l, cc_r;

            cc_l = FDKreadBit(hBs); /* cc_l[c] */
            cc_r = FDKreadBit(hBs); /* cc_r[c] */

            if (cc_l && cc_r) {
              num_gain_element_lists++;
            }
          }
        }
        FDKreadBit(hBs);     /* cc_domain */
        FDKreadBit(hBs);     /* gain_element_sign  */
        FDKreadBits(hBs, 2); /* gain_element_scale */
      } break;

      case gain_element_lists: {
        const CodeBookDescription *hcb;
        UCHAR *pCodeBook;
        int c;

        hcb = &AACcodeBookDescriptionTable[BOOKSCL];
        pCodeBook = pAacDecoderChannelInfo[ch]->pDynData->aCodeBook;

        for (c = 1; c < num_gain_element_lists; c++) {
          int cge;
          if (ind_sw_cce_flag) {
            cge = 1;
          } else {
            cge = FDKreadBits(hBs, 1); /* common_gain_element_present[c] */
          }
          if (cge) {
            /* Huffman */
            CBlock_DecodeHuffmanWord(
                hBs, hcb); /* hcod_sf[common_gain_element[c]] 1..19 */
          } else {
            int g, sfb;
            for (g = 0;
                 g < GetWindowGroups(&pAacDecoderChannelInfo[ch]->icsInfo);
                 g++) {
              for (sfb = 0; sfb < GetScaleFactorBandsTransmitted(
                                      &pAacDecoderChannelInfo[ch]->icsInfo);
                   sfb++) {
                if (pCodeBook[sfb] != ZERO_HCB) {
                  /* Huffman */
                  CBlock_DecodeHuffmanWord(
                      hBs,
                      hcb); /* hcod_sf[dpcm_gain_element[c][g][sfb]] 1..19 */
                }
              }
            }
          }
        }
      } break;

        /* CRC handling */
      case adtscrc_start_reg1:
        if (pTpDec != NULL) {
          crcReg1 = transportDec_CrcStartReg(pTpDec, 192);
        }
        break;
      case adtscrc_start_reg2:
        if (pTpDec != NULL) {
          crcReg2 = transportDec_CrcStartReg(pTpDec, 128);
        }
        break;
      case adtscrc_end_reg1:
      case drmcrc_end_reg:
        if (pTpDec != NULL) {
          transportDec_CrcEndReg(pTpDec, crcReg1);
          crcReg1 = -1;
        }
        break;
      case adtscrc_end_reg2:
        if (crcReg1 != -1) {
          error = AAC_DEC_DECODE_FRAME_ERROR;
        } else if (pTpDec != NULL) {
          transportDec_CrcEndReg(pTpDec, crcReg2);
          crcReg2 = -1;
        }
        break;
      case drmcrc_start_reg:
        if (pTpDec != NULL) {
          crcReg1 = transportDec_CrcStartReg(pTpDec, 0);
        }
        break;

        /* Non data cases */
      case next_channel:
        ch = (ch + 1) % numberOfChannels;
        break;
      case link_sequence:
        list = list->next[decision_bit];
        i = -1;
        break;

      default:
        error = AAC_DEC_UNSUPPORTED_FORMAT;
        break;
    }

    if (error != AAC_DEC_OK) {
      goto bail;
    }

    i++;

  } while (list->id[i] != end_of_sequence);

  for (ch = 0; ch < numberOfChannels; ch++) {
    if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_IMDCT ||
        pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_ELDFB) {
      /* Shows which bands are empty. */
      UCHAR *band_is_noise =
          pAacDecoderChannelInfo[ch]->pDynData->band_is_noise;
      FDKmemset(band_is_noise, (UCHAR)1, sizeof(UCHAR) * (8 * 16));

      error = CBlock_InverseQuantizeSpectralData(
          pAacDecoderChannelInfo[ch], pSamplingRateInfo, band_is_noise, 1);
      if (error != AAC_DEC_OK) {
        return error;
      }

      if (elFlags & AC_EL_USAC_NOISE) {
        CBlock_ApplyNoise(pAacDecoderChannelInfo[ch], pSamplingRateInfo,
                          &pAacDecoderStaticChannelInfo[ch]->nfRandomSeed,
                          band_is_noise);

      } /* if (elFlags & AC_EL_USAC_NOISE) */
    }
  }

bail:
  if (crcReg1 != -1 || crcReg2 != -1) {
    if (error == AAC_DEC_OK) {
      error = AAC_DEC_DECODE_FRAME_ERROR;
    }
    if (crcReg1 != -1) {
      transportDec_CrcEndReg(pTpDec, crcReg1);
    }
    if (crcReg2 != -1) {
      transportDec_CrcEndReg(pTpDec, crcReg2);
    }
  }
  return error;
}
Beispiel #19
0
INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
                        const int fac_scale, FIXP_LPC *A, INT A_exp,
                        INT nrOutSamples, const INT fac_length,
                        const INT isFdFac, UCHAR prevWindowShape) {
  FIXP_DBL *pOvl;
  FIXP_DBL *pOut0;
  const FIXP_WTP *pWindow;
  int i, fl, nrSamples = 0;

  FDK_ASSERT(fac_length <= 1024 / (4 * 2));

  fl = fac_length * 2;

  pWindow = FDKgetWindowSlope(fl, prevWindowShape);

  /* Adapt window slope length in case of frame loss. */
  if (hMdct->prev_fr != fl) {
    int nl = 0;
    imdct_adapt_parameters(hMdct, &fl, &nl, fac_length, pWindow, nrOutSamples);
    FDK_ASSERT(nl == 0);
  }

  if (nrSamples < nrOutSamples) {
    pOut0 = output;
    nrSamples += hMdct->ov_offset;
    /* Purge buffered output. */
    FDKmemcpy(pOut0, hMdct->overlap.time, hMdct->ov_offset * sizeof(pOut0[0]));
    hMdct->ov_offset = 0;
  }

  pOvl = hMdct->overlap.freq + hMdct->ov_size - 1;

  if (nrSamples >= nrOutSamples) {
    pOut0 = hMdct->overlap.time + hMdct->ov_offset;
    hMdct->ov_offset += hMdct->prev_nr + fl / 2;
  } else {
    pOut0 = output + nrSamples;
    nrSamples += hMdct->prev_nr + fl / 2;
  }
  if (hMdct->prevPrevAliasSymmetry == 0) {
    for (i = 0; i < hMdct->prev_nr; i++) {
      FIXP_DBL x = -(*pOvl--);
      *pOut0 = IMDCT_SCALE_DBL(x);
      pOut0++;
    }
  } else {
    for (i = 0; i < hMdct->prev_nr; i++) {
      FIXP_DBL x = (*pOvl--);
      *pOut0 = IMDCT_SCALE_DBL(x);
      pOut0++;
    }
  }
  hMdct->prev_nr = 0;

  {
    if (pFac != NULL) {
      /* Note: The FAC gain might have been applied directly after bit stream
       * parse in this case. */
      CFac_CalcFacSignal(pOut0, pFac, fac_scale, fac_length, A, A_exp, 0,
                         isFdFac);
    } else {
      /* Clear buffer because of the overlap and ADD! */
      FDKmemclear(pOut0, fac_length * sizeof(FIXP_DBL));
    }
  }

  i = 0;

  if (hMdct->prevPrevAliasSymmetry == 0) {
    for (; i < fl / 2; i++) {
      FIXP_DBL x0;

      /* Overlap Add */
      x0 = -fMult(*pOvl--, pWindow[i].v.re);

      *pOut0 += IMDCT_SCALE_DBL(x0);
      pOut0++;
    }
  } else {
    for (; i < fl / 2; i++) {
      FIXP_DBL x0;

      /* Overlap Add */
      x0 = fMult(*pOvl--, pWindow[i].v.re);

      *pOut0 += IMDCT_SCALE_DBL(x0);
      pOut0++;
    }
  }
  if (hMdct->pFacZir !=
      0) { /* this should only happen for ACELP -> TCX20 -> ACELP transition */
    FIXP_DBL *pOut = pOut0 - fl / 2; /* fl/2 == fac_length */
    for (i = 0; i < fl / 2; i++) {
      pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
    }
    hMdct->pFacZir = NULL;
  }

  hMdct->prev_fr = 0;
  hMdct->prev_nr = 0;
  hMdct->prev_tl = 0;
  hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;

  return nrSamples;
}
Beispiel #20
0
/*!
  \brief Decode channel pair element

  The function decodes a channel pair element.

  \return  none
*/
void CChannelElement_Decode(
    CAacDecoderChannelInfo
        *pAacDecoderChannelInfo[2], /*!< pointer to aac decoder channel info */
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
    SamplingRateInfo *pSamplingRateInfo, UINT flags, UINT elFlags,
    int el_channels) {
  int ch = 0;

  int maxSfBandsL = 0, maxSfBandsR = 0;
  int maybe_jstereo = (el_channels > 1);

  if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && el_channels == 2) {
    if (pAacDecoderChannelInfo[L]->data.usac.core_mode ||
        pAacDecoderChannelInfo[R]->data.usac.core_mode) {
      maybe_jstereo = 0;
    }
  }

  if (maybe_jstereo) {
    maxSfBandsL =
        GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo);
    maxSfBandsR =
        GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[R]->icsInfo);

    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
      if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
        if (pAacDecoderChannelInfo[L]->data.aac.PnsData.PnsActive ||
            pAacDecoderChannelInfo[R]->data.aac.PnsData.PnsActive) {
          MapMidSideMaskToPnsCorrelation(pAacDecoderChannelInfo);
        }
      }
      /* if tns_on_lr == 1 run MS */ /* &&
                                        (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active
                                        == 1) */
      if (((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
            1)) ||
          ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) == 0)) {
        int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

        CJointStereo_ApplyMS(
            pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
            pAacDecoderChannelInfo[L]->pSpectralCoefficient,
            pAacDecoderChannelInfo[R]->pSpectralCoefficient,
            pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[L]->specScale,
            pAacDecoderChannelInfo[R]->specScale,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
            maxSfBandsL, maxSfBandsR,
            pAacDecoderChannelInfo[L]
                ->pComData->jointStereoData.store_dmx_re_prev,
            &(pAacDecoderChannelInfo[L]
                  ->pComData->jointStereoData.store_dmx_re_prev_e),
            1);

      } /* if ( ((elFlags & AC_EL_USAC_CP_POSSIBLE).... */
    }   /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow)*/

    /* apply intensity stereo */ /* modifies pAacDecoderChannelInfo[]->aSpecSfb
                                  */
    if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
      if ((pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
           1) &&
          (el_channels == 2)) {
        CJointStereo_ApplyIS(
            pAacDecoderChannelInfo,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo),
            GetScaleFactorBandsTransmitted(
                &pAacDecoderChannelInfo[L]->icsInfo));
      }
    }
  } /* maybe_stereo */

  for (ch = 0; ch < el_channels; ch++) {
    if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
      /* Decode LPD data */
      CLpdChannelStream_Decode(pAacDecoderChannelInfo[ch],
                               pAacDecoderStaticChannelInfo[ch], flags);
    } else {
      UCHAR noSfbs =
          GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[ch]->icsInfo);
      /* For USAC common window: max_sfb of both channels may differ
       * (common_max_sfb == 0). */
      if ((maybe_jstereo == 1) &&
          (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
           1)) {
        noSfbs = fMax(maxSfBandsL, maxSfBandsR);
      }
      int CP_active = 0;
      if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
        CP_active = pAacDecoderChannelInfo[ch]
                        ->pComData->jointStereoData.cplx_pred_flag;
      }

      /* Omit writing of pAacDecoderChannelInfo[ch]->specScale for complex
         stereo prediction since scaling has already been carried out. */
      int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

      if ((!CP_active) || (CP_active && (max_sfb_ste < noSfbs)) ||
          ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
            0))) {
        CBlock_ScaleSpectralData(pAacDecoderChannelInfo[ch], noSfbs,
                                 pSamplingRateInfo);

        /*Active for the case of TNS applied before MS/CP*/
        if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
            (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
             0)) {
          if (IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo)) {
            for (int i = 0; i < noSfbs; i++) {
              pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i] =
                  pAacDecoderChannelInfo[ch]->specScale[0];
            }
          } else {
            for (int i = 0; i < 8; i++) {
              for (int j = 0; j < noSfbs; j++) {
                pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i * 16 + j] =
                    pAacDecoderChannelInfo[ch]->specScale[i];
              }
            }
          }
        }
      }
    }
  } /* End "for (ch = 0; ch < el_channels; ch++)" */

  if (maybe_jstereo) {
    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
    } /* CommonWindow */
    else {
      if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
        FDKmemclear(
            pAacDecoderStaticChannelInfo[L]
                ->pCpeStaticData->jointStereoPersistentData.alpha_q_re_prev,
            JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
        FDKmemclear(
            pAacDecoderStaticChannelInfo[L]
                ->pCpeStaticData->jointStereoPersistentData.alpha_q_im_prev,
            JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
      }
    }

  } /* if (maybe_jstereo) */

  for (ch = 0; ch < el_channels; ch++) {
    if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
    } else {
      if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
        /* Use same seed for coupled channels (CPE) */
        int pnsCh = (ch > 0) ? L : ch;
        CPns_UpdateNoiseState(
            &pAacDecoderChannelInfo[ch]->data.aac.PnsData,
            pAacDecoderChannelInfo[pnsCh]->data.aac.PnsData.currentSeed,
            pAacDecoderChannelInfo[ch]->pComData->pnsRandomSeed);
      }

      if ((!(flags & (AC_USAC))) ||
          ((flags & (AC_USAC)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active ==
            1)) ||
          (maybe_jstereo == 0)) {
        ApplyTools(
            pAacDecoderChannelInfo, pSamplingRateInfo, flags, elFlags, ch,
            pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow);
      }
    } /* End "} else" */
  }   /* End "for (ch = 0; ch < el_channels; ch++)" */

  if (maybe_jstereo) {
    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
      /* if tns_on_lr == 0 run MS */
      if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
          (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
           0)) {
        int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

        CJointStereo_ApplyMS(
            pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
            pAacDecoderChannelInfo[L]->pSpectralCoefficient,
            pAacDecoderChannelInfo[R]->pSpectralCoefficient,
            pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[L]->specScale,
            pAacDecoderChannelInfo[R]->specScale,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
            maxSfBandsL, maxSfBandsR,
            pAacDecoderChannelInfo[L]
                ->pComData->jointStereoData.store_dmx_re_prev,
            &(pAacDecoderChannelInfo[L]
                  ->pComData->jointStereoData.store_dmx_re_prev_e),
            1);
      }

    } /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) */

  } /* if (maybe_jstereo) */

  for (ch = 0; ch < el_channels; ch++) {
    if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
      pAacDecoderStaticChannelInfo[L]
          ->pCpeStaticData->jointStereoPersistentData.clearSpectralCoeffs = 0;
    }
  }

  CRvlc_ElementCheck(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
                     flags, el_channels);
}
Beispiel #21
0
INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
                        const SHORT spec_scale[], const int nSpec,
                        FIXP_DBL *pFac, const int fac_scale,
                        const INT fac_length, INT noOutSamples, const INT tl,
                        const FIXP_WTP *wrs, const INT fr, FIXP_LPC A[16],
                        INT A_exp, CAcelpStaticMem *acelp_mem,
                        const FIXP_DBL gain, const int last_frame_lost,
                        const int isFdFac, const UCHAR last_lpd_mode,
                        const int k, int currAliasingSymmetry) {
  FIXP_DBL *pCurr, *pOvl, *pSpec;
  const FIXP_WTP *pWindow;
  const FIXP_WTB *FacWindowZir_conceal;
  UCHAR doFacZirConceal = 0;
  int doDeemph = 1;
  const FIXP_WTB *FacWindowZir, *FacWindowSynth;
  FIXP_DBL *pOut0 = output, *pOut1;
  int w, i, fl, nl, nr, f_len, nrSamples = 0, s = 0, scale, total_gain_e;
  FIXP_DBL *pF, *pFAC_and_FAC_ZIR = NULL;
  FIXP_DBL total_gain = gain;

  FDK_ASSERT(fac_length <= 1024 / (4 * 2));
  switch (fac_length) {
    /* coreCoderFrameLength = 1024 */
    case 128:
      pWindow = SineWindow256;
      FacWindowZir = FacWindowZir128;
      FacWindowSynth = FacWindowSynth128;
      break;
    case 64:
      pWindow = SineWindow128;
      FacWindowZir = FacWindowZir64;
      FacWindowSynth = FacWindowSynth64;
      break;
    case 32:
      pWindow = SineWindow64;
      FacWindowZir = FacWindowZir32;
      FacWindowSynth = FacWindowSynth32;
      break;
    /* coreCoderFrameLength = 768 */
    case 96:
      pWindow = SineWindow192;
      FacWindowZir = FacWindowZir96;
      FacWindowSynth = FacWindowSynth96;
      break;
    case 48:
      pWindow = SineWindow96;
      FacWindowZir = FacWindowZir48;
      FacWindowSynth = FacWindowSynth48;
      break;
    default:
      FDK_ASSERT(0);
      return 0;
  }

  FacWindowZir_conceal = FacWindowSynth;
  /* Derive NR and NL */
  fl = fac_length * 2;
  nl = (tl - fl) >> 1;
  nr = (tl - fr) >> 1;

  if (noOutSamples > nrSamples) {
    /* Purge buffered output. */
    FDKmemcpy(pOut0, hMdct->overlap.time, hMdct->ov_offset * sizeof(pOut0[0]));
    nrSamples = hMdct->ov_offset;
    hMdct->ov_offset = 0;
  }

  if (nrSamples >= noOutSamples) {
    pOut1 = hMdct->overlap.time + hMdct->ov_offset;
    if (hMdct->ov_offset < fac_length) {
      pOut0 = output + nrSamples;
    } else {
      pOut0 = pOut1;
    }
    hMdct->ov_offset += fac_length + nl;
  } else {
    pOut1 = output + nrSamples;
    pOut0 = output + nrSamples;
  }

  {
    pFAC_and_FAC_ZIR = CLpd_ACELP_GetFreeExcMem(acelp_mem, 2 * fac_length);
    {
      const FIXP_DBL *pTmp1, *pTmp2;

      doFacZirConceal |= ((last_frame_lost != 0) && (k == 0));
      doDeemph &= (last_lpd_mode != 4);
      if (doFacZirConceal) {
        /* ACELP contribution in concealment case:
           Use ZIR with a modified ZIR window to preserve some more energy.
           Dont use FAC, which contains wrong information for concealed frame
           Dont use last ACELP samples, but double ZIR, instead (afterwards) */
        FDKmemclear(pFAC_and_FAC_ZIR, 2 * fac_length * sizeof(FIXP_DBL));
        FacWindowSynth = (FIXP_WTB *)pFAC_and_FAC_ZIR;
        FacWindowZir = FacWindowZir_conceal;
      } else {
        CFac_CalcFacSignal(pFAC_and_FAC_ZIR, pFac, fac_scale + s, fac_length, A,
                           A_exp, 1, isFdFac);
      }
      /* 6) Get windowed past ACELP samples and ACELP ZIR signal */

      /*
       * Get ACELP ZIR (pFac[]) and ACELP past samples (pOut0[]) and add them
       * to the FAC synth signal contribution on pOut1[].
       */
      {
        {
          CLpd_Acelp_Zir(A, A_exp, acelp_mem, fac_length, pFac, doDeemph);

          pTmp1 = pOut0;
          pTmp2 = pFac;
        }

        for (i = 0, w = 0; i < fac_length; i++) {
          FIXP_DBL x;
          /* Div2 is compensated by table scaling */
          x = fMultDiv2(pTmp2[i], FacWindowZir[w]);
          x += fMultDiv2(pTmp1[-i - 1], FacWindowSynth[w]);
          x += pFAC_and_FAC_ZIR[i];
          pOut1[i] = x;

          w++;
        }
      }

      if (doFacZirConceal) {
        /* ZIR is the only ACELP contribution, so double it */
        scaleValues(pOut1, fac_length, 1);
      }
    }
  }

  if (nrSamples < noOutSamples) {
    nrSamples += fac_length + nl;
  }

  /* Obtain transform gain */
  total_gain = gain;
  total_gain_e = 0;
  imdct_gain(&total_gain, &total_gain_e, tl);

  /* IMDCT overlap add */
  scale = total_gain_e;
  pSpec = _pSpec;

  /* Note:when comming from an LPD frame (TCX/ACELP) the previous alisaing
   * symmetry must always be 0 */
  if (currAliasingSymmetry == 0) {
    dct_IV(pSpec, tl, &scale);
  } else {
    FIXP_DBL _tmp[1024 + ALIGNMENT_DEFAULT / sizeof(FIXP_DBL)];
    FIXP_DBL *tmp = (FIXP_DBL *)ALIGN_PTR(_tmp);
    C_ALLOC_ALIGNED_REGISTER(tmp, sizeof(_tmp));
    dst_III(pSpec, tmp, tl, &scale);
    C_ALLOC_ALIGNED_UNREGISTER(tmp);
  }

  /* Optional scaling of time domain - no yet windowed - of current spectrum */
  if (total_gain != (FIXP_DBL)0) {
    for (i = 0; i < tl; i++) {
      pSpec[i] = fMult(pSpec[i], total_gain);
    }
  }
  int loc_scale = fixmin_I(spec_scale[0] + scale, (INT)DFRACT_BITS - 1);
  scaleValuesSaturate(pSpec, tl, loc_scale);

  pOut1 += fl / 2 - 1;
  pCurr = pSpec + tl - fl / 2;

  for (i = 0; i < fl / 2; i++) {
    FIXP_DBL x1;

    /* FAC signal is already on pOut1, because of that the += operator. */
    x1 = fMult(*pCurr++, pWindow[i].v.re);
    FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
                pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
               (pOut1 >= output && pOut1 < output + 1024));
    *pOut1 += IMDCT_SCALE_DBL(-x1);
    pOut1--;
  }

  /* NL output samples TL/2+FL/2..TL. - current[FL/2..0] */
  pOut1 += (fl / 2) + 1;

  pFAC_and_FAC_ZIR += fac_length; /* set pointer to beginning of FAC ZIR */

  if (nl == 0) {
    /* save pointer to write FAC ZIR data later */
    hMdct->pFacZir = pFAC_and_FAC_ZIR;
  } else {
    FDK_ASSERT(nl >= fac_length);
    /* FAC ZIR will be added now ... */
    hMdct->pFacZir = NULL;
  }

  pF = pFAC_and_FAC_ZIR;
  f_len = fac_length;

  pCurr = pSpec + tl - fl / 2 - 1;
  for (i = 0; i < nl; i++) {
    FIXP_DBL x = -(*pCurr--);
    /* 5) (item 4) Synthesis filter Zir component, FAC ZIR (another one). */
    if (i < f_len) {
      x += *pF++;
    }

    FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
                pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
               (pOut1 >= output && pOut1 < output + 1024));
    *pOut1 = IMDCT_SCALE_DBL(x);
    pOut1++;
  }

  hMdct->prev_nr = nr;
  hMdct->prev_fr = fr;
  hMdct->prev_wrs = wrs;
  hMdct->prev_tl = tl;
  hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
  hMdct->prevAliasSymmetry = currAliasingSymmetry;
  fl = fr;
  nl = nr;

  pOvl = pSpec + tl / 2 - 1;
  pOut0 = pOut1;

  for (w = 1; w < nSpec; w++) /* for ACELP -> FD short */
  {
    const FIXP_WTP *pWindow_prev;

    /* Setup window pointers */
    pWindow_prev = hMdct->prev_wrs;

    /* Current spectrum */
    pSpec = _pSpec + w * tl;

    scale = total_gain_e;

    /* For the second, third, etc. short frames the alisaing symmetry is equal,
     * either (0,0) or (1,1) */
    if (currAliasingSymmetry == 0) {
      /* DCT IV of current spectrum */
      dct_IV(pSpec, tl, &scale);
    } else {
      dst_IV(pSpec, tl, &scale);
    }

    /* Optional scaling of time domain - no yet windowed - of current spectrum
     */
    /* and de-scale current spectrum signal (time domain, no yet windowed) */
    if (total_gain != (FIXP_DBL)0) {
      for (i = 0; i < tl; i++) {
        pSpec[i] = fMult(pSpec[i], total_gain);
      }
    }
    loc_scale = fixmin_I(spec_scale[w] + scale, (INT)DFRACT_BITS - 1);
    scaleValuesSaturate(pSpec, tl, loc_scale);

    if (noOutSamples <= nrSamples) {
      /* Divert output first half to overlap buffer if we already got enough
       * output samples. */
      pOut0 = hMdct->overlap.time + hMdct->ov_offset;
      hMdct->ov_offset += hMdct->prev_nr + fl / 2;
    } else {
      /* Account output samples */
      nrSamples += hMdct->prev_nr + fl / 2;
    }

    /* NR output samples 0 .. NR. -overlap[TL/2..TL/2-NR] */
    for (i = 0; i < hMdct->prev_nr; i++) {
      FIXP_DBL x = -(*pOvl--);
      *pOut0 = IMDCT_SCALE_DBL(x);
      pOut0++;
    }

    if (noOutSamples <= nrSamples) {
      /* Divert output second half to overlap buffer if we already got enough
       * output samples. */
      pOut1 = hMdct->overlap.time + hMdct->ov_offset + fl / 2 - 1;
      hMdct->ov_offset += fl / 2 + nl;
    } else {
      pOut1 = pOut0 + (fl - 1);
      nrSamples += fl / 2 + nl;
    }

    /* output samples before window crossing point NR .. TL/2.
     * -overlap[TL/2-NR..TL/2-NR-FL/2] + current[NR..TL/2] */
    /* output samples after window crossing point TL/2 .. TL/2+FL/2.
     * -overlap[0..FL/2] - current[TL/2..FL/2] */
    pCurr = pSpec + tl - fl / 2;
    if (currAliasingSymmetry == 0) {
      for (i = 0; i < fl / 2; i++) {
        FIXP_DBL x0, x1;

        cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
        *pOut0 = IMDCT_SCALE_DBL(x0);
        *pOut1 = IMDCT_SCALE_DBL(-x1);
        pOut0++;
        pOut1--;
      }
    } else {
      if (hMdct->prevPrevAliasSymmetry == 0) {
        /* Jump DST II -> DST IV for the second window */
        for (i = 0; i < fl / 2; i++) {
          FIXP_DBL x0, x1;

          cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
          *pOut0 = IMDCT_SCALE_DBL(x0);
          *pOut1 = IMDCT_SCALE_DBL(x1);
          pOut0++;
          pOut1--;
        }
      } else {
        /* Jump DST IV -> DST IV from the second window on */
        for (i = 0; i < fl / 2; i++) {
          FIXP_DBL x0, x1;

          cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
          *pOut0 = IMDCT_SCALE_DBL(x0);
          *pOut1 = IMDCT_SCALE_DBL(x1);
          pOut0++;
          pOut1--;
        }
      }
    }

    if (hMdct->pFacZir != 0) {
      /* add FAC ZIR of previous ACELP -> mdct transition */
      FIXP_DBL *pOut = pOut0 - fl / 2;
      FDK_ASSERT(fl / 2 <= 128);
      for (i = 0; i < fl / 2; i++) {
        pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
      }
      hMdct->pFacZir = NULL;
    }
    pOut0 += (fl / 2);

    /* NL output samples TL/2+FL/2..TL. - current[FL/2..0] */
    pOut1 += (fl / 2) + 1;
    pCurr = pSpec + tl - fl / 2 - 1;
    for (i = 0; i < nl; i++) {
      FIXP_DBL x = -(*pCurr--);
      *pOut1 = IMDCT_SCALE_DBL(x);
      pOut1++;
    }

    /* Set overlap source pointer for next window pOvl = pSpec + tl/2 - 1; */
    pOvl = pSpec + tl / 2 - 1;

    /* Previous window values. */
    hMdct->prev_nr = nr;
    hMdct->prev_fr = fr;
    hMdct->prev_tl = tl;
    hMdct->prev_wrs = pWindow_prev;
    hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
    hMdct->prevAliasSymmetry = currAliasingSymmetry;
  }

  /* Save overlap */

  pOvl = hMdct->overlap.freq + hMdct->ov_size - tl / 2;
  FDK_ASSERT(pOvl >= hMdct->overlap.time + hMdct->ov_offset);
  FDK_ASSERT(tl / 2 <= hMdct->ov_size);
  for (i = 0; i < tl / 2; i++) {
    pOvl[i] = _pSpec[i + (w - 1) * tl];
  }

  return nrSamples;
}
static void
calculateDetectorValues(FIXP_DBL **quotaMatrixOrig,       /*!< Matrix holding the tonality values of the original. */
                        SCHAR    *indexVector,            /*!< Index vector to obtain the patched data. */
                        FIXP_DBL *nrgVector,              /*!< Energy vector. */
                        DETECTOR_VALUES *detectorValues,  /*!< pointer to DETECTOR_VALUES struct. */
                        INT startChannel,                 /*!< Start channel. */
                        INT stopChannel,                  /*!< Stop channel. */
                        INT startIndex,                   /*!< Start index. */
                        INT stopIndex,                    /*!< Stop index. */
                        INT numberOfStrongest             /*!< The number of sorted tonal components to be considered. */
                        )
{
  INT i,temp, j;

  const FIXP_DBL* filter = *fir_table[INVF_SMOOTHING_LENGTH];
  FIXP_DBL origQuotaMeanStrongest, sbrQuotaMeanStrongest;
  FIXP_DBL origQuota, sbrQuota;
  FIXP_DBL invIndex, invChannel, invTemp;
  FIXP_DBL quotaVecOrig[64], quotaVecSbr[64];

  FDKmemclear(quotaVecOrig,64*sizeof(FIXP_DBL));
  FDKmemclear(quotaVecSbr,64*sizeof(FIXP_DBL));

  invIndex = GetInvInt(stopIndex-startIndex);
  invChannel = GetInvInt(stopChannel-startChannel);

  /*
   Calculate the mean value, over the current time segment, for the original, the HFR
   and the difference, over all channels in the current frequency range.
   NOTE: the averaging is done on the values quota/(1 - quota + RELAXATION).
   */

  /* The original, the sbr signal and the total energy */
  detectorValues->avgNrg = FL2FXCONST_DBL(0.0f);
  for(j=startIndex; j<stopIndex; j++) {
    for(i=startChannel; i<stopChannel; i++) {
      quotaVecOrig[i] += fMult(quotaMatrixOrig[j][i], invIndex);

      if(indexVector[i] != -1)
        quotaVecSbr[i] += fMult(quotaMatrixOrig[j][indexVector[i]], invIndex);
    }
    detectorValues->avgNrg += fMult(nrgVector[j], invIndex);
  }

  /*
   Calculate the mean value, over the current frequency range, for the original, the HFR
   and the difference. Also calculate the same mean values for the three vectors, but only
   includeing the x strongest copmponents.
   */

  origQuota = FL2FXCONST_DBL(0.0f);
  sbrQuota  = FL2FXCONST_DBL(0.0f);
  for(i=startChannel; i<stopChannel; i++) {
    origQuota += fMultDiv2(quotaVecOrig[i], invChannel);
    sbrQuota  += fMultDiv2(quotaVecSbr[i], invChannel);
  }

  /*
   Calculate the mean value for the x strongest components
  */
  FDKsbrEnc_Shellsort_fract(quotaVecOrig+startChannel,stopChannel-startChannel);
  FDKsbrEnc_Shellsort_fract(quotaVecSbr+startChannel,stopChannel-startChannel);

  origQuotaMeanStrongest = FL2FXCONST_DBL(0.0f);
  sbrQuotaMeanStrongest  = FL2FXCONST_DBL(0.0f);

  temp = min(stopChannel - startChannel, numberOfStrongest);
  invTemp = GetInvInt(temp);

  for(i=0; i<temp; i++) {
    origQuotaMeanStrongest += fMultDiv2(quotaVecOrig[i + stopChannel - temp], invTemp);
    sbrQuotaMeanStrongest  += fMultDiv2(quotaVecSbr[i + stopChannel - temp], invTemp);
  }

  /*
   The value for the strongest component
  */
  detectorValues->origQuotaMax = quotaVecOrig[stopChannel - 1];
  detectorValues->sbrQuotaMax  = quotaVecSbr[stopChannel - 1];

  /*
   Buffer values
  */
  FDKmemmove(detectorValues->origQuotaMean, detectorValues->origQuotaMean + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
  FDKmemmove(detectorValues->sbrQuotaMean, detectorValues->sbrQuotaMean + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
  FDKmemmove(detectorValues->origQuotaMeanStrongest, detectorValues->origQuotaMeanStrongest + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
  FDKmemmove(detectorValues->sbrQuotaMeanStrongest, detectorValues->sbrQuotaMeanStrongest + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));

  detectorValues->origQuotaMean[INVF_SMOOTHING_LENGTH]          = origQuota<<1;
  detectorValues->sbrQuotaMean[INVF_SMOOTHING_LENGTH]           = sbrQuota<<1;
  detectorValues->origQuotaMeanStrongest[INVF_SMOOTHING_LENGTH] = origQuotaMeanStrongest<<1;
  detectorValues->sbrQuotaMeanStrongest[INVF_SMOOTHING_LENGTH]  = sbrQuotaMeanStrongest<<1;

  /*
   Filter values
  */
  detectorValues->origQuotaMeanFilt = FL2FXCONST_DBL(0.0f);
  detectorValues->sbrQuotaMeanFilt = FL2FXCONST_DBL(0.0f);
  detectorValues->origQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f);
  detectorValues->sbrQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f);

  for(i=0;i<INVF_SMOOTHING_LENGTH+1;i++) {
    detectorValues->origQuotaMeanFilt += fMult(detectorValues->origQuotaMean[i], filter[i]);
    detectorValues->sbrQuotaMeanFilt  += fMult(detectorValues->sbrQuotaMean[i], filter[i]);
    detectorValues->origQuotaMeanStrongestFilt += fMult(detectorValues->origQuotaMeanStrongest[i], filter[i]);
    detectorValues->sbrQuotaMeanStrongestFilt  += fMult(detectorValues->sbrQuotaMeanStrongest[i], filter[i]);
  }
}
Beispiel #23
0
/*****************************************************************************

    functionname: FDKaacEnc_PnsDetect
    description:  do decision, if PNS shall used or not
    returns:
    input:        pns config structure
                  pns data structure (modified),
                  lastWindowSequence (long or short blocks)
                  sfbActive
                  pointer to Sfb Energy, Threshold, Offset
                  pointer to mdct Spectrum
                  length of each group
                  pointer to tonality calculated in chaosmeasure
                  tns order and prediction gain
                  calculated noiseNrg at active PNS
    output:       pnsFlag in pns data structure

*****************************************************************************/
void FDKaacEnc_PnsDetect(PNS_CONFIG  *pnsConf,
                         PNS_DATA    *pnsData,
                         const INT    lastWindowSequence,
                         const INT    sfbActive,
                         const INT    maxSfbPerGroup,
                         FIXP_DBL    *sfbThresholdLdData,
                         const INT   *sfbOffset,
                         FIXP_DBL    *mdctSpectrum,
                         INT         *sfbMaxScaleSpec,
                         FIXP_SGL    *sfbtonality,
                         INT          tnsOrder,
                         INT          tnsPredictionGain,
                         INT          tnsActive,
                         FIXP_DBL    *sfbEnergyLdData,
                         INT         *noiseNrg )

{
  int sfb;
  int startNoiseSfb;

  if (pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMLEXITY) {
    if ( (!pnsConf->usePns) ||              /* pns enabled? */
           (lastWindowSequence == SHORT_WINDOW) ) /* currently only long blocks */
    {
      FDKmemclear(pnsData->pnsFlag, MAX_GROUPED_SFB*sizeof(INT)); /* clear all pnsFlags */
      for (sfb=0; sfb<MAX_GROUPED_SFB; sfb++) {
          noiseNrg[sfb] = NO_NOISE_PNS;                           /* clear nrg's of previous frame */
      }
      return;
    }
  }
  else {
    if(!pnsConf->usePns)
      return;

    /* PNS only for long Windows */
    if (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) {
      if(lastWindowSequence != LONG_WINDOW) {
        for (sfb = 0; sfb < sfbActive; sfb++) {
          pnsData->pnsFlag[sfb] = 0;    /* clear all pnsFlags */
        }
        return;
      }
    }
  }
  /*
    call noise detection
  */
  FDKaacEnc_FDKaacEnc_noiseDetection( pnsConf,
                  pnsData,
                  sfbActive,
                  sfbOffset,
                  tnsOrder,
                  tnsPredictionGain,
                  tnsActive,
                  mdctSpectrum,
                  sfbMaxScaleSpec,
                  sfbtonality );

  /* set startNoiseSfb (long) */
  startNoiseSfb = pnsConf->np.startSfb;

  /* Set noise substitution status */
  for(sfb = 0; sfb < sfbActive; sfb++) {

    /* No PNS below startNoiseSfb */
    if(sfb < startNoiseSfb){
      pnsData->pnsFlag[sfb] = 0;
      continue;
    }

    /*
      do noise substitution if
      fuzzy measure is high enough
      sfb freq > minimum sfb freq
      signal in coder band is not masked
    */

    if((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) &&
       ( (sfbThresholdLdData[sfb] + FL2FXCONST_DBL(0.5849625f/64.0f))  /* thr * 1.5 = thrLd +ld(1.5)/64 */
         < sfbEnergyLdData[sfb] ) )
    {
      /*
        mark in psyout flag array that we will code
        this band with PNS
      */
      pnsData->pnsFlag[sfb] = 1; /* PNS_ON */
    }
    else{
      pnsData->pnsFlag[sfb] = 0; /* PNS_OFF */
    }

    /* no PNS if LTP is active */
  }

  /* avoid PNS holes */
  if((pnsData->noiseFuzzyMeasure[0]>FL2FXCONST_SGL(0.5f)) && (pnsData->pnsFlag[1])) {
    pnsData->pnsFlag[0] = 1;
  }

  for(sfb=1; sfb<maxSfbPerGroup-1; sfb++) {
    if((pnsData->noiseFuzzyMeasure[sfb]>pnsConf->np.gapFillThr) &&
       (pnsData->pnsFlag[sfb-1]) && (pnsData->pnsFlag[sfb+1])) {
      pnsData->pnsFlag[sfb] = 1;
    }
  }

  if(maxSfbPerGroup>0) {
    /* avoid PNS hole */
    if((pnsData->noiseFuzzyMeasure[maxSfbPerGroup-1]>pnsConf->np.gapFillThr) && (pnsData->pnsFlag[maxSfbPerGroup-2])) {
      pnsData->pnsFlag[maxSfbPerGroup-1] = 1;
    }
    /* avoid single PNS band */
    if(pnsData->pnsFlag[maxSfbPerGroup-2]==0) {
      pnsData->pnsFlag[maxSfbPerGroup-1] = 0;
    }
  }

  /* avoid single PNS bands */
  if(pnsData->pnsFlag[1]==0) {
    pnsData->pnsFlag[0] = 0;
  }

  for(sfb=1; sfb<maxSfbPerGroup-1; sfb++) {
    if((pnsData->pnsFlag[sfb-1]==0)&&(pnsData->pnsFlag[sfb+1]==0)) {
      pnsData->pnsFlag[sfb] = 0;
    }
  }


  /*
    calculate noiseNrg's
  */
  FDKaacEnc_CalcNoiseNrgs( sfbActive,
                 pnsData->pnsFlag,
                 sfbEnergyLdData,
                 noiseNrg );
}
/*!
  \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;
}
/*!
  \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 #26
0
SBR_ERROR sbrDecoder_InitElement (
        HANDLE_SBRDECODER       self,
        const int               sampleRateIn,
        const int               sampleRateOut,
        const int               samplesPerFrame,
        const AUDIO_OBJECT_TYPE coreCodec,
        const MP4_ELEMENT_ID    elementID,
        const int               elementIndex
        )
{
  SBR_ERROR sbrError = SBRDEC_OK;
  int chCnt=0;
  int nSbrElementsStart = self->numSbrElements;

  /* Check core codec AOT */
  if (! sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (8)) {
    sbrError = SBRDEC_UNSUPPORTED_CONFIG;
    goto bail;
  }

  if ( elementID != ID_SCE && elementID != ID_CPE && elementID != ID_LFE )
  {
    sbrError = SBRDEC_UNSUPPORTED_CONFIG;
    goto bail;
  }

  if (  self->sampleRateIn == sampleRateIn
     && self->codecFrameSize == samplesPerFrame
     && self->coreCodec == coreCodec
     && self->pSbrElement[elementIndex] != NULL
     && self->pSbrElement[elementIndex]->elementID == elementID
     && !(self->flags & SBRDEC_FORCE_RESET)
     )
  {
     /* Nothing to do */
     return SBRDEC_OK;
  }

  self->sampleRateIn = sampleRateIn;
  self->codecFrameSize = samplesPerFrame;
  self->coreCodec = coreCodec;

  self->flags = 0;
  self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0;

  /* Init SBR elements */
  {
    int elChannels, ch;

    if (self->pSbrElement[elementIndex] == NULL) {
      self->pSbrElement[elementIndex] = GetRam_SbrDecElement(elementIndex);
      if (self->pSbrElement[elementIndex] == NULL) {
        sbrError = SBRDEC_MEM_ALLOC_FAILED;
        goto bail;
      }
      self->numSbrElements ++;
    } else {
      self->numSbrChannels -= self->pSbrElement[elementIndex]->nChannels;
    }

    /* Save element ID for sanity checks and to have a fallback for concealment. */
    self->pSbrElement[elementIndex]->elementID = elementID;

    /* Determine amount of channels for this element */
    switch (elementID) {
      case ID_NONE:
      case ID_CPE: elChannels=2;
        break;
      case ID_LFE:
      case ID_SCE: elChannels=1;
        break;
      default: elChannels=0;
        break;
    }

    /* Handle case of Parametric Stereo */
    if ( elementIndex == 0 && elementID == ID_SCE ) {
      switch (coreCodec) {
        case AOT_AAC_LC:
        case AOT_SBR:
        case AOT_PS:
        case AOT_ER_AAC_SCAL:
        case AOT_DRM_AAC:
        case AOT_DRM_SURROUND:
          elChannels = 2;
          break;
        default:
          break;
      }
    }

    self->pSbrElement[elementIndex]->nChannels = elChannels;

    for (ch=0; ch<elChannels; ch++)
    {
      if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) {
        self->pSbrElement[elementIndex]->pSbrChannel[ch] = GetRam_SbrDecChannel(chCnt);
        if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) {
          sbrError = SBRDEC_MEM_ALLOC_FAILED;
          goto bail;
        }
      }
      self->numSbrChannels ++;

      sbrDecoder_drcInitChannel( &self->pSbrElement[elementIndex]->pSbrChannel[ch]->SbrDec.sbrDrcChannel );

      /* Add reference pointer to workbuffers. */
      self->pSbrElement[elementIndex]->pSbrChannel[ch]->SbrDec.WorkBuffer1 = self->workBuffer1;
      self->pSbrElement[elementIndex]->pSbrChannel[ch]->SbrDec.WorkBuffer2 = self->workBuffer2;
      chCnt++;
    }
    if (elChannels == 1 && self->pSbrElement[elementIndex]->pSbrChannel[ch] != NULL) {
      deleteSbrDec( self->pSbrElement[elementIndex]->pSbrChannel[ch] );
      FreeRam_SbrDecChannel( &self->pSbrElement[elementIndex]->pSbrChannel[ch] );
    }
  }

  /* clear error flags for all delay slots */
  FDKmemclear(self->pSbrElement[elementIndex]->frameErrorFlag, ((1)+1)*sizeof(UCHAR));

  /* Initialize this instance */
  sbrError = sbrDecoder_ResetElement(
          self,
          sampleRateIn,
          sampleRateOut,
          samplesPerFrame,
          elementID,
          elementIndex,
          (coreCodec == AOT_ER_AAC_ELD) ? 0 : (6)
          );



bail:
  if (sbrError != SBRDEC_OK) {
    if (nSbrElementsStart < self->numSbrElements) {
      /* Free the memory allocated for this element */
      sbrDecoder_DestroyElement( self, elementIndex );
    } else if ( (self->pSbrElement[elementIndex] != NULL)
             && (elementIndex < (8)))
    { /* Set error flag to trigger concealment */
      self->pSbrElement[elementIndex]->frameErrorFlag[self->pSbrElement[elementIndex]->useFrameSlot] = 1;
    }
  }

  return sbrError;
}