Пример #1
0
void FDK_QmfDomain_WorkBuffer2ProcChannel(
    const HANDLE_FDK_QMF_DOMAIN_IN qd_ch) {
  FDK_ASSERT(qd_ch != NULL);
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
  USHORT workBufferOffset = qd_ch->workBufferOffset;
  USHORT workBufferSectSize = qd_ch->workBufferSectSize;

  if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
                        qd_ch->workBuf_nBands) ==
      qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) {
    /* work buffer is part of processing channel => nothing to do */
    return;
  } else {
    /* copy parked new QMF data to processing channel */
    const int bands = qd_ch->workBuf_nBands;
    const int slots = qd_ch->workBuf_nTimeSlots;
    int ts;
    for (ts = 0; ts < slots; ts++) {
      FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
                FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
                                  workBufferSectSize, bands),
                sizeof(FIXP_DBL) * bands);  // parkBuf_to_anaMatrix
      workBufferOffset += bands;
      FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
                FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
                                  workBufferSectSize, bands),
                sizeof(FIXP_DBL) * bands);
      workBufferOffset += bands;
    }
  }
}
Пример #2
0
void FDK_QmfDomain_SaveOverlap(HANDLE_FDK_QMF_DOMAIN_IN qd_ch, int offset) {
  FDK_ASSERT(qd_ch != NULL);
  int ts;
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  int ovSlots = gc->nQmfOvTimeSlots;
  int nCols = gc->nQmfTimeSlots;
  int nProcBands = gc->nQmfProcBands;
  FIXP_DBL **qmfReal = qd_ch->hQmfSlotsReal;
  FIXP_DBL **qmfImag = qd_ch->hQmfSlotsImag;
  QMF_SCALE_FACTOR *pScaling = &qd_ch->scaling;

  /* for high part it would be enough to save only used part of overlap area */
  if (qmfImag != NULL) {
    for (ts = offset; ts < ovSlots; ts++) {
      FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
                sizeof(FIXP_DBL) * nProcBands);
      FDKmemcpy(qmfImag[ts], qmfImag[nCols + ts],
                sizeof(FIXP_DBL) * nProcBands);
    }
  } else {
    for (ts = 0; ts < ovSlots; ts++) {
      FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
                sizeof(FIXP_DBL) * nProcBands);
    }
  }
  pScaling->ov_lb_scale = pScaling->lb_scale;
}
Пример #3
0
void FDK_QmfDomain_QmfData2HBE(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
                               FIXP_DBL **ppQmfReal, FIXP_DBL **ppQmfImag) {
  FDK_ASSERT(qd_ch != NULL);
  FDK_ASSERT(ppQmfReal != NULL);
  FDK_ASSERT(ppQmfImag != NULL);
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
  USHORT workBufferOffset = qd_ch->workBufferOffset;
  USHORT workBufferSectSize = qd_ch->workBufferSectSize;

  if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
                        qd_ch->workBuf_nBands) ==
      qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) {  // left channel (anaMatrix)
    int ts;
    const int bands = gc->nBandsAnalysis;
    const int slots = qd_ch->workBuf_nTimeSlots;
    FDK_ASSERT(bands <= 64);
    for (ts = 0; ts < slots; ts++) {
      /* copy current data of processing channel */
      FIXP_DBL tmp[64];  // one slot
      /* real */
      FDKmemcpy(tmp, qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
                sizeof(FIXP_DBL) * bands);  // anaMatrix_to_tmp
      FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
                sizeof(FIXP_DBL) * bands);  // HBE_to_anaMatrix
      FDKmemcpy(ppQmfReal[ts], tmp, sizeof(FIXP_DBL) * bands);  // tmp_to_HBE
      /* imag */
      FDKmemcpy(tmp, qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
                sizeof(FIXP_DBL) * bands);
      FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
                sizeof(FIXP_DBL) * bands);
      FDKmemcpy(ppQmfImag[ts], tmp, sizeof(FIXP_DBL) * bands);
    }
  } else {  // right channel (parkBuf)
    const int bands = qd_ch->workBuf_nBands;
    const int slots = qd_ch->workBuf_nTimeSlots;
    int ts;
    FDK_ASSERT(qd_ch->workBuf_nBands == gc->nBandsAnalysis);
    for (ts = 0; ts < slots; ts++) {
      /* copy HBE QMF data buffer to processing channel */
      FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
                sizeof(FIXP_DBL) * bands);  // HBE_to_anaMatrix
      FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
                sizeof(FIXP_DBL) * bands);
      /* copy parked new QMF data to HBE QMF data buffer */
      FDKmemcpy(ppQmfReal[ts],
                FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
                                  workBufferSectSize, bands),
                sizeof(FIXP_DBL) * bands);  // parkBuf_to_HBE
      workBufferOffset += bands;
      FDKmemcpy(ppQmfImag[ts],
                FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
                                  workBufferSectSize, bands),
                sizeof(FIXP_DBL) * bands);
      workBufferOffset += bands;
    }
  }
}
Пример #4
0
INT imdct_copy_ov_and_nr(
        H_MDCT hMdct,
        FIXP_DBL * pTimeData,
        INT nrSamples
        )
{
  FIXP_DBL *pOvl;
  int nt, nf, i;

  nt = fMin(hMdct->ov_offset, nrSamples);
  nrSamples -= nt;
  nf = fMin(hMdct->prev_nr, nrSamples);
  nrSamples -= nf;
  FDKmemcpy(pTimeData, hMdct->overlap.time, nt*sizeof(FIXP_DBL));
  pTimeData += nt;

  pOvl = hMdct->overlap.freq + hMdct->ov_size - 1;
  for (i=0; i<nf; i++) {
    FIXP_DBL x = - (*pOvl--);
    *pTimeData = IMDCT_SCALE_DBL(x);
    pTimeData ++;
  }

  return (nt+nf);
}
Пример #5
0
static void copySbrHeader( HANDLE_SBR_HEADER_DATA hDst, const HANDLE_SBR_HEADER_DATA hSrc )
{
  /* copy the whole header memory (including pointers) */
  FDKmemcpy( hDst, hSrc, sizeof(SBR_HEADER_DATA) );

  /* update pointers */
  hDst->freqBandData.freqBandTable[0]  = hDst->freqBandData.freqBandTableLo;
  hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi;
}
Пример #6
0
/*!
  \brief    Convert raw envelope and noisefloor data to energy levels

  This function is being called by sbrDecoder_ParseElement() and provides two important algorithms:

  First the function decodes envelopes and noise floor levels as described in requantizeEnvelopeData()
  and sbr_envelope_unmapping(). The function also implements concealment algorithms in case there are errors
  within the sbr data. For both operations fractional arithmetic is used.
  Therefore you might encounter different output values on your target
  system compared to the reference implementation.
*/
void
decodeSbrData (HANDLE_SBR_HEADER_DATA hHeaderData,          /*!< Static control data */
               HANDLE_SBR_FRAME_DATA h_data_left,           /*!< pointer to left channel frame data */
               HANDLE_SBR_PREV_FRAME_DATA h_prev_data_left, /*!< pointer to left channel previous frame data */
               HANDLE_SBR_FRAME_DATA h_data_right,          /*!< pointer to right channel frame data */
               HANDLE_SBR_PREV_FRAME_DATA h_prev_data_right)/*!< pointer to right channel previous frame data */
{
  FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];
  int errLeft;

  /* Save previous energy values to be able to reuse them later for concealment. */
  FDKmemcpy (tempSfbNrgPrev, h_prev_data_left->sfb_nrg_prev, MAX_FREQ_COEFFS * sizeof(FIXP_SGL));

  decodeEnvelope (hHeaderData, h_data_left, h_prev_data_left, h_prev_data_right);
  decodeNoiseFloorlevels (hHeaderData, h_data_left, h_prev_data_left);

  if(h_data_right != NULL) {
    errLeft = hHeaderData->frameErrorFlag;
    decodeEnvelope (hHeaderData, h_data_right, h_prev_data_right, h_prev_data_left);
    decodeNoiseFloorlevels (hHeaderData, h_data_right, h_prev_data_right);

    if (!errLeft && hHeaderData->frameErrorFlag) {
      /* If an error occurs in the right channel where the left channel seemed ok,
         we apply concealment also on the left channel. This ensures that the coupling
         modes of both channels match and that we have the same number of envelopes in
         coupling mode.
         However, as the left channel has already been processed before, the resulting
         energy levels are not the same as if the left channel had been concealed
         during the first call of decodeEnvelope().
      */
      /* Restore previous energy values for concealment, because the values have been
         overwritten by the first call of decodeEnvelope(). */
      FDKmemcpy (h_prev_data_left->sfb_nrg_prev, tempSfbNrgPrev, MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
      /* Do concealment */
      decodeEnvelope (hHeaderData, h_data_left, h_prev_data_left, h_prev_data_right);
    }

    if (h_data_left->coupling) {
      sbr_envelope_unmapping (hHeaderData, h_data_left, h_data_right);
    }
  }

  /* Display the data for debugging: */
}
INT
FDKsbrEnc_resetInvFiltDetector(HANDLE_SBR_INV_FILT_EST hInvFilt, /*!< Handle to the SBR_INV_FILT_EST struct. */
                     INT* freqBandTableDetector,       /*!< Frequency band table for the inverse filtering. */
                     INT numDetectorBands)             /*!< Number of inverse filtering bands. */
{

  hInvFilt->numberOfStrongest     = 1;
  FDKmemcpy(hInvFilt->freqBandTableInvFilt,freqBandTableDetector,(numDetectorBands+1)*sizeof(INT));
  hInvFilt->noDetectorBands = numDetectorBands;

  return (0);
}
Пример #8
0
INT imdct_drain(
        H_MDCT hMdct,
        FIXP_DBL *output,
        INT nrSamplesRoom
        )
{
  int buffered_samples = 0;

  if (nrSamplesRoom > 0) {
    buffered_samples = hMdct->ov_offset;

    FDK_ASSERT(buffered_samples <= nrSamplesRoom);

    if (buffered_samples > 0)  {
      FDKmemcpy(output, hMdct->overlap.time, buffered_samples*sizeof(FIXP_DBL));
      hMdct->ov_offset = 0;
    }
  }
  return buffered_samples;
}
Пример #9
0
TRANSPORTDEC_ERROR adtsRead_DecodeHeader(
        HANDLE_ADTS           pAdts,
        CSAudioSpecificConfig *pAsc,
        HANDLE_FDK_BITSTREAM  hBs,
        const INT             ignoreBufferFullness
        )
{
  INT crcReg;

  INT valBits;
  INT cmp_buffer_fullness;
  int i, adtsHeaderLength;

  STRUCT_ADTS_BS bs;

#ifdef TP_PCE_ENABLE
  CProgramConfig oldPce;
  /* Store the old PCE temporarily. Maybe we'll need it later if we
     have channelConfig=0 and no PCE in this frame. */
  FDKmemcpy(&oldPce, &pAsc->m_progrConfigElement, sizeof(CProgramConfig));
#endif

  valBits = FDKgetValidBits(hBs);

#ifndef ANDROID_DEFAULT_CODE
  if (valBits <= ADTS_HEADERLENGTH) return TRANSPORTDEC_NOT_ENOUGH_BITS;
#endif

  /* adts_fixed_header */
  bs.mpeg_id           = FDKreadBits(hBs, Adts_Length_Id);
  bs.layer             = FDKreadBits(hBs, Adts_Length_Layer);
  bs.protection_absent = FDKreadBits(hBs, Adts_Length_ProtectionAbsent);
  bs.profile           = FDKreadBits(hBs, Adts_Length_Profile);
  bs.sample_freq_index = FDKreadBits(hBs, Adts_Length_SamplingFrequencyIndex);
  bs.private_bit       = FDKreadBits(hBs, Adts_Length_PrivateBit);
  bs.channel_config    = FDKreadBits(hBs, Adts_Length_ChannelConfiguration);
  bs.original          = FDKreadBits(hBs, Adts_Length_OriginalCopy);
  bs.home              = FDKreadBits(hBs, Adts_Length_Home);

  /* adts_variable_header */
  bs.copyright_id    = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationBit);
  bs.copyright_start = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationStart);
  bs.frame_length    = FDKreadBits(hBs, Adts_Length_FrameLength);
  bs.adts_fullness   = FDKreadBits(hBs, Adts_Length_BufferFullness);
  bs.num_raw_blocks  = FDKreadBits(hBs, Adts_Length_NumberOfRawDataBlocksInFrame);
  bs.num_pce_bits    = 0;

  adtsHeaderLength = ADTS_HEADERLENGTH;

  if (!bs.protection_absent) {
    FDKcrcReset(&pAdts->crcInfo);
    FDKpushBack(hBs, 56);   /* complete fixed and variable header! */
    crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0);
    FDKpushFor(hBs, 56);
  }

  if (! bs.protection_absent && bs.num_raw_blocks>0) {
    for (i=0; i<bs.num_raw_blocks; i++) {
      pAdts->rawDataBlockDist[i] = (USHORT)FDKreadBits(hBs, 16);
      adtsHeaderLength += 16;
    }
    /* Change raw data blocks to delta values */
    pAdts->rawDataBlockDist[bs.num_raw_blocks] = bs.frame_length - 7 - bs.num_raw_blocks*2 - 2 ;
    for (i=bs.num_raw_blocks; i>0; i--) {
      pAdts->rawDataBlockDist[i] -= pAdts->rawDataBlockDist[i-1];
    }
  }

  /* adts_error_check */
  if (!bs.protection_absent)
  {
    USHORT crc_check;

    FDKcrcEndReg(&pAdts->crcInfo, hBs, crcReg);
    crc_check = FDKreadBits(hBs, Adts_Length_CrcCheck);
    adtsHeaderLength += Adts_Length_CrcCheck;

    pAdts->crcReadValue = crc_check;
    /* Check header CRC in case of multiple raw data blocks */
    if (bs.num_raw_blocks > 0) {
      if (pAdts->crcReadValue != FDKcrcGetCRC(&pAdts->crcInfo)) {
        return TRANSPORTDEC_CRC_ERROR;
      }
      /* Reset CRC for the upcoming raw_data_block() */
      FDKcrcReset(&pAdts->crcInfo);
    }
  }


  /* check if valid header */
  if (
      (bs.layer != 0) ||                          // we only support MPEG ADTS
      (bs.sample_freq_index >= 13)                // we only support 96kHz - 7350kHz
      ) {
    FDKpushFor(hBs, bs.frame_length * 8);   // try again one frame later
    return TRANSPORTDEC_UNSUPPORTED_FORMAT;
  }

  /* special treatment of id-bit */
  if ( (bs.mpeg_id == 0) && (pAdts->decoderCanDoMpeg4 == 0) )
  {
    /* MPEG-2 decoder cannot play MPEG-4 bitstreams */


    FDKpushFor(hBs, bs.frame_length * 8);  // try again one frame later
    return TRANSPORTDEC_UNSUPPORTED_FORMAT;
  }

  if (!ignoreBufferFullness)
  {
    cmp_buffer_fullness = bs.frame_length*8 + bs.adts_fullness*32*getNumberOfEffectiveChannels(bs.channel_config);


    /* Evaluate buffer fullness */
    if (bs.adts_fullness != 0x7FF)
    {
      if (pAdts->BufferFullnesStartFlag)
      {
        if ( valBits < cmp_buffer_fullness )
        {
          /* Condition for start of decoding is not fulfilled */

          /* The current frame will not be decoded */
          FDKpushBack(hBs, adtsHeaderLength);

          if ( (cmp_buffer_fullness+adtsHeaderLength) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
            return TRANSPORTDEC_SYNC_ERROR;
          } else {
            return TRANSPORTDEC_NOT_ENOUGH_BITS;
          }
        }
        else
        {
          pAdts->BufferFullnesStartFlag = 0;
        }
      }
    }
  }


  /* Get info from ADTS header */
  AudioSpecificConfig_Init(pAsc);
  pAsc->m_aot                    = (AUDIO_OBJECT_TYPE)(bs.profile + 1);
  pAsc->m_samplingFrequencyIndex = bs.sample_freq_index;
  pAsc->m_samplingFrequency      = SamplingRateTable[bs.sample_freq_index];
  pAsc->m_channelConfiguration   = bs.channel_config;
  pAsc->m_samplesPerFrame        = 1024;

#ifdef TP_PCE_ENABLE
  if (bs.channel_config == 0)
  {
    int pceBits = 0;
    UINT alignAnchor = FDKgetValidBits(hBs);
    
    if (FDKreadBits(hBs,3) == ID_PCE) {
      /* Got luck! Parse the PCE */
      int crcReg;
      crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0);

      CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor);

      adtsRead_CrcEndReg(pAdts, hBs, crcReg);
      pceBits = alignAnchor - FDKgetValidBits(hBs);
      /* store the number of PCE bits */
      bs.num_pce_bits = pceBits;
    }
    else {
      /* No PCE in this frame! Push back the ID tag bits. */
      FDKpushBack(hBs,3);

      /* Encoders do not have to write a PCE in each frame.
         So if we already have a valid PCE we have to use it. */
      if (  oldPce.isValid
        && (bs.sample_freq_index == pAdts->bs.sample_freq_index)  /* we could compare the complete fixed header (bytes) here! */
        && (bs.channel_config    == pAdts->bs.channel_config) /* == 0 */
        && (bs.mpeg_id           == pAdts->bs.mpeg_id) )
      { /* Restore previous PCE which is still valid */
        FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, sizeof(CProgramConfig));
      }
      else if (bs.mpeg_id == 0) {
        /* If not it seems that we have a implicit channel configuration.
           This mode is not allowed in the context of ISO/IEC 14496-3.
           Skip this frame and try the next one. */
        FDKpushFor(hBs, (bs.frame_length<<3) - adtsHeaderLength - 3);
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;
      }
      /* else {
         ISO/IEC 13818-7 implicit channel mapping is allowed.
         So just open the box of chocolates to see what we got.
      } */
    }
  }
#endif /* TP_PCE_ENABLE */

  /* Copy bit stream data struct to persistent memory now, once we passed all sanity checks above. */
  FDKmemcpy(&pAdts->bs, &bs, sizeof(STRUCT_ADTS_BS));

  return TRANSPORTDEC_OK;
}
Пример #10
0
static
TRANSPORTDEC_ERROR synchronization(
        HANDLE_TRANSPORTDEC hTp,
        INT                *pHeaderBits
        )
{
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];

  INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
  INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
  INT totalBits;
  INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
  INT numFramesTraversed = 0, fTraverseMoreFrames, fConfigFound = 0, startPos, startPosFirstFrame = -1;
  INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious, globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
  INT ignoreBufferFullness = hTp->flags & (TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK);

  /* Synch parameters */
  INT syncLength;      /* Length of sync word in bits */
  UINT syncWord;       /* Sync word to be found */
  UINT syncMask;       /* Mask for sync word (for adding one bit, so comprising one bit less) */
  C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);

  totalBits = (INT)FDKgetValidBits(hBs);

  if (totalBits <= 0) {
    /* Return sync error, because this happens only in case of severly damaged bit streams.
       Returning TRANSPORTDEC_NOT_ENOUGH_BITS here is very dangerous. */
    /* numberOfRawDataBlocks must be always reset in case of sync errors. */
    hTp->numberOfRawDataBlocks = 0;
    goto bail;
  }

  fTraverseMoreFrames = (hTp->flags & (TPDEC_MINIMIZE_DELAY|TPDEC_EARLY_CONFIG)) && ! (hTp->flags & TPDEC_SYNCOK);

  /* Set transport specific sync parameters */
  switch (hTp->transportFmt) {
    case TT_MP4_ADTS:
      syncWord = ADTS_SYNCWORD;
      syncLength = ADTS_SYNCLENGTH;
      break;
    case TT_MP4_LOAS:
      syncWord = 0x2B7;
      syncLength = 11;
      break;
    default:
      syncWord = 0;
      syncLength = 0;
      break;
  }

  syncMask = (1<<syncLength)-1;

  do {
    INT bitsAvail = 0;     /* Bits available in bitstream buffer    */
    INT checkLengthBits;   /* Helper to check remaining bits and buffer boundaries */
    UINT synch;            /* Current sync word read from bitstream */

    headerBitsPrevious = headerBits;

    bitsAvail = (INT)FDKgetValidBits(hBs);

    if (hTp->numberOfRawDataBlocks == 0) {
      /* search synchword */

      FDK_ASSERT( (bitsAvail % TPDEC_SYNCSKIP) == 0);

      if ((bitsAvail-syncLength) < TPDEC_SYNCSKIP) {
        err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        headerBits = 0;
      } else {

        synch = FDKreadBits(hBs, syncLength);

        if ( !(hTp->flags & TPDEC_SYNCOK) ) {
          for (; (bitsAvail-syncLength) >= TPDEC_SYNCSKIP; bitsAvail-=TPDEC_SYNCSKIP) {
            if (synch == syncWord) {
              break;
            }
            synch = ((synch << TPDEC_SYNCSKIP) & syncMask) | FDKreadBits(hBs, TPDEC_SYNCSKIP);
          }
        }
        if (synch != syncWord) {
          /* No correct syncword found. */
          err = TRANSPORTDEC_SYNC_ERROR;
        } else {
          err = TRANSPORTDEC_OK;
        }
        headerBits = syncLength;
      }
    } else {
      headerBits = 0;
    }

    /* Save previous raw data block data */
    rawDataBlockLengthPrevious = rawDataBlockLength;
    numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;

    /* Parse transport header (raw data block granularity) */
    startPos = FDKgetValidBits(hBs);

    if (err == TRANSPORTDEC_OK )
    {
      switch (hTp->transportFmt) {
        case TT_MP4_ADTS:
          if (hTp->numberOfRawDataBlocks <= 0)
          {
            int errC;

            /* Parse ADTS header */
            err = adtsRead_DecodeHeader( &hTp->parser.adts, &hTp->asc[0], hBs, ignoreBufferFullness );
            if (err != TRANSPORTDEC_OK) {
              if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
                err = TRANSPORTDEC_SYNC_ERROR;
              }
            } else {
              errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
              if (errC != 0) {
                err = TRANSPORTDEC_SYNC_ERROR;
              } else {
                hTp->numberOfRawDataBlocks = hTp->parser.adts.bs.num_raw_blocks+1;
                /* CAUTION: The PCE (if available) is declared to be a part of the header! */
                hTp->globalFramePos = FDKgetValidBits(hBs) + hTp->parser.adts.bs.num_pce_bits;
              }
            }
          }
          else {
            /* Reset CRC because the next bits are the beginning of a raw_data_block() */
            FDKcrcReset(&hTp->parser.adts.crcInfo);
            hTp->globalFramePos = FDKgetValidBits(hBs);
          }
          if (err == TRANSPORTDEC_OK) {
            hTp->numberOfRawDataBlocks--;
            rawDataBlockLength = adtsRead_GetRawDataBlockLength(&hTp->parser.adts, (hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks));
            syncLayerFrameBits = (hTp->parser.adts.bs.frame_length<<3) - (startPos - FDKgetValidBits(hBs)) - syncLength;
            if (syncLayerFrameBits <= 0) {
              err = TRANSPORTDEC_SYNC_ERROR;
            }
          } else {
            hTp->numberOfRawDataBlocks = 0;
          }
          break;
        case TT_MP4_LOAS:
          if (hTp->numberOfRawDataBlocks <= 0)
          {
            syncLayerFrameBits = FDKreadBits(hBs, 13);
            hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
            syncLayerFrameBits <<= 3;
          }
        case TT_MP4_LATM_MCP1:
        case TT_MP4_LATM_MCP0:
          if (hTp->numberOfRawDataBlocks <= 0)
          {
            hTp->globalFramePos = FDKgetValidBits(hBs);

            err = CLatmDemux_Read(
                    hBs,
                   &hTp->parser.latm,
                    hTp->transportFmt,
                   &hTp->callbacks,
                    hTp->asc,
                    ignoreBufferFullness);

            if (err != TRANSPORTDEC_OK) {
              if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
                err = TRANSPORTDEC_SYNC_ERROR;
              }
            } else {
              hTp->numberOfRawDataBlocks = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
              syncLayerFrameBits -= startPos - FDKgetValidBits(hBs) - (13);            
            }
          } else {
            err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
            if (err != TRANSPORTDEC_OK) {
              err = TRANSPORTDEC_SYNC_ERROR;
            }
          }
          if (err == TRANSPORTDEC_OK) {
            rawDataBlockLength = CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm);
            hTp->numberOfRawDataBlocks--;
          } else {
            hTp->numberOfRawDataBlocks = 0;
          }
          break;
        default:
          {
            syncLayerFrameBits = 0;
          }
          break;
      }
    }

    headerBits += startPos - (INT)FDKgetValidBits(hBs);
    bitsAvail -= headerBits;

    checkLengthBits  = syncLayerFrameBits;

    /* Check if the whole frame would fit the bitstream buffer */
    if (err == TRANSPORTDEC_OK) {
      if ( (checkLengthBits+headerBits) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
        /* We assume that the size of the transport bit buffer has been
           chosen to meet all system requirements, thus this condition
           is considered a synchronisation error. */
        err = TRANSPORTDEC_SYNC_ERROR;
      } else {
        if ( bitsAvail < checkLengthBits ) {
          err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        }
      }
    }

    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      break;
    }


    if (err == TRANSPORTDEC_SYNC_ERROR) {
      int bits;

      /* Enforce re-sync of transport headers. */
      hTp->numberOfRawDataBlocks = 0;

      /* Ensure that the bit amount lands and a multiple of TPDEC_SYNCSKIP */
      bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
      /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead next time. */
      FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
      bitsAvail += headerBits - TPDEC_SYNCSKIP - bits;
      headerBits = 0;      
    }

    /* Frame traversal */
    if ( fTraverseMoreFrames )
    {
      /* Save parser context for early config discovery "rewind all frames" */
      if ( (hTp->flags & TPDEC_EARLY_CONFIG) && !(hTp->flags & TPDEC_MINIMIZE_DELAY))
      {
        /* ignore buffer fullness if just traversing additional frames for ECD */
        ignoreBufferFullness = 1;

        /* Save context in order to return later */
        if ( err == TRANSPORTDEC_OK && startPosFirstFrame == -1 ) {
          startPosFirstFrame = FDKgetValidBits(hBs);
          numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
          globalFramePosFirstFrame = hTp->globalFramePos;
          rawDataBlockLengthFirstFrame = rawDataBlockLength;
          headerBitsFirstFrame = headerBits;
          errFirstFrame = err;
          FDKmemcpy(contextFirstFrame, &hTp->parser, sizeof(transportdec_parser_t));
        }

        /* Break when config was found or it is not possible anymore to find a config */
        if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
          break;
        }
      }

      if (err == TRANSPORTDEC_OK) {
        FDKpushFor(hBs, rawDataBlockLength);
        bitsAvail -= rawDataBlockLength;
        numFramesTraversed++;
        /* Ignore error here itentionally. */
        transportDec_AdjustEndOfAccessUnit(hTp);
      }
    }
  } while ( fTraverseMoreFrames || (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));

  /* Restore context in case of ECD frame traversal */
  if ( startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK) ) {
    FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
    FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
    hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
    hTp->globalFramePos = globalFramePosFirstFrame;
    rawDataBlockLength = rawDataBlockLengthFirstFrame;
    headerBits = headerBitsFirstFrame;
    err = errFirstFrame;
    numFramesTraversed = 0;
  } 

  /* Additional burst data mode buffer fullness check. */
  if ( !(hTp->flags & (TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK)) && err == TRANSPORTDEC_OK) {
    err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), FDKgetValidBits(hBs) - syncLayerFrameBits);
    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      hTp->holdOffFrames++;
    }
  }
  
  /* Rewind for retry because of not enough bits */
  if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
    FDKpushBack(hBs, headerBits);
    headerBits = 0;
  }
  else {
    /* reset hold off frame counter */
    hTp->holdOffFrames = 0;
  }

  /* Return to last good frame in case of frame traversal but not ECD. */
  if (numFramesTraversed > 0) {
    FDKpushBack(hBs, rawDataBlockLengthPrevious);
    if (err != TRANSPORTDEC_OK) {
      hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
      headerBits = headerBitsPrevious;
    }
    err = TRANSPORTDEC_OK;
  }

bail:
  hTp->auLength[0] = rawDataBlockLength;

  if (err == TRANSPORTDEC_OK) {
    hTp->flags |= TPDEC_SYNCOK;
  }

  if (pHeaderBits != NULL) {
    *pHeaderBits = headerBits;
  }

  if (err == TRANSPORTDEC_SYNC_ERROR) {
    hTp->flags &= ~TPDEC_SYNCOK;
  }

  C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);

  return err;
}
Пример #11
0
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()
Пример #12
0
/*****************************************************************************

    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;

}
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);
}
Пример #14
0
TRANSPORTENC_ERROR transportEnc_Init(
        HANDLE_TRANSPORTENC hTpEnc,
        UCHAR             *bsBuffer,
        INT                bsBufferSize,
        TRANSPORT_TYPE     transportFmt,
        CODER_CONFIG      *cconfig,
        UINT               flags
        )
{
  /* Copy configuration structure */
  FDKmemcpy(&hTpEnc->config, cconfig, sizeof(CODER_CONFIG));

  /* Init transportEnc struct. */
  hTpEnc->transportFmt = transportFmt;

  hTpEnc->bsBuffer = bsBuffer;
  hTpEnc->bsBufferSize = bsBufferSize;

  FDKinitBitStream(&hTpEnc->bitStream, hTpEnc->bsBuffer, hTpEnc->bsBufferSize, 0, BS_WRITER);

  switch (transportFmt) {

  case TT_MP4_ADIF:
    /* Sanity checks */
    if ( (hTpEnc->config.aot != AOT_AAC_LC)
       ||(hTpEnc->config.samplesPerFrame != 1024))
    {
      return TRANSPORTENC_INVALID_PARAMETER;
    }
    hTpEnc->writer.adif.headerWritten = 0;
    hTpEnc->writer.adif.samplingRate = hTpEnc->config.samplingRate;
    hTpEnc->writer.adif.bitRate = hTpEnc->config.bitRate;
    hTpEnc->writer.adif.profile = ((int)hTpEnc->config.aot) - 1;
    hTpEnc->writer.adif.cm = hTpEnc->config.channelMode;
    hTpEnc->writer.adif.bVariableRate = 0;
    hTpEnc->writer.adif.instanceTag = 0;
    break;

  case TT_MP4_ADTS:
    /* Sanity checks */
    if ( ( hTpEnc->config.aot != AOT_AAC_LC)
       ||(hTpEnc->config.samplesPerFrame != 1024) )
    {
      return TRANSPORTENC_INVALID_PARAMETER;
    }
    if ( adtsWrite_Init(&hTpEnc->writer.adts, &hTpEnc->config) != 0) {
      return TRANSPORTENC_INVALID_PARAMETER;
    }
    break;

  case TT_DABPLUS:
    /* Sanity checks */
    if ( ( hTpEnc->config.aot != AOT_AAC_LC)
       ||(hTpEnc->config.samplesPerFrame != 960) )
    {
      return TRANSPORTENC_INVALID_PARAMETER;
    }
    if ( dabWrite_Init(&hTpEnc->writer.dab, &hTpEnc->config) != 0) {
      return TRANSPORTENC_INVALID_PARAMETER;
    }
    break;

  case TT_MP4_LOAS:
  case TT_MP4_LATM_MCP0:
  case TT_MP4_LATM_MCP1:
    {
      TRANSPORTENC_ERROR error;

      error = transportEnc_Latm_Init(
                &hTpEnc->writer.latm,
                &hTpEnc->bitStream,
                &hTpEnc->config,
                 flags & TP_FLAG_LATM_AMV,
                 transportFmt,
                &hTpEnc->callbacks
                 );
      if (error != TRANSPORTENC_OK) {
        return error;
      }
    }
    break;

  case TT_MP4_RAW:
    hTpEnc->writer.raw.curSubFrame = 0;
    hTpEnc->writer.raw.nSubFrames = hTpEnc->config.nSubFrames;
    break;



  default:
    return TRANSPORTENC_INVALID_PARAMETER;
  }

  /* pceFrameCounter indicates if PCE must be written in raw_data_block. */
  hTpEnc->pceFrameCounter = getPceRepetitionRate(
                    getChannelConfig(hTpEnc->config.channelMode),
                    transportFmt,
                    hTpEnc->config.headerPeriod,
                    hTpEnc->config.matrixMixdownA);

  return TRANSPORTENC_OK;
}
Пример #15
0
/**
 * \brief Render one SBR element into time domain signal.
 * \param self SBR decoder handle
 * \param timeData pointer to output buffer
 * \param interleaved flag indicating interleaved channel output
 * \param channelMapping pointer to UCHAR array where next 2 channel offsets are stored. 
 * \param elementIndex enumerating index of the SBR element to render.
 * \param numInChannels number of channels from core coder (reading stride).
 * \param numOutChannels pointer to a location to return number of output channels.
 * \param psPossible flag indicating if PS is possible or not.
 * \return SBRDEC_OK if successfull, else error code
 */
static SBR_ERROR
sbrDecoder_DecodeElement (
        HANDLE_SBRDECODER    self,
        INT_PCM             *timeData,
        const int            interleaved,
        const UCHAR         *channelMapping,
        const int            elementIndex,
        const int            numInChannels,
        int                 *numOutChannels,
        const int            psPossible
        )
{
  SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex];
  HANDLE_SBR_CHANNEL    *pSbrChannel = self->pSbrElement[elementIndex]->pSbrChannel;
  HANDLE_SBR_HEADER_DATA hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]];
  HANDLE_PS_DEC h_ps_d = self->hParametricStereoDec;

  /* get memory for frame data from scratch */
  SBR_FRAME_DATA *hFrameDataLeft  = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
  SBR_FRAME_DATA *hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];

  SBR_ERROR errorStatus = SBRDEC_OK;


  INT  strideIn, strideOut, offset0, offset1;
  INT  codecFrameSize = self->codecFrameSize;

  int  stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;
  int  numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */

  if (self->flags & SBRDEC_FLUSH) {
    /* Move frame pointer to the next slot which is up to be decoded/applied next */
    hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1);
    /* Update header and frame data pointer because they have already been set */
    hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]];
    hFrameDataLeft  = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
    hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
  }

  /* Update the header error flag */
  hSbrHeader->frameErrorFlag = hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot];

  /*
     Prepare filterbank for upsampling if no valid bit stream data is available.
   */
  if ( hSbrHeader->syncState == SBR_NOT_INITIALIZED )
  {
    errorStatus = initHeaderData(
            hSbrHeader,
            self->sampleRateIn,
            self->sampleRateOut,
            codecFrameSize,
            self->flags
            );

    if (errorStatus != SBRDEC_OK) {
      return errorStatus;
    }

    hSbrHeader->syncState = UPSAMPLING;

    errorStatus = sbrDecoder_HeaderUpdate(
            self,
            hSbrHeader,
            HEADER_NOT_PRESENT,
            pSbrChannel,
            hSbrElement->nChannels
            );

    if (errorStatus != SBRDEC_OK) {
      hSbrHeader->syncState = SBR_NOT_INITIALIZED;
      return errorStatus;
    }
  }

  /* reset */
  if (hSbrHeader->status & SBRDEC_HDR_STAT_RESET) {
    int ch;
    for (ch = 0 ; ch < numElementChannels; ch++) {
      SBR_ERROR errorStatusTmp = SBRDEC_OK;

      errorStatusTmp = resetSbrDec (
             &pSbrChannel[ch]->SbrDec,
              hSbrHeader,
             &pSbrChannel[ch]->prevFrameData,
              self->flags & SBRDEC_LOW_POWER,
              self->synDownsampleFac
              );

      if (errorStatusTmp != SBRDEC_OK) {
        errorStatus = errorStatusTmp;
      }
    }
    hSbrHeader->status &= ~SBRDEC_HDR_STAT_RESET;
  }

  /* decoding */
  if ( (hSbrHeader->syncState == SBR_ACTIVE)
    || ((hSbrHeader->syncState == SBR_HEADER) && (hSbrHeader->frameErrorFlag == 0)) )
  {
    errorStatus = SBRDEC_OK;

    decodeSbrData (hSbrHeader,
                   hFrameDataLeft,
                  &pSbrChannel[0]->prevFrameData,
                   (stereo) ? hFrameDataRight : NULL,
                   (stereo) ? &pSbrChannel[1]->prevFrameData : NULL);


    /* Now we have a full parameter set and can do parameter
       based concealment instead of plain upsampling. */
    hSbrHeader->syncState = SBR_ACTIVE;
  }

  /* decode PS data if available */
  if (h_ps_d != NULL && psPossible) {
    int applyPs = 1;

    /* define which frame delay line slot to process */
    h_ps_d->processSlot = hSbrElement->useFrameSlot;

    applyPs = DecodePs(h_ps_d, hSbrHeader->frameErrorFlag);
    self->flags |= (applyPs) ? SBRDEC_PS_DECODED : 0;
  }

  /* Set strides for reading and writing */
  if (interleaved) {
    strideIn = numInChannels;
    if ( psPossible )
      strideOut = (numInChannels < 2) ? 2 : numInChannels;
    else
      strideOut = numInChannels;
    offset0 = channelMapping[0];
    offset1 = channelMapping[1];
  } else {
    strideIn  = 1;
    strideOut = 1;
    offset0 = channelMapping[0]*2*codecFrameSize;
    offset1 = channelMapping[1]*2*codecFrameSize;
  }

  /* use same buffers for left and right channel and apply PS per timeslot */
  /* Process left channel */
//FDKprintf("self->codecFrameSize %d\t%d\n",self->codecFrameSize,self->sampleRateIn);
  sbr_dec (&pSbrChannel[0]->SbrDec,
            timeData + offset0,
            timeData + offset0,
           &pSbrChannel[1]->SbrDec,
            timeData + offset1,
            strideIn,
            strideOut,
            hSbrHeader,
            hFrameDataLeft,
           &pSbrChannel[0]->prevFrameData,
            (hSbrHeader->syncState == SBR_ACTIVE),
            h_ps_d,
            self->flags
          );

  if (stereo) {
    /* Process right channel */
    sbr_dec (&pSbrChannel[1]->SbrDec,
              timeData + offset1,
              timeData + offset1,
              NULL,
              NULL,
              strideIn,
              strideOut,
              hSbrHeader,
              hFrameDataRight,
             &pSbrChannel[1]->prevFrameData,
              (hSbrHeader->syncState == SBR_ACTIVE),
              NULL,
              self->flags
            );
  }

  if (h_ps_d != NULL) {
    /* save PS status for next run */
    h_ps_d->psDecodedPrv = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0 ;
  }

  if ( psPossible 
    )
  {
    FDK_ASSERT(strideOut > 1);
    if ( !(self->flags & SBRDEC_PS_DECODED) ) {
      /* A decoder which is able to decode PS has to produce a stereo output even if no PS data is availble. */
      /* So copy left channel to right channel.                                                              */
      if (interleaved) {
        INT_PCM *ptr;
        INT i;
        FDK_ASSERT(strideOut == 2);

        ptr = timeData;
        for (i = codecFrameSize; i--; ) 
        {
          INT_PCM tmp; /* This temporal variable is required because some compilers can't do *ptr++ = *ptr++ correctly. */
          tmp = *ptr++; *ptr++ = tmp;
          tmp = *ptr++; *ptr++ = tmp;
        }
      } else {
        FDKmemcpy( timeData+2*codecFrameSize, timeData, 2*codecFrameSize*sizeof(INT_PCM) );
      }
    }
    *numOutChannels = 2;  /* Output minimum two channels when PS is enabled. */
  }

  return errorStatus;
}
Пример #16
0
static
TRANSPORTDEC_ERROR synchronization(
        HANDLE_TRANSPORTDEC hTp,
        INT                *pHeaderBits
        )
{
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];

  INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
  INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
  INT totalBits;
  INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
  INT numFramesTraversed = 0, fTraverseMoreFrames, fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
  INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious, globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
  INT ignoreBufferFullness = hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK);

  /* Synch parameters */
  INT syncLength;      /* Length of sync word in bits */
  UINT syncWord;       /* Sync word to be found */
  UINT syncMask;       /* Mask for sync word (for adding one bit, so comprising one bit less) */
  C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);

  totalBits = (INT)FDKgetValidBits(hBs);

  if (totalBits <= 0) {
    err = TRANSPORTDEC_NOT_ENOUGH_BITS;
    goto bail;
  }

  fTraverseMoreFrames = (hTp->flags & (TPDEC_MINIMIZE_DELAY|TPDEC_EARLY_CONFIG)) && ! (hTp->flags & TPDEC_SYNCOK);

  /* Set transport specific sync parameters */
  switch (hTp->transportFmt) {
    case TT_MP4_ADTS:
      syncWord = ADTS_SYNCWORD;
      syncLength = ADTS_SYNCLENGTH;
      break;
    case TT_MP4_LOAS:
      syncWord = 0x2B7;
      syncLength = 11;
      break;
    default:
      syncWord = 0;
      syncLength = 0;
      break;
  }

  syncMask = (1<<syncLength)-1;

  do {
    INT bitsAvail = 0;     /* Bits available in bitstream buffer    */
    INT checkLengthBits;   /* Helper to check remaining bits and buffer boundaries */
    UINT synch;            /* Current sync word read from bitstream */

    headerBitsPrevious = headerBits;

    bitsAvail = (INT)FDKgetValidBits(hBs);

    if (hTp->numberOfRawDataBlocks == 0) {
      /* search synchword */

      FDK_ASSERT( (bitsAvail % TPDEC_SYNCSKIP) == 0);

      if ((bitsAvail-syncLength) < TPDEC_SYNCSKIP) {
        err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        headerBits = 0;
      } else {

        synch = FDKreadBits(hBs, syncLength);

        if ( !(hTp->flags & TPDEC_SYNCOK) ) {
          for (; (bitsAvail-syncLength) >= TPDEC_SYNCSKIP; bitsAvail-=TPDEC_SYNCSKIP) {
            if (synch == syncWord) {
              break;
            }
            synch = ((synch << TPDEC_SYNCSKIP) & syncMask) | FDKreadBits(hBs, TPDEC_SYNCSKIP);
          }
        }
        if (synch != syncWord) {
          /* No correct syncword found. */
          err = TRANSPORTDEC_SYNC_ERROR;
        } else {
          err = TRANSPORTDEC_OK;
        }
        headerBits = syncLength;
      }
    } else {
      headerBits = 0;
    }

    /* Save previous raw data block data */
    rawDataBlockLengthPrevious = rawDataBlockLength;
    numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;

    /* Parse transport header (raw data block granularity) */

    if (err == TRANSPORTDEC_OK )
    {
      err = transportDec_readHeader(
              hTp,
              hBs,
              syncLength,
              ignoreBufferFullness,
             &rawDataBlockLength,
             &fTraverseMoreFrames,
             &syncLayerFrameBits,
             &fConfigFound,
             &headerBits
              );
    }

    bitsAvail -= headerBits;

    checkLengthBits  = syncLayerFrameBits;

    /* Check if the whole frame would fit the bitstream buffer */
    if (err == TRANSPORTDEC_OK) {
      if ( (checkLengthBits+headerBits) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
        /* We assume that the size of the transport bit buffer has been
           chosen to meet all system requirements, thus this condition
           is considered a synchronisation error. */
        err = TRANSPORTDEC_SYNC_ERROR;
      } else {
        if ( bitsAvail < checkLengthBits ) {
          err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        }
      }
    }

    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      break;
    }


    if (err == TRANSPORTDEC_SYNC_ERROR) {
      int bits;

      /* Enforce re-sync of transport headers. */
      hTp->numberOfRawDataBlocks = 0;

      /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
      bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
      /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead next time. */
      FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
      bitsAvail += headerBits - TPDEC_SYNCSKIP - bits;
      headerBits = 0;
    }

    /* Frame traversal */
    if ( fTraverseMoreFrames )
    {
      /* Save parser context for early config discovery "rewind all frames" */
      if ( (hTp->flags & TPDEC_EARLY_CONFIG) && !(hTp->flags & TPDEC_MINIMIZE_DELAY))
      {
        /* ignore buffer fullness if just traversing additional frames for ECD */
        ignoreBufferFullness = 1;

        /* Save context in order to return later */
        if ( err == TRANSPORTDEC_OK && startPosFirstFrame == -1 ) {
          startPosFirstFrame = FDKgetValidBits(hBs);
          numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
          globalFramePosFirstFrame = hTp->globalFramePos;
          rawDataBlockLengthFirstFrame = rawDataBlockLength;
          headerBitsFirstFrame = headerBits;
          errFirstFrame = err;
          FDKmemcpy(contextFirstFrame, &hTp->parser, sizeof(transportdec_parser_t));
        }

        /* Break when config was found or it is not possible anymore to find a config */
        if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK))
        {
          /* In case of ECD and sync error, do not rewind anywhere. */
          if (err == TRANSPORTDEC_SYNC_ERROR)
          {
            startPosFirstFrame = -1;
            fConfigFound = 0;
            numFramesTraversed = 0;
          }
          break;
        }
      }

      if (err == TRANSPORTDEC_OK) {
        FDKpushFor(hBs, rawDataBlockLength);
        bitsAvail -= rawDataBlockLength;
        numFramesTraversed++;
        /* Ignore error here itentionally. */
        transportDec_AdjustEndOfAccessUnit(hTp);
      }
    }
  } while ( fTraverseMoreFrames || (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));

  /* Restore context in case of ECD frame traversal */
  if ( startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK) ) {
    FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
    FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
    hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
    hTp->globalFramePos = globalFramePosFirstFrame;
    rawDataBlockLength = rawDataBlockLengthFirstFrame;
    headerBits = headerBitsFirstFrame;
    err = errFirstFrame;
    numFramesTraversed = 0;
  } 

  /* Additional burst data mode buffer fullness check. */
  if ( !(hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK)) && err == TRANSPORTDEC_OK) {
    err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), FDKgetValidBits(hBs) - syncLayerFrameBits);
    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      hTp->holdOffFrames++;
    }
  }
  
  /* Rewind for retry because of not enough bits */
  if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
    FDKpushBack(hBs, headerBits);
    headerBits = 0;
  }
  else {
    /* reset hold off frame counter */
    hTp->holdOffFrames = 0;
  }

  /* Return to last good frame in case of frame traversal but not ECD. */
  if (numFramesTraversed > 0) {
    FDKpushBack(hBs, rawDataBlockLengthPrevious);
    if (err != TRANSPORTDEC_OK) {
      hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
      headerBits = headerBitsPrevious;
    }
    err = TRANSPORTDEC_OK;
  }

bail:
  hTp->auLength[0] = rawDataBlockLength;

  /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, were the bit buffer is already full,
     or no new burst packet fits. Recover by advancing the bit buffer. */
  if ( (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&  (FDKgetValidBits(hBs) >= ((TRANSPORTDEC_INBUF_SIZE*8 - ((hTp->avgBitRate*hTp->burstPeriod)/1000)) - 7)) )
  {
    FDKpushFor(hBs, TPDEC_SYNCSKIP);
    err = TRANSPORTDEC_SYNC_ERROR;
  }

  if (err == TRANSPORTDEC_OK) {
    hTp->flags |= TPDEC_SYNCOK;
  }

  if (fConfigFound) {
    hTp->flags |= TPDEC_CONFIG_FOUND;
  }

  if (pHeaderBits != NULL) {
    *pHeaderBits = headerBits;
  }

  if (err == TRANSPORTDEC_SYNC_ERROR) {
    hTp->flags &= ~TPDEC_SYNCOK;
  }

  C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);

  return err;
}
Пример #17
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;
}
Пример #18
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;
}
Пример #19
0
/*!

  \brief  Reads parametric stereo data from bitstream

  \return

****************************************************************************/
unsigned int
ReadPsData (HANDLE_PS_DEC h_ps_d,          /*!< handle to struct PS_DEC */
            HANDLE_FDK_BITSTREAM hBitBuf,  /*!< handle to struct BIT_BUF */
            int nBitsLeft                  /*!< max number of bits available */
           )
{
  MPEG_PS_BS_DATA *pBsData;

  UCHAR     gr, env;
  SCHAR     dtFlag;
  INT       startbits;
  Huffman   CurrentTable;
  SCHAR     bEnableHeader;

  if (!h_ps_d)
    return 0;

  pBsData = &h_ps_d->bsData[h_ps_d->bsReadSlot].mpeg;

  if (h_ps_d->bsReadSlot != h_ps_d->bsLastSlot) {
    /* Copy last header data */
    FDKmemcpy(pBsData, &h_ps_d->bsData[h_ps_d->bsLastSlot].mpeg, sizeof(MPEG_PS_BS_DATA));
  }


  startbits = (INT) FDKgetValidBits(hBitBuf);

  bEnableHeader = (SCHAR) FDKreadBits (hBitBuf, 1);

  /* Read header */
  if (bEnableHeader) {
    pBsData->bPsHeaderValid = 1;
    pBsData->bEnableIid = (UCHAR) FDKreadBits (hBitBuf, 1);
    if (pBsData->bEnableIid) {
      pBsData->modeIid = (UCHAR) FDKreadBits (hBitBuf, 3);
    }

    pBsData->bEnableIcc = (UCHAR) FDKreadBits (hBitBuf, 1);
    if (pBsData->bEnableIcc) {
      pBsData->modeIcc = (UCHAR) FDKreadBits (hBitBuf, 3);
    }

    pBsData->bEnableExt = (UCHAR) FDKreadBits (hBitBuf, 1);
  }

  pBsData->bFrameClass = (UCHAR) FDKreadBits (hBitBuf, 1);
  if (pBsData->bFrameClass == 0) {
    /* FIX_BORDERS NoEnv=0,1,2,4 */
    pBsData->noEnv = FDK_sbrDecoder_aFixNoEnvDecode[(UCHAR) FDKreadBits (hBitBuf, 2)];
    /* all additional handling of env borders is now in DecodePs() */
  }
  else {
    /* VAR_BORDERS NoEnv=1,2,3,4 */
    pBsData->noEnv = 1+(UCHAR) FDKreadBits (hBitBuf, 2);
    for (env=1; env<pBsData->noEnv+1; env++)
      pBsData->aEnvStartStop[env] = ((UCHAR) FDKreadBits (hBitBuf, 5)) + 1;
    /* all additional handling of env borders is now in DecodePs() */
  }

  /* verify that IID & ICC modes (quant grid, freq res) are supported */
  if ((pBsData->modeIid > 5) || (pBsData->modeIcc > 5)) {
    /* no useful PS data could be read from bitstream */
    h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_none;
    /* discard all remaining bits */
    nBitsLeft -= startbits - FDKgetValidBits(hBitBuf);
    while (nBitsLeft) {
      int i = nBitsLeft;
      if (i>8) {
        i = 8;
      }
      FDKreadBits (hBitBuf, i);
      nBitsLeft -= i;
    }
    return (startbits - FDKgetValidBits(hBitBuf));
  }

  if (pBsData->modeIid > 2){
    pBsData->freqResIid = pBsData->modeIid-3;
    pBsData->bFineIidQ = 1;
  }
  else{
    pBsData->freqResIid = pBsData->modeIid;
    pBsData->bFineIidQ = 0;
  }

  if (pBsData->modeIcc > 2){
    pBsData->freqResIcc = pBsData->modeIcc-3;
  }
  else{
    pBsData->freqResIcc = pBsData->modeIcc;
  }


  /* Extract IID data */
  if (pBsData->bEnableIid) {
    for (env=0; env<pBsData->noEnv; env++) {
      dtFlag = (SCHAR)FDKreadBits (hBitBuf, 1);
      if (!dtFlag)
      {
        if (pBsData->bFineIidQ)
          CurrentTable = (Huffman)&aBookPsIidFineFreqDecode;
        else
          CurrentTable = (Huffman)&aBookPsIidFreqDecode;
      }
      else
      {
        if (pBsData->bFineIidQ)
         CurrentTable = (Huffman)&aBookPsIidFineTimeDecode;
        else
          CurrentTable = (Huffman)&aBookPsIidTimeDecode;
      }

      for (gr = 0; gr < FDK_sbrDecoder_aNoIidBins[pBsData->freqResIid]; gr++)
        pBsData->aaIidIndex[env][gr] = decode_huff_cw(CurrentTable,hBitBuf,NULL);
      pBsData->abIidDtFlag[env] = dtFlag;
    }
  }

  /* Extract ICC data */
  if (pBsData->bEnableIcc) {
    for (env=0; env<pBsData->noEnv; env++) {
      dtFlag = (SCHAR)FDKreadBits (hBitBuf, 1);
      if (!dtFlag)
        CurrentTable = (Huffman)&aBookPsIccFreqDecode;
      else
        CurrentTable = (Huffman)&aBookPsIccTimeDecode;

      for (gr = 0; gr < FDK_sbrDecoder_aNoIccBins[pBsData->freqResIcc]; gr++)
        pBsData->aaIccIndex[env][gr] = decode_huff_cw(CurrentTable,hBitBuf,NULL);
      pBsData->abIccDtFlag[env] = dtFlag;
    }
  }

  if (pBsData->bEnableExt) {

    /*!
    Decoders that support only the baseline version of the PS tool are allowed
    to ignore the IPD/OPD data, but according header data has to be parsed.
    ISO/IEC 14496-3 Subpart 8 Annex 4
    */

    int cnt = FDKreadBits(hBitBuf, PS_EXTENSION_SIZE_BITS);
    if (cnt == (1<<PS_EXTENSION_SIZE_BITS)-1) {
      cnt += FDKreadBits(hBitBuf, PS_EXTENSION_ESC_COUNT_BITS);
    }
    while (cnt--)
      FDKreadBits(hBitBuf, 8);
  }


  /* new PS data was read from bitstream */
  h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_mpeg;



  return (startbits - FDKgetValidBits(hBitBuf));
}
Пример #20
0
void
FDKaacEnc_groupShortData(FIXP_DBL      *mdctSpectrum,     /* in-out                           */
               SFB_THRESHOLD *sfbThreshold,     /* in-out                           */
               SFB_ENERGY    *sfbEnergy,        /* in-out                           */
               SFB_ENERGY    *sfbEnergyMS,      /* in-out                           */
               SFB_ENERGY    *sfbSpreadEnergy,
               const INT      sfbCnt,
               const INT      sfbActive,
               const INT     *sfbOffset,
               const FIXP_DBL *sfbMinSnrLdData,
               INT           *groupedSfbOffset,       /* out */
               INT           *maxSfbPerGroup,         /* out */
               FIXP_DBL      *groupedSfbMinSnrLdData,
               const INT      noOfGroups,
               const INT     *groupLen,
               const INT      granuleLength)
{
  INT i,j;
  INT line;       /* counts through lines              */
  INT sfb;        /* counts through scalefactor bands  */
  INT grp;        /* counts through groups             */
  INT wnd;        /* counts through windows in a group */
  INT offset;     /* needed in sfbOffset grouping      */
  INT highestSfb;

  INT granuleLength_short = granuleLength/TRANS_FAC;

  /* for short blocks: regroup spectrum and */
  /* group energies and thresholds according to grouping */
  C_ALLOC_SCRATCH_START(tmpSpectrum, FIXP_DBL, (1024));

  /* calculate maxSfbPerGroup */
  highestSfb = 0;
  for (wnd = 0; wnd < TRANS_FAC; wnd++)
  {
    for (sfb = sfbActive-1; sfb >= highestSfb; sfb--)
    {
      for (line = sfbOffset[sfb+1]-1; line >= sfbOffset[sfb]; line--)
      {
        if ( mdctSpectrum[wnd*granuleLength_short+line] != FL2FXCONST_SPC(0.0) ) break; /* this band is not completely zero */
      }
      if (line >= sfbOffset[sfb]) break;                                      /* this band was not completely zero */
    }
    highestSfb = fixMax(highestSfb, sfb);
  }
  highestSfb = highestSfb > 0 ? highestSfb : 0;
  *maxSfbPerGroup = highestSfb+1;

  /* calculate groupedSfbOffset */
  i = 0;
  offset = 0;
  for (grp = 0; grp < noOfGroups; grp++)
  {
      for (sfb = 0; sfb < sfbActive+1; sfb++)
      {
          groupedSfbOffset[i++] = offset + sfbOffset[sfb] * groupLen[grp];
      }
      i +=  sfbCnt-sfb;
      offset += groupLen[grp] * granuleLength_short;
  }
  groupedSfbOffset[i++] = granuleLength;

  /* calculate groupedSfbMinSnr */
  i = 0;
  for (grp = 0; grp < noOfGroups; grp++)
  {
    for (sfb = 0; sfb < sfbActive; sfb++)
    {
      groupedSfbMinSnrLdData[i++] = sfbMinSnrLdData[sfb];
    }
    i +=  sfbCnt-sfb;
  }

  /* sum up sfbThresholds */
  wnd = 0;
  i = 0;
  for (grp = 0; grp < noOfGroups; grp++)
  {
    for (sfb = 0; sfb < sfbActive; sfb++)
    {
      FIXP_DBL thresh = sfbThreshold->Short[wnd][sfb];
      for (j=1; j<groupLen[grp]; j++)
      {
        thresh = nrgAddSaturate(thresh, sfbThreshold->Short[wnd+j][sfb]);
      }
      sfbThreshold->Long[i++] = thresh;
    }
    i +=  sfbCnt-sfb;
    wnd += groupLen[grp];
  }

  /* sum up sfbEnergies left/right */
  wnd = 0;
  i = 0;
  for (grp = 0; grp < noOfGroups; grp++)
  {
    for (sfb = 0; sfb < sfbActive; sfb++)
    {
      FIXP_DBL energy = sfbEnergy->Short[wnd][sfb];
      for (j=1; j<groupLen[grp]; j++)
      {
        energy = nrgAddSaturate(energy, sfbEnergy->Short[wnd+j][sfb]);
      }
      sfbEnergy->Long[i++] = energy;
    }
    i +=  sfbCnt-sfb;
    wnd += groupLen[grp];
  }

  /* sum up sfbEnergies mid/side */
  wnd = 0;
  i = 0;
  for (grp = 0; grp < noOfGroups; grp++)
  {
    for (sfb = 0; sfb < sfbActive; sfb++)
    {
      FIXP_DBL energy = sfbEnergyMS->Short[wnd][sfb];
      for (j=1; j<groupLen[grp]; j++)
      {
        energy = nrgAddSaturate(energy, sfbEnergyMS->Short[wnd+j][sfb]);
      }
      sfbEnergyMS->Long[i++] = energy;
    }
    i +=  sfbCnt-sfb;
    wnd += groupLen[grp];
  }

  /* sum up sfbSpreadEnergies */
  wnd = 0;
  i = 0;
  for (grp = 0; grp < noOfGroups; grp++)
  {
    for (sfb = 0; sfb < sfbActive; sfb++)
    {
      FIXP_DBL energy = sfbSpreadEnergy->Short[wnd][sfb];
      for (j=1; j<groupLen[grp]; j++)
      {
         energy = nrgAddSaturate(energy, sfbSpreadEnergy->Short[wnd+j][sfb]);
      }
      sfbSpreadEnergy->Long[i++] = energy;
    }
    i +=  sfbCnt-sfb;
    wnd += groupLen[grp];
  }

  /* re-group spectrum */
  wnd = 0;
  i = 0;
  for (grp = 0; grp < noOfGroups; grp++)
  {
    for (sfb = 0; sfb < sfbActive; sfb++)
    {
      int width = sfbOffset[sfb+1]-sfbOffset[sfb];
      FIXP_DBL *pMdctSpectrum = &mdctSpectrum[sfbOffset[sfb]] + wnd*granuleLength_short;
      for (j = 0; j < groupLen[grp]; j++)
      {
        FIXP_DBL *pTmp = pMdctSpectrum;
        for (line = width; line > 0; line--)
        {
          tmpSpectrum[i++] = *pTmp++;
        }
        pMdctSpectrum += granuleLength_short;
      }
    }
    i +=  (groupLen[grp]*(sfbOffset[sfbCnt]-sfbOffset[sfb]));
    wnd += groupLen[grp];
  }

  FDKmemcpy(mdctSpectrum, tmpSpectrum, granuleLength*sizeof(FIXP_DBL));

  C_ALLOC_SCRATCH_END(tmpSpectrum, FIXP_DBL, (1024))
}