コード例 #1
0
ファイル: env_dec.cpp プロジェクト: 0x0B501E7E/aac
/*!
  \brief   Convert from coupled channels to independent L/R data
*/
static void
sbr_envelope_unmapping (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
                        HANDLE_SBR_FRAME_DATA h_data_left,  /*!< pointer to left channel */
                        HANDLE_SBR_FRAME_DATA h_data_right) /*!< pointer to right channel */
{
  int i;
  FIXP_SGL tempL_m, tempR_m, tempRplus1_m, newL_m, newR_m;
  SCHAR   tempL_e, tempR_e, tempRplus1_e, newL_e, newR_e;


  /* 1. Unmap (already dequantized) coupled envelope energies */

  for (i = 0; i < h_data_left->nScaleFactors; i++) {
    tempR_m = (FIXP_SGL)((LONG)h_data_right->iEnvelope[i] & MASK_M);
    tempR_e = (SCHAR)((LONG)h_data_right->iEnvelope[i] & MASK_E);

    tempR_e -= (18 + NRG_EXP_OFFSET);  /* -18 = ld(UNMAPPING_SCALE / h_data_right->nChannels) */
    tempL_m = (FIXP_SGL)((LONG)h_data_left->iEnvelope[i] & MASK_M);
    tempL_e = (SCHAR)((LONG)h_data_left->iEnvelope[i] & MASK_E);

    tempL_e -= NRG_EXP_OFFSET;

    /* Calculate tempRight+1 */
    FDK_add_MantExp( tempR_m, tempR_e,
                     FL2FXCONST_SGL(0.5f), 1,  /* 1.0 */
                     &tempRplus1_m, &tempRplus1_e);

    FDK_divide_MantExp( tempL_m, tempL_e+1,  /*  2 * tempLeft */
                       tempRplus1_m, tempRplus1_e,
                       &newR_m, &newR_e );

    if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
      newR_m >>= 1;
      newR_e += 1;
    }

    newL_m = FX_DBL2FX_SGL(fMult(tempR_m,newR_m));
    newL_e = tempR_e + newR_e;

    h_data_right->iEnvelope[i] = ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) +
                                  (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NRG_EXP_OFFSET) & MASK_E);
    h_data_left->iEnvelope[i] =  ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) +
                                  (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NRG_EXP_OFFSET) & MASK_E);
  }
コード例 #2
0
ファイル: tonality.cpp プロジェクト: wlanjie/AndroidFFmpeg
                            INT           sfbCnt,
                            const INT     *RESTRICT sfbOffset,
                            FIXP_DBL      *RESTRICT sfbEnergyLD64 );


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);
コード例 #3
0
ファイル: aacenc_pns.cpp プロジェクト: ho1iarty/fdk-aac
/*****************************************************************************

    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 );
}
コード例 #4
0
ファイル: pvc_dec.cpp プロジェクト: ShiftMediaProject/fdk-aac
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;
}
コード例 #5
0
    {1, 2},    {3, 4},     {-63, -65}, {5, -66},   {-64, 6},   {-80, 7},
    {8, 9},    {-68, 10},  {11, 12},   {-56, -67}, {-61, 13},  {-62, -69},
    {14, 15},  {16, -72},  {-71, 17},  {-70, -60}, {18, -59},  {19, 20},
    {21, -79}, {-57, -73}, {22, -58},  {-76, 23},  {-75, -74}, {-78, -77}};

const SCHAR deltaGain_codingProfile_2_huffman[48][2] = {
    {1, 2},     {3, 4},     {5, 6},     {7, 8},     {9, 10},    {11, 12},
    {13, -65},  {14, -64},  {15, -66},  {16, -67},  {17, 18},   {19, -68},
    {20, -63},  {-69, 21},  {-59, 22},  {-61, -62}, {-60, 23},  {24, -58},
    {-70, -57}, {-56, -71}, {25, 26},   {27, -55},  {-72, 28},  {-54, 29},
    {-53, 30},  {-73, -52}, {31, -74},  {32, 33},   {-75, 34},  {-76, 35},
    {-51, 36},  {-78, 37},  {-77, 38},  {-96, 39},  {-48, 40},  {-50, -79},
    {41, 42},   {-80, -81}, {-82, 43},  {44, -49},  {45, -84},  {-83, -89},
    {-86, 46},  {-90, -85}, {-91, -93}, {-92, 47},  {-88, -87}, {-95, -94}};

const FIXP_SGL slopeSteepness[] = {FL2FXCONST_SGL(-3.0518f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(-1.2207f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(-0.4883f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(-0.1953f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(-0.0781f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(-0.0312f / (float)(1 << 2)),
                                   FL2FXCONST_SGL(-0.005f / (float)(1 << 2)),
                                   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))};