⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aac_enc_quantization_fp.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 3 页
字号:
  *bitsForScaleFactorData = bits_for_scale_factor_data;

  common_scalefactor += SF_OFFSET;

  if (!pBlock->ns_mode) {
    for (i = 0; i < num_scale_factor; i++) {
      pStream->scale_factors[i] = (Ipp16s)common_scalefactor;
    }
  }
}

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

static Ipp32f aac_NoiseCalculation(Ipp32f* mdct_scaled,
                                   Ipp32f* mdct_line_abs,
                                   Ipp16s* scalefactor,
                                   Ipp16s* maxXQuant,
                                   Ipp32s  width)

{
  Ipp32f sf, temp, real_sf, noise;
  Ipp32f mdct_rqnt[N_LONG/2];
  Ipp16s x_quant_unsigned[N_LONG/2];

  sf = (Ipp32f)scalefac_pow[scalefactor[0] + SF_OFFSET];
  temp = (Ipp32f)(MAGIC_NUMBER - 0.5f)/sf;
  ippsAddC_32f(mdct_scaled, temp, mdct_rqnt, width);
  ippsMulC_Low_32f16s(mdct_rqnt, sf, x_quant_unsigned, width);
  ippsPow43_16s32f(x_quant_unsigned, mdct_rqnt, width);
  ippsCalcSF_16s32f(scalefactor, 0, &real_sf, 1);
  ippsMulC_32f_I(real_sf, mdct_rqnt, width);
  ippsSub_32f_I(mdct_line_abs, mdct_rqnt, width);
  ippsDotProd_32f(mdct_rqnt, mdct_rqnt, width, &noise);
  ippsMax_16s(x_quant_unsigned, width, maxXQuant);

  return noise;
}

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

void aac_FindSF(sEnc_individual_channel_stream* pStream,
                sQuantizationData* qData,
                Ipp32f* mdct_scaled,
                Ipp32f* mdct_line_abs,
                Ipp32s* startSF,
                Ipp32s* finishSF,
                Ipp16s* scalefac,
                Ipp16s* maxXQuant)
{
  Ipp16s scalefactor;
  Ipp32f noise;
  Ipp32s sfb;
  Ipp32f *noiseThr = qData->noiseThr;
  Ipp32s stopSF;
  Ipp32s *sfb_offset = pStream->sfb_offset;
  Ipp32s *sfb_width = pStream->sfb_width;

  for (sfb = 0; sfb < pStream->num_window_groups * pStream->max_sfb; sfb++) {
    Ipp32s sfb_start = sfb_offset[sfb];
    Ipp32s width = sfb_width[sfb];
    Ipp32s start_scalefac = startSF[sfb];
    Ipp32s finish_scalefac = finishSF[sfb];
    Ipp32s i, ind;
    Ipp32f sqrtMdctLine = 0;
    Ipp16s maxXQuantSaved;
    Ipp32f minNoise;

    for (i = 0; i < width; i++) {
      sqrtMdctLine += (Ipp32f)sqrt(mdct_line_abs[sfb_start+i]);
    }

    if ((noiseThr[sfb] > 0) && (qData->energy[sfb] >= noiseThr[sfb])) {
      Ipp32f tmp;

      tmp = (Ipp32f)log((27.0/4.0)*noiseThr[sfb]/sqrtMdctLine)/(Ipp32f)log(2);
      tmp *= (Ipp32f)8/(Ipp32f)3;
      scalefactor = (Ipp16s)(tmp+0.5);
      if (scalefactor < start_scalefac)  scalefactor = (Ipp16s)start_scalefac;
      if (scalefactor > finish_scalefac) scalefactor = (Ipp16s)finish_scalefac;

      noise = aac_NoiseCalculation(mdct_scaled + sfb_start, mdct_line_abs + sfb_start,
                                   &scalefactor, maxXQuant + sfb, width);

      minNoise = noise;
      ind = 0;
      maxXQuantSaved = maxXQuant[sfb];

      /* Let's check other scalefactors. */
      /* Perhaps quantization with bigger scalefactors will give us less noise. */

      stopSF = finish_scalefac - scalefactor + 1;
      if (stopSF > 5) stopSF = 5; /* magic value :) */

      for (i = 1; i < stopSF; i++) {
        Ipp16s scalefactor1 = scalefactor + (Ipp16s)i;
        if (scalefactor1 > finish_scalefac) scalefactor1 = (Ipp16s)finish_scalefac;
        noise = aac_NoiseCalculation(mdct_scaled + sfb_start, mdct_line_abs + sfb_start,
                                     &scalefactor1, maxXQuant + sfb, width);

        if (noise < minNoise) {
          minNoise = noise;
          ind = i;
          maxXQuantSaved = maxXQuant[sfb];
        }
      }
      scalefac[sfb] = scalefactor + (Ipp16s)ind;
      maxXQuant[sfb] = maxXQuantSaved;
    } else {
      scalefac[sfb] = -100;
      maxXQuant[sfb] = 0;
    }
  }
}

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

void aac_UpdateSF(sEnc_individual_channel_stream* pStream,
                  Ipp32f* mdct_scaled,
                  Ipp32f* mdct_line_abs,
                  Ipp32s* startSF,
                  Ipp16s* scalefac,
                  Ipp16s* maxXQuant,
                  Ipp32s  minSf,
                  Ipp32f  bitsToPeCoeff,
                  Ipp32f  possibleAddBits)
{
  Ipp32s numScf[MAX_SECTION_NUMBER];
  Ipp32s sfb_start[MAX_SECTION_NUMBER];
  Ipp32s width[MAX_SECTION_NUMBER];
  Ipp32s transferTable[MAX_SECTION_NUMBER];
  Ipp32s index[MAX_SECTION_NUMBER][61];
  Ipp32s tmpMaxXQuant[MAX_SECTION_NUMBER][61];
  Ipp32f numBits[MAX_SECTION_NUMBER][61];
  Ipp16s scalefactor0, mXQuant;
  Ipp32f minBits, iniBits;
  Ipp32f minNoise;
  Ipp32s i, j, sfb, bestIndx, realSfb;
  Ipp32s *sfb_offset = pStream->sfb_offset;
  Ipp32s *sfb_width = pStream->sfb_width;
  Ipp32s numSfb = pStream->num_window_groups * pStream->max_sfb;
  Ipp32f coeff = 0.3f * 3.0f/8.0f / (bitsToPeCoeff * 3.32f); /* 3.32 ~ 1/log10(2) */

  realSfb = 0;
  for (sfb = 0; sfb < numSfb; sfb++) {

    /* Exclude scalefactor bands which contain only zero elements */
    if (maxXQuant[sfb] != 0) {
      if (minSf > startSF[sfb]) {
        numScf[realSfb] = scalefac[sfb] - minSf + 1;
      } else {
        numScf[realSfb] = scalefac[sfb] - startSF[sfb] + 1;
      }

      width[realSfb] = sfb_width[sfb];

      for (i = 0; i < numScf[realSfb]; i++) {
        numBits[realSfb][i] = coeff * i * width[realSfb];
      }

      sfb_start[realSfb] = sfb_offset[sfb];
      transferTable[realSfb] = sfb;
      realSfb++;
    }
  }

  if (realSfb > 0) {
    numSfb = realSfb;

    iniBits = 0;

    for (sfb = 1; sfb < numSfb; sfb++) {
      Ipp32f addBits = possibleAddBits/(numSfb - sfb + 1);

      iniBits += sf_huff_codebook[2*(scalefac[transferTable[sfb]] -
                                     scalefac[transferTable[sfb-1]] + SF_MID)];

      for (i = 0; i < numScf[sfb]; i++) {
        Ipp32f bits[61];
        Ipp32s bestIdx;
        Ipp32s deltaSF = scalefac[transferTable[sfb]] - i -
                         scalefac[transferTable[sfb-1]];

        minBits = bits[0] = sf_huff_codebook[2*(deltaSF + SF_MID)] +
                            numBits[sfb-1][0];
        bestIdx = 0;

        deltaSF++;

        for (j = 1; j < numScf[sfb-1]; j++) {
          bits[j] = sf_huff_codebook[2*(deltaSF + SF_MID)] + numBits[sfb-1][j];
          if (minBits > bits[j]) {
            minBits = bits[j];
            bestIdx = j;
          }
          deltaSF++;
        }

        scalefactor0 = scalefac[transferTable[sfb-1]] - (Ipp16s)bestIdx;

        minNoise = aac_NoiseCalculation(mdct_scaled + sfb_start[sfb-1],
                                        mdct_line_abs + sfb_start[sfb-1],
                                        &scalefactor0, &mXQuant, width[sfb-1]);

        index[sfb-1][i] = bestIdx;
        tmpMaxXQuant[sfb-1][i] = mXQuant;
        scalefactor0 = scalefac[transferTable[sfb-1]];

        for (j = 0; j < numScf[sfb-1]; j++) {
          if (bits[j] <= minBits + addBits) {
            Ipp32f tmpNoise;

            tmpNoise = aac_NoiseCalculation(mdct_scaled + sfb_start[sfb-1],
                                            mdct_line_abs + sfb_start[sfb-1],
                                            &scalefactor0, &mXQuant, width[sfb-1]);

            if (tmpNoise <= minNoise) {
              minNoise = tmpNoise;
              index[sfb-1][i] = j;
              tmpMaxXQuant[sfb-1][i] = mXQuant;
            }
          }
          scalefactor0--;
        }
        numBits[sfb][i] += bits[index[sfb-1][i]];
        possibleAddBits -= bits[index[sfb-1][i]] - minBits;
      }
    }

    scalefactor0 = scalefac[transferTable[numSfb - 1]];

    minBits = numBits[numSfb-1][0];

    minNoise = aac_NoiseCalculation(mdct_scaled + sfb_start[numSfb-1],
                                    mdct_line_abs + sfb_start[numSfb-1],
                                    &scalefactor0, &mXQuant, width[numSfb-1]);

    index[sfb-1][0] = 0;
    tmpMaxXQuant[sfb-1][0] = mXQuant;
    scalefactor0--;

    for (j = 1; j < numScf[numSfb - 1]; j++) {
      Ipp32f tmpBits;

      tmpBits = numBits[numSfb - 1][j];

      if (tmpBits < minBits) {
        Ipp32f tmpNoise;

        tmpNoise = aac_NoiseCalculation(mdct_scaled + sfb_start[numSfb-1],
                                        mdct_line_abs + sfb_start[numSfb-1],
                                        &scalefactor0, &mXQuant, width[numSfb-1]);

        if (tmpNoise < minNoise) {
          minNoise = tmpNoise;
          minBits = tmpBits;
          index[numSfb-1][0] = j;
          tmpMaxXQuant[numSfb-1][0] = mXQuant;
        }
      }
      scalefactor0--;
    }

    bestIndx = index[numSfb-1][0];
    mXQuant = (Ipp16s)tmpMaxXQuant[numSfb-1][0];
    for (sfb = numSfb-1; sfb > 0; sfb--) {
      /* Include scalefactor bands which contain only zero elements */
      scalefac[transferTable[sfb]] -= (Ipp16s)bestIndx;
      maxXQuant[transferTable[sfb]] = mXQuant;
      mXQuant = (Ipp16s)tmpMaxXQuant[sfb-1][bestIndx];
      bestIndx = index[sfb-1][bestIndx];
    }
    /* Include scalefactor bands which contain only zero elements */
    scalefac[transferTable[0]] -= (Ipp16s)bestIndx;
    maxXQuant[transferTable[0]] = mXQuant;
  }
}

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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -