Beispiel #1
0
static
SBRDEC_DRC_CHANNEL * sbrDecoder_drcGetChannel( const HANDLE_SBRDECODER self, const INT channel )
{
  SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
  int elementIndex, elChanIdx=0, numCh=0;

  for (elementIndex = 0; (elementIndex < (8)) && (numCh <= channel); elementIndex++)
  {
    SBR_DECODER_ELEMENT *pSbrElement = self->pSbrElement[elementIndex];
    int c, elChannels;

    elChanIdx = 0;
    if (pSbrElement == NULL) break;

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

    /* Limit with actual allocated element channels */
    elChannels = FDKmin(elChannels, pSbrElement->nChannels);

    for (c = 0; (c < elChannels) && (numCh <= channel); c++) {
      if (pSbrElement->pSbrChannel[elChanIdx] != NULL) {
        numCh++;
        elChanIdx++;
      }
    }
  }
  elementIndex -= 1;
  elChanIdx -= 1;

  if (elChanIdx < 0 || elementIndex < 0) {
    return NULL;
  }

  if ( self->pSbrElement[elementIndex] != NULL ) {
    if ( self->pSbrElement[elementIndex]->pSbrChannel[elChanIdx] != NULL )
    {
      pSbrDrcChannelData = &self->pSbrElement[elementIndex]->pSbrChannel[elChanIdx]->SbrDec.sbrDrcChannel;
    }
  }

  return (pSbrDrcChannelData);
}
/*****************************************************************************

    functionname: FDKaacEnc_InitTnsConfiguration
    description:  fill TNS_CONFIG structure with sensible content
    returns:
    input:        bitrate, samplerate, number of channels,
                  blocktype (long or short),
                  TNS Config struct (modified),
                  psy config struct,
                  tns active flag
    output:

*****************************************************************************/
AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
                                                 INT sampleRate,
                                                 INT channels,
                                                 INT blockType,
                                                 INT granuleLength,
                                                 INT ldSbrPresent,
                                                 TNS_CONFIG *tC,
                                                 PSY_CONFIGURATION *pC,
                                                 INT active,
                                                 INT useTnsPeak)
{
  int i;
  //float acfTimeRes   = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f;

  if (channels <= 0)
    return (AAC_ENCODER_ERROR)1;

  /* initialize TNS filter flag, order, and coefficient resolution (in bits per coeff) */
  tC->tnsActive      = (active) ? TRUE : FALSE;
  tC->maxOrder       = (blockType == SHORT_WINDOW) ? 5 : 12;  /* maximum: 7, 20 */
  if (bitRate < 16000)
    tC->maxOrder -= 2;
  tC->coefRes        = (blockType == SHORT_WINDOW) ? 3 : 4;

  /* LPC stop line: highest MDCT line to be coded, but do not go beyond TNS_MAX_BANDS! */
  tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength, (blockType == SHORT_WINDOW) ? 1 : 0);

  if (tC->lpcStopBand < 0) {
    return (AAC_ENCODER_ERROR)1;
  }

  tC->lpcStopBand = FDKmin(tC->lpcStopBand, pC->sfbActive);
  tC->lpcStopLine    = pC->sfbOffset[tC->lpcStopBand];

  switch (granuleLength) {
    case 1024:
      /* TNS start line: skip lower MDCT lines to prevent artifacts due to filter mismatch */
      tC->lpcStartBand[LOFILT]   = (blockType == SHORT_WINDOW) ? 0 : ((sampleRate < 18783) ? 4 : 8);
      tC->lpcStartLine[LOFILT]   = pC->sfbOffset[tC->lpcStartBand[LOFILT]];

      i = tC->lpcStopBand;
      while (pC->sfbOffset[i] > (tC->lpcStartLine[LOFILT] + (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4)) i--;
      tC->lpcStartBand[HIFILT]   = i;
      tC->lpcStartLine[HIFILT]   = pC->sfbOffset[i];

      tC->confTab.threshOn[HIFILT] = 1437;
      tC->confTab.threshOn[LOFILT] = 1500;

      tC->confTab.tnsLimitOrder[HIFILT] = tC->maxOrder;
      tC->confTab.tnsLimitOrder[LOFILT] = tC->maxOrder - 7;

      tC->confTab.tnsFilterDirection[HIFILT] = FILTER_DIRECTION;
      tC->confTab.tnsFilterDirection[LOFILT] = FILTER_DIRECTION;

      tC->confTab.acfSplit[HIFILT] = -1;  /* signal Merged4to2QuartersAutoCorrelation in FDKaacEnc_MergedAutoCorrelation*/
      tC->confTab.acfSplit[LOFILT] = -1;  /* signal Merged4to2QuartersAutoCorrelation in FDKaacEnc_MergedAutoCorrelation */

      tC->confTab.filterEnabled[HIFILT] = 1;
      tC->confTab.filterEnabled[LOFILT] = 1;
      tC->confTab.seperateFiltersAllowed = 1;

      /* compute autocorrelation window based on maximum filter order for given block type */
      /* for (i = 0; i <= tC->maxOrder + 3; i++) {
           float acfWinTemp = acfTimeRes * i;
           acfWindow[i] = FL2FXCONST_DBL(1.0f - acfWinTemp * acfWinTemp);
         }
      */
      if (blockType == SHORT_WINDOW) {
        FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort, FDKmin(sizeof(acfWindowShort), sizeof(tC->acfWindow[HIFILT])));
        FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort, FDKmin(sizeof(acfWindowShort), sizeof(tC->acfWindow[HIFILT])));
      }
      else {
        FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong, FDKmin(sizeof(acfWindowLong), sizeof(tC->acfWindow[HIFILT])));
        FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong, FDKmin(sizeof(acfWindowLong), sizeof(tC->acfWindow[HIFILT])));
      }
      break;
    case 480:
    case 512:
      {
        const TNS_PARAMETER_TABULATED* pCfg = FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent);

        if ( pCfg != NULL ) {
          tC->lpcStartBand[HIFILT]         = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, pC->sfbOffset);
          tC->lpcStartLine[HIFILT]         = pC->sfbOffset[tC->lpcStartBand[HIFILT]];
          tC->lpcStartBand[LOFILT]         = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, pC->sfbOffset);
          tC->lpcStartLine[LOFILT]         = pC->sfbOffset[tC->lpcStartBand[LOFILT]];

          tC->confTab.threshOn[HIFILT] = pCfg->threshOn[HIFILT];
          tC->confTab.threshOn[LOFILT] = pCfg->threshOn[LOFILT];

          tC->confTab.tnsLimitOrder[HIFILT] = pCfg->tnsLimitOrder[HIFILT];
          tC->confTab.tnsLimitOrder[LOFILT] = pCfg->tnsLimitOrder[LOFILT];

          tC->confTab.tnsFilterDirection[HIFILT] = pCfg->tnsFilterDirection[HIFILT];
          tC->confTab.tnsFilterDirection[LOFILT] = pCfg->tnsFilterDirection[LOFILT];

          tC->confTab.acfSplit[HIFILT] = pCfg->acfSplit[HIFILT];
          tC->confTab.acfSplit[LOFILT] = pCfg->acfSplit[LOFILT];

          tC->confTab.filterEnabled[HIFILT] = pCfg->filterEnabled[HIFILT];
          tC->confTab.filterEnabled[LOFILT] = pCfg->filterEnabled[LOFILT];
          tC->confTab.seperateFiltersAllowed = pCfg->seperateFiltersAllowed;

          FDKaacEnc_CalcGaussWindow(tC->acfWindow[HIFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE);
          FDKaacEnc_CalcGaussWindow(tC->acfWindow[LOFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE);
        }
        else {
          tC->tnsActive = FALSE; /* no configuration available, disable tns tool */
        }
      }
      break;
    default:
      tC->tnsActive = FALSE; /* no configuration available, disable tns tool */
  }

  return AAC_ENC_OK;

}
TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(
                                               HANDLE_TRANSPORTENC hTp,
                                               INT frameUsedBits,
                                               int bufferFullness,
                                               int ncc
                                              )
{
  TRANSPORTENC_ERROR err = TRANSPORTENC_OK;

  if (!hTp) {
    return TRANSPORTENC_INVALID_PARAMETER;
  }
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream;

  /* In case of writing PCE in raw_data_block frameUsedBits must be adapted. */
  if (hTp->pceFrameCounter>=hTp->config.headerPeriod) {
    frameUsedBits += transportEnc_GetPCEBits(hTp->config.channelMode, hTp->config.matrixMixdownA, 3); /* Consider 3 bits ID signalling in alignment */
  }

  switch (hTp->transportFmt) {
    case TT_MP4_ADIF:
      FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0, BS_WRITER);
      adifWrite_EncodeHeader(
             &hTp->writer.adif,
              hBs,
              bufferFullness
              );
      break;
    case TT_MP4_ADTS:
      bufferFullness /= ncc;                          /* Number of Considered Channels */
      bufferFullness /= 32;
      bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
      adtsWrite_EncodeHeader(
             &hTp->writer.adts,
             &hTp->bitStream,
              bufferFullness,
              frameUsedBits
              );
      break;
    case TT_DABPLUS:
      bufferFullness /= ncc;                          /* Number of Considered Channels */
      bufferFullness /= 32;
      bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
      dabWrite_EncodeHeader(
             &hTp->writer.dab,
             &hTp->bitStream,
              bufferFullness,
              frameUsedBits
              );
      break;
    case TT_MP4_LOAS:
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      bufferFullness /= ncc;                         /* Number of Considered Channels */
      bufferFullness /= 32;
      bufferFullness = FDKmin(0xFF, bufferFullness); /* Signal variable rate */
      transportEnc_LatmWrite(
             &hTp->writer.latm,
              hBs,
              frameUsedBits,
              bufferFullness,
             &hTp->callbacks
              );
    break;
    case TT_MP4_RAW:
      if (hTp->writer.raw.curSubFrame >= hTp->writer.raw.nSubFrames) {
        hTp->writer.raw.curSubFrame = 0;
        FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0, BS_WRITER);
      }
      hTp->writer.raw.prevBits = FDKgetValidBits(hBs);
      break;
    default:
      err = TRANSPORTENC_UNSUPPORTED_FORMAT;
      break;
  }

  /* Write PCE in raw_data_block if required */
  if (hTp->pceFrameCounter>=hTp->config.headerPeriod) {
    INT crcIndex = 0;
    /* Align inside PCE with repsect to the first bit of the raw_data_block() */
    UINT alignAnchor = FDKgetValidBits(&hTp->bitStream);

    /* Write PCE element ID bits */
    FDKwriteBits(&hTp->bitStream, ID_PCE, 3);

    if ( (hTp->transportFmt==TT_MP4_ADTS) && !hTp->writer.adts.protection_absent) {
      crcIndex = adtsWrite_CrcStartReg(&hTp->writer.adts, &hTp->bitStream, 0);
    }

    /* Write PCE as first raw_data_block element */
    transportEnc_writePCE(&hTp->bitStream, hTp->config.channelMode, hTp->config.samplingRate, 0, 1, hTp->config.matrixMixdownA, hTp->config.flags & CC_PSEUDO_SURROUND, alignAnchor);

    if ( (hTp->transportFmt==TT_MP4_ADTS) && !hTp->writer.adts.protection_absent) {
      adtsWrite_CrcEndReg(&hTp->writer.adts, &hTp->bitStream, crcIndex);
    }
    hTp->pceFrameCounter = 0; /* reset pce frame counter */
  }

  if (hTp->pceFrameCounter!=-1) {
    hTp->pceFrameCounter++; /* Update pceFrameCounter only if PCE writing is active. */
  }

  return err;
}