/*!
  \brief Initialize DRC information

  \self Handle of DRC info

  \return none
*/
void aacDecoder_drcInit (
    HANDLE_AAC_DRC self )
{
  CDrcParams *pParams;

  if (self == NULL) {
    return;
  }

  /* init control fields */
  self->enable = 0;
  self->numThreads = 0;
  self->digitalNorm = 0;

  /* init params */
  pParams = &self->params;
  pParams->bsDelayEnable = 0;
  pParams->cut   = FL2FXCONST_DBL(0.0f);
  pParams->boost = FL2FXCONST_DBL(0.0f);
  pParams->targetRefLevel = AACDEC_DRC_DEFAULT_REF_LEVEL;
  pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;

  /* initial program ref level = target ref level */
  self->progRefLevel = pParams->targetRefLevel;
}
DRC_ERROR
initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
            const int sampleRate) {
  int i, j, k;

  if (frameSize < 1) {
    return DE_NOT_OK;
  }

  hGainDec->frameSize = frameSize;

  if (hGainDec->frameSize * 1000 < sampleRate) {
    return DE_NOT_OK;
  }

  hGainDec->deltaTminDefault = getDeltaTmin(sampleRate);
  if (hGainDec->deltaTminDefault > hGainDec->frameSize) {
    return DE_NOT_OK;
  }

  for (i = 0; i < MAX_ACTIVE_DRCS; i++) {
    for (j = 0; j < 8; j++) {
      /* use startup node at the beginning */
      hGainDec->activeDrc[i].lnbIndexForChannel[j][0] = 0;
      for (k = 1; k < NUM_LNB_FRAMES; k++) {
        hGainDec->activeDrc[i].lnbIndexForChannel[j][k] = -1;
      }
    }
  }

  for (j = 0; j < 8; j++) {
    hGainDec->channelGain[j] = FL2FXCONST_DBL(1.0f / (float)(1 << 8));
  }

  for (i = 0; i < 4 * 1024 / 256; i++) {
    hGainDec->dummySubbandGains[i] = FL2FXCONST_DBL(1.0f / (float)(1 << 7));
  }

  hGainDec->status = 0; /* startup */

  return DE_OK;
}
SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
  SACDEC_ERROR err = MPS_OK;
  int ch;

  for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
    self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
    self->oldWetEnerLD64[ch] =
        FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */
  }
  for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
    self->oldDryEnerLD64[ch] =
        FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */
  }

  self->BP = BP__FDK;
  self->BP_GF = BP_GF__FDK;

  self->update_old_ener = 0;

  return err;
}
Exemple #4
0
SBR_ERROR sbrDecoder_drcFeedChannel ( HANDLE_SBRDECODER  self,
                                      INT                ch,
                                      UINT               numBands,
                                      FIXP_DBL          *pNextFact_mag,
                                      INT                nextFact_exp,
                                      SHORT              drcInterpolationScheme,
                                      UCHAR              winSequence,
                                      USHORT            *pBandTop )
{
  SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
  int band, isValidData = 0;

  if (self == NULL) {
    return SBRDEC_NOT_INITIALIZED;
  }
  if (ch > (8) || pNextFact_mag == NULL) {
    return SBRDEC_SET_PARAM_FAIL;
  }

  /* Search for gain values different to 1.0f */
  for (band = 0; band < numBands; band += 1) {
    if ( !((pNextFact_mag[band] == FL2FXCONST_DBL(0.5))  && (nextFact_exp == 1))
      && !((pNextFact_mag[band] == (FIXP_DBL)MAXVAL_DBL) && (nextFact_exp == 0)) ) {
      isValidData = 1;
      break;
    }
  }

  /* Find the right SBR channel */
  pSbrDrcChannelData = sbrDecoder_drcGetChannel( self, ch );

  if ( pSbrDrcChannelData != NULL ) {
    if ( pSbrDrcChannelData->enable || isValidData )
  { /* Activate processing only with real and valid data */
    int i;

    pSbrDrcChannelData->enable   = 1;
    pSbrDrcChannelData->numBandsNext = numBands;

    pSbrDrcChannelData->winSequenceNext            = winSequence;
    pSbrDrcChannelData->drcInterpolationSchemeNext = drcInterpolationScheme;
    pSbrDrcChannelData->nextFact_exp               = nextFact_exp;

    for (i = 0; i < (int)numBands; i++) {
      pSbrDrcChannelData->bandTopNext[i]  = pBandTop[i];
      pSbrDrcChannelData->nextFact_mag[i] = pNextFact_mag[i];
    }
  }
  }

  return SBRDEC_OK;
}
void imdct_gain(FIXP_DBL *pGain_m, int *pGain_e, int tl)
{
  FIXP_DBL gain_m = *pGain_m;
  int gain_e = *pGain_e;
  int log2_tl;

  log2_tl = DFRACT_BITS-1-fNormz((FIXP_DBL)tl);

  gain_e += -MDCT_OUTPUT_GAIN - log2_tl - MDCT_OUT_HEADROOM + 1;

  /* Detect non-radix 2 transform length and add amplitude compensation factor
     which cannot be included into the exponent above */
  switch ( (tl) >> (log2_tl - 2) ) {
    case 0x7: /* 10 ms, 1/tl = 1.0/(FDKpow(2.0, -log2_tl) * 0.53333333333333333333) */
      if (gain_m == (FIXP_DBL)0) {
        gain_m = FL2FXCONST_DBL(0.53333333333333333333f);
      } else {
        gain_m = fMult(gain_m, FL2FXCONST_DBL(0.53333333333333333333f));
      }
      break;
    case 0x6: /* 3/4 of radix 2, 1/tl = 1.0/(FDKpow(2.0, -log2_tl) * 2.0/3.0) */
      if (gain_m == (FIXP_DBL)0) {
        gain_m = FL2FXCONST_DBL(2.0/3.0f);
      } else {
        gain_m = fMult(gain_m, FL2FXCONST_DBL(2.0/3.0f));
      }
      break;
    case 0x4:
      /* radix 2, nothing to do. */
      break;
    default:
      /* unsupported */
      FDK_ASSERT(0);
      break;
  }

  *pGain_m = gain_m;
  *pGain_e = gain_e;
}
void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers) {
  int i, c, j;
  /* prepare 12 instances of node buffers */
  for (i = 0; i < 12; i++) {
    for (j = 0; j < NUM_LNB_FRAMES; j++) {
      drcGainBuffers->linearNodeBuffer[i].nNodes[j] = 1;
      drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].gainLin =
          FL2FXCONST_DBL(1.0f / (float)(1 << 7));
      if (j == 0) {
        drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time =
            0; /* initialize last node with startup node */
      } else {
        drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time =
            frameSize - 1;
      }
    }
  }

  /* prepare dummyLnb, a linearNodeBuffer containing a constant gain of 0 dB,
   * for the "no DRC processing" case */
  drcGainBuffers->dummyLnb.gainInterpolationType = GIT_LINEAR;
  for (i = 0; i < NUM_LNB_FRAMES; i++) {
    drcGainBuffers->dummyLnb.nNodes[i] = 1;
    drcGainBuffers->dummyLnb.linearNode[i][0].gainLin =
        FL2FXCONST_DBL(1.0f / (float)(1 << 7));
    drcGainBuffers->dummyLnb.linearNode[i][0].time = frameSize - 1;
  }

  /* prepare channelGain delay line */
  for (c = 0; c < 8; c++) {
    for (i = 0; i < NUM_LNB_FRAMES; i++) {
      drcGainBuffers->channelGain[c][i] =
          FL2FXCONST_DBL(1.0f / (float)(1 << 8));
    }
  }

  drcGainBuffers->lnbPointer = 0;
}
/*!
  \brief     FDKaacEnc_CalcAutoCorrValue

  Calculate autocorellation value for one lag

  \param pointer to spectrum
  \param start line
  \param stop line
  \param lag to be calculated
  \param scaling of the lag

****************************************************************************/
static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue(
        const FIXP_DBL           *spectrum,
        const INT                 startLine,
        const INT                 stopLine,
        const INT                 lag,
        const INT                 scale
        )
{
    int i;
    FIXP_DBL result = FL2FXCONST_DBL(0.f);

    if (lag==0) {
      for (i=startLine; i<stopLine; i++) {
        result += (fPow2(spectrum[i])>>scale);
      }
    }
    else {
      for (i=startLine; i<(stopLine-lag); i++) {
/*!
  \brief     FDKaacEnc_ScaleUpSpectrum

  Scales up spectrum lines in a given frequency section

  \param scaled spectrum
  \param original spectrum
  \param frequency line to start scaling
  \param frequency line to enc scaling

  \return scale factor

****************************************************************************/
static inline INT FDKaacEnc_ScaleUpSpectrum(
        FIXP_DBL                 *dest,
        const FIXP_DBL           *src,
        const INT                 startLine,
        const INT                 stopLine
        )
{
    INT i, scale;

    FIXP_DBL maxVal = FL2FXCONST_DBL(0.f);

    /* Get highest value in given spectrum */
    for (i=startLine; i<stopLine; i++) {
      maxVal = fixMax(maxVal,fixp_abs(src[i]));
    }
    scale = CountLeadingBits(maxVal);

    /* Scale spectrum according to highest value */
    for (i=startLine; i<stopLine; i++) {
      dest[i] = src[i]<<scale;
    }

    return scale;
}
Exemple #9
0
static inline INT_PCM AdvanceFilter(LP_FILTER *downFilter,  /*!< pointer to iir filter instance */
                                     INT_PCM  *pInput,          /*!< input of filter                */
                                     int downRatio,
                                     int inStride)
{
  INT_PCM output;
  int i, n;


#ifdef RS_BIQUAD_SCATTERGAIN
#define BIQUAD_SCALE 3
#else
#define BIQUAD_SCALE 12
#endif

  FIXP_DBL y = FL2FXCONST_DBL(0.0f);
  FIXP_DBL input;

  for (n=0; n<downRatio; n++)
  {
    FIXP_BQS (*states)[2] = downFilter->states;
    const FIXP_SGL *coeff = downFilter->coeffa;
    int s1,s2;

    s1 = downFilter->ptr;
    s2 = s1 ^ 1;

#if (SAMPLE_BITS == 16)
    input =  ((FIXP_DBL)pInput[n*inStride]) << (DFRACT_BITS-SAMPLE_BITS-BIQUAD_SCALE);
#elif (SAMPLE_BITS == 32)
    input =  pInput[n*inStride] >> BIQUAD_SCALE;
#else
#error NOT IMPLEMENTED
#endif

#ifndef RS_BIQUAD_SCATTERGAIN /* Merged Direct form I */

    FIXP_BQS state1, state2, state1b, state2b;

    state1 = states[0][s1];
    state2 = states[0][s2];

    /* Loop over sections */
    for (i=0; i<downFilter->noCoeffs; i++)
    {
      FIXP_DBL state0;

      /* Load merged states (from next section) */
      state1b = states[i+1][s1];
      state2b = states[i+1][s2];

      state0 = input  + fMult(state1, coeff[B1]) + fMult(state2, coeff[B2]);
      y      = state0 - fMult(state1b, coeff[A1]) - fMult(state2b, coeff[A2]);

      /* Store new feed forward merge state */
      states[i+1][s2] = y<<1;
      /* Store new feed backward state */
      states[i][s2] = input<<1;

      /* Feedback output to next section. */
      input = y;

      /* Transfer merged states */
      state1 = state1b;
      state2 = state2b;

      /* Step to next coef set */
      coeff += BIQUAD_COEFSTEP;
    }
    downFilter->ptr ^= 1;
  }
  /* Apply global gain */
  y = fMult(y, downFilter->gain);

#else /* Direct form II */

    /* Loop over sections */
    for (i=0; i<downFilter->noCoeffs; i++)
    {
      FIXP_BQS state1, state2;
      FIXP_DBL state0;

      /* Load states */
      state1 = states[i][s1];
      state2 = states[i][s2];

      state0 = input  - fMult(state1, coeff[A1]) - fMult(state2, coeff[A2]);
      y = state0      + fMult(state1, coeff[B1]) + fMult(state2, coeff[B2]);
      /* Apply scattered gain */
      y = fMult(y, downFilter->gain);

      /* Store new state in normalized form */
#ifdef RS_BIQUAD_STATES16
      /* Do not saturate any state value ! The result would be unacceptable. Rounding makes SNR around 10dB better. */
      states[i][s2] = (FIXP_BQS)(LONG)((state0 + (FIXP_DBL)(1<<(DFRACT_BITS-FRACT_BITS-2))) >> (DFRACT_BITS-FRACT_BITS-1));
#else
      states[i][s2] = state0<<1;
#endif

      /* Feedback output to next section. */
      input=y;

      /* Step to next coef set */
      coeff += BIQUAD_COEFSTEP;
    }
    downFilter->ptr ^= 1;
  }
Exemple #10
0
/*******************************************************************************
 Functionname: subbandTPApply
 ******************************************************************************/
SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
  FIXP_DBL *qmfOutputRealDry[MAX_OUTPUT_CHANNELS];
  FIXP_DBL *qmfOutputImagDry[MAX_OUTPUT_CHANNELS];
  FIXP_DBL *qmfOutputRealWet[MAX_OUTPUT_CHANNELS];
  FIXP_DBL *qmfOutputImagWet[MAX_OUTPUT_CHANNELS];

  FIXP_DBL DryEner[MAX_INPUT_CHANNELS];
  FIXP_DBL scale[MAX_OUTPUT_CHANNELS];

  FIXP_DBL DryEnerLD64[MAX_INPUT_CHANNELS];
  FIXP_DBL WetEnerLD64[MAX_OUTPUT_CHANNELS];

  FIXP_DBL DryEner0 = FL2FXCONST_DBL(0.0f);
  FIXP_DBL WetEnerX, damp, tmp;
  FIXP_DBL dmxReal0, dmxImag0;
  int skipChannels[MAX_OUTPUT_CHANNELS];
  int n, ch, cplxBands, cplxHybBands;
  int dry_scale_dmx, wet_scale_dmx;
  int i_LF, i_RF;
  HANDLE_STP_DEC hStpDec;
  const FIXP_CFG *pBP;

  int nrgScale = (2 * self->clipProtectGainSF__FDK);

  hStpDec = self->hStpDec;

  /* set scalefactor and loop counter */
  FDK_ASSERT(SF_DRY >= 1);
  {
    cplxBands = BP_GF_SIZE;
    cplxHybBands = self->hybridBands;
    dry_scale_dmx = (2 * SF_DRY) - 2;
    wet_scale_dmx = 2;
  }

  /* setup pointer for forming the direct downmix signal */
  for (ch = 0; ch < self->numOutputChannels; ch++) {
    qmfOutputRealDry[ch] = &self->hybOutputRealDry__FDK[ch][7];
    qmfOutputRealWet[ch] = &self->hybOutputRealWet__FDK[ch][7];
    qmfOutputImagDry[ch] = &self->hybOutputImagDry__FDK[ch][7];
    qmfOutputImagWet[ch] = &self->hybOutputImagWet__FDK[ch][7];
  }

  /* clear skipping flag for all output channels */
  FDKmemset(skipChannels, 0, self->numOutputChannels * sizeof(int));

  /* set scale values to zero */
  FDKmemset(scale, 0, self->numOutputChannels * sizeof(FIXP_DBL));

  /* update normalisation energy with latest smoothed energy */
  if (hStpDec->update_old_ener == STP_UPDATE_ENERGY_RATE) {
    hStpDec->update_old_ener = 1;
    for (ch = 0; ch < self->numInputChannels; ch++) {
      hStpDec->oldDryEnerLD64[ch] =
          CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
    }
    for (ch = 0; ch < self->numOutputChannels; ch++) {
      hStpDec->oldWetEnerLD64[ch] =
          CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
    }
  } else {
    hStpDec->update_old_ener++;
  }

  /* get channel configuration */
  switch (self->treeConfig) {
    case TREE_212:
      i_LF = 0;
      i_RF = 1;
      break;
    default:
      return MPS_WRONG_TREECONFIG;
  }

  /* form the 'direct' downmix signal */
  pBP = hStpDec->BP_GF - BP_GF_START;
  switch (self->treeConfig) {
    case TREE_212:
      for (n = BP_GF_START; n < cplxBands; n++) {
        dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
        dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
        DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
      }
      DRY_ENER_WEIGHT(DryEner0);
      break;
    default:;
  }
  DryEner[0] = DryEner0;

  /* normalise the 'direct' signals */
  for (ch = 0; ch < self->numInputChannels; ch++) {
    DryEner[ch] = DryEner[ch] << (nrgScale);
    hStpDec->runDryEner[ch] =
        fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
        fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
    if (DryEner[ch] != FL2FXCONST_DBL(0.0f)) {
      DryEnerLD64[ch] =
          fixMax((CalcLdData(DryEner[ch]) - hStpDec->oldDryEnerLD64[ch]),
                 FL2FXCONST_DBL(-0.484375f));
    } else {
      DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
    }
  }
  if (self->treeConfig == TREE_212) {
    for (; ch < MAX_INPUT_CHANNELS; ch++) {
      DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
    }
  }

  /* normalise the 'diffuse' signals */
  pBP = hStpDec->BP_GF - BP_GF_START;
  for (ch = 0; ch < self->numOutputChannels; ch++) {
    if (skipChannels[ch]) {
      continue;
    }

    WetEnerX = FL2FXCONST_DBL(0.0f);
    for (n = BP_GF_START; n < cplxBands; n++) {
      tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET);
      tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET);
      WetEnerX += fMultDiv2(tmp, pBP[n]);
    }
    WET_ENER_WEIGHT(WetEnerX);

    WetEnerX = WetEnerX << (nrgScale);
    hStpDec->runWetEner[ch] =
        fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
        fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);

    if (WetEnerX == FL2FXCONST_DBL(0.0f)) {
      WetEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
    } else {
      WetEnerLD64[ch] =
          fixMax((CalcLdData(WetEnerX) - hStpDec->oldWetEnerLD64[ch]),
                 FL2FXCONST_DBL(-0.484375f));
    }
  }

  /* compute scale factor for the 'diffuse' signals */
  switch (self->treeConfig) {
    case TREE_212:
      if (DryEner[0] != FL2FXCONST_DBL(0.0f)) {
        CALC_WET_SCALE(0, i_LF);
        CALC_WET_SCALE(0, i_RF);
      }
      break;
    default:;
  }

  damp = FL2FXCONST_DBL(0.1f / (1 << SF_SCALE));
  for (ch = 0; ch < self->numOutputChannels; ch++) {
    /* damp the scaling factor */
    scale[ch] = damp + fMult(FL2FXCONST_DBL(0.9f), scale[ch]);

    /* limiting the scale factor */
    if (scale[ch] > STP_SCALE_LIMIT__FDK) {
      scale[ch] = STP_SCALE_LIMIT__FDK;
    }
    if (scale[ch] < ONE_DIV_STP_SCALE_LIMIT__FDK) {
      scale[ch] = ONE_DIV_STP_SCALE_LIMIT__FDK;
    }

    /* low pass filter the scaling factor */
    scale[ch] =
        fMult(STP_LPF_COEFF2__FDK, scale[ch]) +
        fMult(ONE_MINUS_STP_LPF_COEFF2__FDK, hStpDec->prev_tp_scale[ch]);
    hStpDec->prev_tp_scale[ch] = scale[ch];
  }

  /* combine 'direct' and scaled 'diffuse' signal */
  FDK_ASSERT((HP_SIZE - 3 + 10 - 1) == PC_NUM_HYB_BANDS);
  const SCHAR *channlIndex = row2channelSTP[self->treeConfig];

  for (ch = 0; ch < self->numOutputChannels; ch++) {
    int no_scaling;

    no_scaling = !frame->tempShapeEnableChannelSTP[channlIndex[ch]];
    if (no_scaling) {
      combineSignalCplx(
          &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
          &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
          &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
          &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
          cplxHybBands - self->tp_hybBandBorder);

    } else {
      FIXP_DBL scaleX;
      scaleX = scale[ch];
      pBP = hStpDec->BP - self->tp_hybBandBorder;
      /* Band[HP_SIZE-3+10-1] needs not to be processed in
         combineSignalCplxScale1(), because pB[HP_SIZE-3+10-1] would be 1.0 */
      combineSignalCplxScale1(
          &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
          &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
          &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
          &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
          &pBP[self->tp_hybBandBorder], scaleX,
          (HP_SIZE - 3 + 10 - 1) - self->tp_hybBandBorder);

      {
        combineSignalCplxScale2(
            &self->hybOutputRealDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
            &self->hybOutputImagDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
            &self->hybOutputRealWet__FDK[ch][HP_SIZE - 3 + 10 - 1],
            &self->hybOutputImagWet__FDK[ch][HP_SIZE - 3 + 10 - 1], scaleX,
            cplxHybBands - (HP_SIZE - 3 + 10 - 1));
      }
    }
  }

  return (SACDEC_ERROR)MPS_OK;
  ;
}
Exemple #11
0
  { 52000, 60000,  22050, 2,  9,11, 9, 9,  3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
  { 60000, 76000,  22050, 2, 10,12,10,11,  3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
  { 76000, 82000,  22050, 2, 12,12,11,11,  3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
  { 82000,128001,  22050, 2, 13,12,11,11,  3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */

  /* 24/48 kHz dual rate */
  { 32000, 36000,  24000, 2,  5, 4, 7, 6,  2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
  { 36000, 44000,  24000, 2,  4, 8, 8, 8,  2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
  { 44000, 52000,  24000, 2,  6,10, 8, 8,  3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
  { 52000, 60000,  24000, 2,  9,11, 9, 9,  3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
  { 60000, 76000,  24000, 2, 11,12,10,11,  3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
  { 76000, 88000,  24000, 2, 12,13,11,11,  3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
  { 88000,128001,  24000, 2, 13,13,11,11,  3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 92 kbit/s */


};

const psTuningTable_t psTuningTable[4] =
{
  {  8000,  22000, PSENC_STEREO_BANDS_10, PSENC_NENV_1, FL2FXCONST_DBL(3.0f/4.0f) },
  { 22000,  28000, PSENC_STEREO_BANDS_20, PSENC_NENV_1, FL2FXCONST_DBL(2.0f/4.0f) },
  { 28000,  36000, PSENC_STEREO_BANDS_20, PSENC_NENV_2, FL2FXCONST_DBL(1.5f/4.0f) },
  { 36000, 160001, PSENC_STEREO_BANDS_20, PSENC_NENV_4, FL2FXCONST_DBL(1.1f/4.0f) },
};


//@}



Exemple #12
0

/**
 * \brief Generate a vector of noise of given length. The noise values are
 *        scaled in order to yield a noise energy of 1.0
 * \param spec pointer to were the noise values will be written to.
 * \param size amount of noise values to be generated.
 * \param pRandomState pointer to the state of the random generator being used.
 * \return exponent of generated noise vector.
 */
static int GenerateRandomVector (FIXP_DBL *RESTRICT spec,
                                  int size,
                                  int *pRandomState)
{
  int i, invNrg_e = 0, nrg_e = 0;
  FIXP_DBL invNrg_m, nrg_m = FL2FXCONST_DBL(0.0f) ;
  FIXP_DBL *RESTRICT ptr = spec;
  int randomState = *pRandomState;

#define GEN_NOISE_NRG_SCALE 7

  /* Generate noise and calculate energy. */
  for (i=0; i<size; i++)
  {
    randomState = (1664525L * randomState) + 1013904223L; // Numerical Recipes
    nrg_m = fPow2AddDiv2(nrg_m, (FIXP_DBL)randomState>>GEN_NOISE_NRG_SCALE);
    *ptr++ = (FIXP_DBL)randomState;
  }
  nrg_e = GEN_NOISE_NRG_SCALE*2 + 1;

  /* weight noise with = 1 / sqrt_nrg; */
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]);
  }
}
static INVF_MODE
decisionAlgorithm(const DETECTOR_PARAMETERS *detectorParams,     /*!< Struct with the detector parameters. */
                  DETECTOR_VALUES *detectorValues,               /*!< Struct with the detector values. */
                  INT transientFlag,                             /*!< Flag indicating if there is a transient present.*/
                  INT* prevRegionSbr,                            /*!< The previous region in which the Sbr value was. */
                  INT* prevRegionOrig                            /*!< The previous region in which the Orig value was. */
                  )
{
  INT invFiltLevel, regionSbr, regionOrig, regionNrg;

  /*
   Current thresholds.
   */
  const FIXP_DBL *quantStepsSbr  = detectorParams->quantStepsSbr;
  const FIXP_DBL *quantStepsOrig = detectorParams->quantStepsOrig;
  const FIXP_DBL *nrgBorders     = detectorParams->nrgBorders;
  const INT numRegionsSbr     = detectorParams->numRegionsSbr;
  const INT numRegionsOrig    = detectorParams->numRegionsOrig;
  const INT numRegionsNrg     = detectorParams->numRegionsNrg;

  FIXP_DBL quantStepsSbrTmp[MAX_NUM_REGIONS];
  FIXP_DBL quantStepsOrigTmp[MAX_NUM_REGIONS];

  /*
   Current detector values.
   */
  FIXP_DBL origQuotaMeanFilt;
  FIXP_DBL sbrQuotaMeanFilt;
  FIXP_DBL nrg;

  /* 0.375 = 3.0 / 8.0; 0.31143075889 = log2(RELAXATION)/64.0; 0.625 = log(16)/64.0; 0.6875 = 44/64.0 */
  origQuotaMeanFilt = (fMultDiv2(FL2FXCONST_DBL(2.f*0.375f), (FIXP_DBL)(CalcLdData(max(detectorValues->origQuotaMeanFilt,(FIXP_DBL)1)) + FL2FXCONST_DBL(0.31143075889f)))) << 0;  /* scaled by 1/2^9 */
  sbrQuotaMeanFilt  = (fMultDiv2(FL2FXCONST_DBL(2.f*0.375f), (FIXP_DBL)(CalcLdData(max(detectorValues->sbrQuotaMeanFilt,(FIXP_DBL)1)) + FL2FXCONST_DBL(0.31143075889f)))) << 0;   /* scaled by 1/2^9 */
  /* If energy is zero then we will get different results for different word lengths. */
  nrg               = (fMultDiv2(FL2FXCONST_DBL(2.f*0.375f), (FIXP_DBL)(CalcLdData(detectorValues->avgNrg+(FIXP_DBL)1) + FL2FXCONST_DBL(0.0625f) + FL2FXCONST_DBL(0.6875f)))) << 0;     /* scaled by 1/2^8; 2^44 -> qmf energy scale */

  FDKmemcpy(quantStepsSbrTmp,quantStepsSbr,numRegionsSbr*sizeof(FIXP_DBL));
  FDKmemcpy(quantStepsOrigTmp,quantStepsOrig,numRegionsOrig*sizeof(FIXP_DBL));

  if(*prevRegionSbr < numRegionsSbr)
    quantStepsSbrTmp[*prevRegionSbr] = quantStepsSbr[*prevRegionSbr] + hysteresis;
  if(*prevRegionSbr > 0)
    quantStepsSbrTmp[*prevRegionSbr - 1] = quantStepsSbr[*prevRegionSbr - 1] - hysteresis;

  if(*prevRegionOrig < numRegionsOrig)
    quantStepsOrigTmp[*prevRegionOrig] = quantStepsOrig[*prevRegionOrig] + hysteresis;
  if(*prevRegionOrig > 0)
    quantStepsOrigTmp[*prevRegionOrig - 1] = quantStepsOrig[*prevRegionOrig - 1] - hysteresis;

  regionSbr  = findRegion(sbrQuotaMeanFilt, quantStepsSbrTmp, numRegionsSbr);
  regionOrig = findRegion(origQuotaMeanFilt, quantStepsOrigTmp, numRegionsOrig);
  regionNrg  = findRegion(nrg,nrgBorders,numRegionsNrg);

  *prevRegionSbr = regionSbr;
  *prevRegionOrig = regionOrig;

  /* Use different settings if a transient is present*/
  invFiltLevel = (transientFlag == 1) ? detectorParams->regionSpaceTransient[regionSbr][regionOrig]
                                      : detectorParams->regionSpace[regionSbr][regionOrig];

  /* Compensate for low energy.*/
  invFiltLevel = max(invFiltLevel + detectorParams->EnergyCompFactor[regionNrg],0);

  return (INVF_MODE) (invFiltLevel);
}
#include "sf_estim.h"
#include "aacEnc_rom.h"
#include "quantize.h"
#include "bit_cnt.h"




#define AS_PE_FAC_SHIFT 7
#define DIST_FAC_SHIFT  3
#define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT)
static const INT MAX_SCF_DELTA = 60;


static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(3.0f/AS_PE_FAC_FLOAT);          /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */
static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(1.3219281f/AS_PE_FAC_FLOAT);    /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */
static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f);                    /* 1-C2/C1 */


/*
  Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel

  Description: Calculates the formfactor

  sf: scale factor of the mdct spectrum
  sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) * (2^FORM_FAC_SHIFT))
*/
static void
FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(FIXP_DBL *RESTRICT sfbFormFactorLdData,
                      PSY_OUT_CHANNEL *RESTRICT psyOutChan)
                                   FL2FXCONST_SGL(0.0f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(0.005f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(0.0312f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(0.0781f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(0.1953f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(0.4883f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(1.2207f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(3.0518f / (float)(1 << 2))};

const SCHAR slopeSteepness_huffman[14][2] = {
    {1, -57},  {-58, 2},   {3, 4},    {5, 6},    {7, -56},
    {8, -60},  {-61, -55}, {9, -59},  {10, -54}, {-64, 11},
    {-51, 12}, {-62, -50}, {-63, 13}, {-52, -53}};

const FIXP_DBL downmixCoeff[] = {
    FL2FXCONST_DBL(1.0000000000 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.9440608763 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.8912509381 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.8413951416 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.7943282347 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.7498942093 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.7079457844 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.6683439176 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.6309573445 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.5956621435 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.5623413252 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.5308844442 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.5011872336 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.4216965034 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.3548133892 / (float)(1 << 2)),
    FL2FXCONST_DBL(0.0000000000 / (float)(1 << 2))};
    /* 48/96 kHz dual rate */
    {CODEC_AACLD, 60000, 80000, 48000, 2, 7, 7, 10, 10, 2, 0, -3,
     SBR_SWITCH_LRC, 2},
    {CODEC_AACLD, 80000, 112000, 48000, 2, 9, 9, 10, 10, 3, 0, -3,
     SBR_LEFT_RIGHT, 1},
    {CODEC_AACLD, 112000, 144000, 48000, 2, 11, 11, 11, 11, 3, 0, -3,
     SBR_LEFT_RIGHT, 1},
    {CODEC_AACLD, 144000, 176000, 48000, 2, 12, 12, 11, 11, 3, 0, -3,
     SBR_LEFT_RIGHT, 1},
    {CODEC_AACLD, 176000, 256001, 48000, 2, 13, 13, 11, 11, 3, 0, -3,
     SBR_LEFT_RIGHT, 1},

};

const int sbrTuningTableSize =
    sizeof(sbrTuningTable) / sizeof(sbrTuningTable[0]);

const psTuningTable_t psTuningTable[4] = {
    {8000, 22000, PSENC_STEREO_BANDS_10, PSENC_NENV_1,
     FL2FXCONST_DBL(3.0f / 4.0f)},
    {22000, 28000, PSENC_STEREO_BANDS_20, PSENC_NENV_1,
     FL2FXCONST_DBL(2.0f / 4.0f)},
    {28000, 36000, PSENC_STEREO_BANDS_20, PSENC_NENV_2,
     FL2FXCONST_DBL(1.5f / 4.0f)},
    {36000, 160001, PSENC_STEREO_BANDS_20, PSENC_NENV_4,
     FL2FXCONST_DBL(1.1f / 4.0f)},
};

//@}
Exemple #18
0
void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
                       PVC_DYNAMIC_DATA *pPvcDynamicData,
                       FIXP_DBL **qmfSlotReal, FIXP_DBL **qmfSlotImag,
                       const int qmfExponent, const int pvcBorder0,
                       const int timeSlotNumber, FIXP_DBL predictedEsgSlot[],
                       int *predictedEsg_exp) {
  int i, band, ksg, ksg_start = 0;
  int RATE = pPvcDynamicData->RATE;
  int Esg_index = pPvcStaticData->Esg_slot_index;
  const SCHAR *sg_borders = pPvcDynamicData->sg_offset_low;
  FIXP_DBL *pEsg = pPvcStaticData->Esg[Esg_index];
  FIXP_DBL E[PVC_NBLOW] = {0};

  /* Subband grouping in QMF subbands below SBR range */
  /* Within one timeslot ( i = [0...(RATE-1)] QMF subsamples) calculate energy
     E(ib,t) and group them to Esg(ksg,t). Then transfer values to logarithmical
     domain and store them for time domain smoothing. (7.5.6.3 Subband grouping
     in QMF subbands below SBR range)
  */
  for (ksg = 0; sg_borders[ksg] < 0; ksg++) {
    pEsg[ksg] = FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */
    ksg_start++;
  }

  for (i = 0; i < RATE; i++) {
    FIXP_DBL *qmfR, *qmfI;
    qmfR = qmfSlotReal[i];
    qmfI = qmfSlotImag[i];
    for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
      for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
        /* The division by 8 == (RATE*lbw) is required algorithmically */
        E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2;
      }
    }
  }
  for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
    if (E[ksg] > (FIXP_DBL)0) {
      /* 10/log2(10) = 0.752574989159953 * 2^2 */
      int exp_log;
      FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log);
      nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC));
      nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
      pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)));
    } else {
      pEsg[ksg] =
          FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */
    }
  }

  /* Time domain smoothing of subband-grouped energy */
  {
    int idx = pPvcStaticData->Esg_slot_index;
    FIXP_DBL *pEsg_filt;
    FIXP_SGL SCcoeff;

    E[0] = E[1] = E[2] = (FIXP_DBL)0;
    for (i = 0; i < pPvcDynamicData->ns; i++) {
      SCcoeff = pPvcDynamicData->pSCcoeffs[i];
      pEsg_filt = pPvcStaticData->Esg[idx];
      /* Div2 is compensated by scaling of coeff table */
      E[0] = fMultAddDiv2(E[0], pEsg_filt[0], SCcoeff);
      E[1] = fMultAddDiv2(E[1], pEsg_filt[1], SCcoeff);
      E[2] = fMultAddDiv2(E[2], pEsg_filt[2], SCcoeff);
      if (i >= pPvcDynamicData->pastEsgSlotsAvail) {
        /* if past Esg values are not available use the ones from the last valid
         * slot */
        continue;
      }
      if (idx > 0) {
        idx--;
      } else {
        idx += PVC_NS_MAX - 1;
      }
    }
  }

  /* SBR envelope scalefactor prediction */
  {
    int E_high_exp[PVC_NBHIGH_MAX];
    int E_high_exp_max = 0;
    int pvcTab1ID;
    int pvcTab2ID = (int)pPvcDynamicData->pPvcID[timeSlotNumber];
    const UCHAR *pTab1, *pTab2;
    if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[0]) {
      pvcTab1ID = 0;
    } else if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[1]) {
      pvcTab1ID = 1;
    } else {
      pvcTab1ID = 2;
    }
    pTab1 = &(pPvcDynamicData
                  ->pPVCTab1[pvcTab1ID * PVC_NBLOW * pPvcDynamicData->nbHigh]);
    pTab2 = &(pPvcDynamicData->pPVCTab2[pvcTab2ID * pPvcDynamicData->nbHigh]);
    for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
      FIXP_SGL predCoeff;
      FIXP_DBL accu;
      int predCoeff_exp, kb;
      E_high_exp[ksg] = 0;

      /* residual part */
      accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP +
                                         pPvcDynamicData->pScalingCoef[3]);

      /* linear combination of lower grouped energies part */
      for (kb = 0; kb < PVC_NBLOW; kb++) {
        predCoeff = (FIXP_SGL)(
            (SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
        predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] +
                        1; /* +1 to compensate for Div2 */
        accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp;
      }
      /* convert back to linear domain */
      accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
      accu = f2Pow(
          accu, PVC_ESG_EXP - 1,
          &predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */
      predictedEsgSlot[ksg] = accu;
      E_high_exp[ksg] = predCoeff_exp;
      if (predCoeff_exp > E_high_exp_max) {
        E_high_exp_max = predCoeff_exp;
      }
    }

    /* rescale output vector according to largest exponent */
    for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
      int scale = E_high_exp[ksg] - E_high_exp_max;
      predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale);
    }
    *predictedEsg_exp = E_high_exp_max;
  }

  pPvcStaticData->Esg_slot_index =
      (pPvcStaticData->Esg_slot_index + 1) & (PVC_NS_MAX - 1);
  pPvcDynamicData->pastEsgSlotsAvail =
      fMin(pPvcDynamicData->pastEsgSlotsAvail + 1, PVC_NS_MAX - 1);
  return;
}
Exemple #19
0
 BQC(1.55727745512726),   BQC(1.00000011737815),  BQC(0.712515423588351),     BQC( 0.268752723900498),
 BQC(1.33407591943643),   BQC(0.999999795953228), BQC(0.625059117330989),     BQC( 0.316194685288965),
 BQC(1.10689898412458),   BQC(1.00000035057114),  BQC(0.52803514366398),      BQC( 0.370517843224669),
 BQC(0.89060371078454),   BQC(0.999999343962822), BQC(0.426920462165257),     BQC( 0.429608200207746),
 BQC(0.694438261209433),  BQC( 1.0000008629792),  BQC(0.326530699561716),     BQC( 0.491714450654174),
 BQC(0.523237800935322),  BQC(1.00000101349782),  BQC(0.230829556274851),     BQC( 0.555559034843281),
 BQC(0.378631165929563),  BQC(0.99998986482665),  BQC(0.142906422036095),     BQC( 0.620338874442411),
 BQC(0.260786911308437),  BQC(1.00003261460178),  BQC(0.0651008576256505),    BQC( 0.685759923926262),
 BQC(0.168409429188098),  BQC(0.999933049695828), BQC(-0.000790067789975562), BQC( 0.751905896602325),
 BQC(0.100724533818628),  BQC(1.00009472669872),  BQC(-0.0533772830257041),   BQC( 0.81930744384525),
 BQC(0.0561434357867363), BQC(0.999911636304276), BQC(-0.0913550299236405),   BQC( 0.88883625875915),
 BQC(0.0341680678662057), BQC(1.00003667508676),  BQC(-0.113405185536697),    BQC( 0.961756638268446)
};

#ifdef RS_BIQUAD_SCATTERGAIN
static const FIXP_DBL g48 = FL2FXCONST_DBL(0.67436532061161992682404480717671 - 0.001);
#else
static const FIXP_DBL g48 = FL2FXCONST_DBL(0.002712866530047) - (FIXP_DBL)0x8000;
#endif

static const struct FILTER_PARAM param_set48 = {
  sos48,
  g48,
  480,
  15,
  4 /* LF 2 */
};

/**
 *\brief Low Pass
 Wc = 0,5, order 24, Stop Band -96dB. Wc criteria is "almost 0dB passband", not the usual -3db gain point.
Exemple #20
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 );
}
Exemple #21
0
   Initial author:       M. Lohwasser
   contents/description: pns.c

******************************************************************************/

#include "aacenc_pns.h"
#include "psy_data.h"
#include "pnsparam.h"
#include "noisedet.h"
#include "bit_cnt.h"
#include "interface.h"


/* minCorrelationEnergy = (1.0e-10f)^2 ~ 2^-67 = 2^-47 * 2^-20 */
static const FIXP_DBL minCorrelationEnergy = FL2FXCONST_DBL(0.0); /* FL2FXCONST_DBL((float)FDKpow(2.0,-47)); */
/* noiseCorrelationThresh = 0.6^2 */
static const FIXP_DBL noiseCorrelationThresh = FL2FXCONST_DBL(0.36);

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 );

static void FDKaacEnc_CalcNoiseNrgs( const INT   sfbActive,
Exemple #22
0

void FDKaacEnc_CalculateFullTonality(FIXP_DBL      *RESTRICT spectrum,
						             INT           *RESTRICT sfbMaxScaleSpec,
                                     FIXP_DBL      *RESTRICT sfbEnergyLD64,
                                     FIXP_SGL      *RESTRICT sfbTonality,
                                     INT            sfbCnt,
                                     const INT     *sfbOffset,
                                     INT            usePns)
{
  INT j;
#if defined(ARCH_PREFER_MULT_32x16)
  FIXP_SGL alpha_0 = FL2FXCONST_SGL(0.25f);       /* used in smooth ChaosMeasure */
  FIXP_SGL alpha_1 = FL2FXCONST_SGL(1.0f-0.25f);  /* used in smooth ChaosMeasure */
#else
  FIXP_DBL alpha_0 = FL2FXCONST_DBL(0.25f);       /* used in smooth ChaosMeasure */
  FIXP_DBL alpha_1 = FL2FXCONST_DBL(1.0f-0.25f);  /* used in smooth ChaosMeasure */
#endif
  INT numberOfLines = sfbOffset[sfbCnt];

  if (!usePns)
    return;

  C_ALLOC_SCRATCH_START(chaosMeasurePerLine, FIXP_DBL, (1024));
  /* calculate chaos measure */
  FDKaacEnc_CalculateChaosMeasure(spectrum,
                        numberOfLines,
                        chaosMeasurePerLine);

  /* smooth ChaosMeasure */
  for (j=1;j<numberOfLines;j++) {
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) {