static void
calculateDetectorValues(FIXP_DBL **quotaMatrixOrig,       /*!< Matrix holding the tonality values of the original. */
                        SCHAR    *indexVector,            /*!< Index vector to obtain the patched data. */
                        FIXP_DBL *nrgVector,              /*!< Energy vector. */
                        DETECTOR_VALUES *detectorValues,  /*!< pointer to DETECTOR_VALUES struct. */
                        INT startChannel,                 /*!< Start channel. */
                        INT stopChannel,                  /*!< Stop channel. */
                        INT startIndex,                   /*!< Start index. */
                        INT stopIndex,                    /*!< Stop index. */
                        INT numberOfStrongest             /*!< The number of sorted tonal components to be considered. */
                        )
{
  INT i,temp, j;

  const FIXP_DBL* filter = *fir_table[INVF_SMOOTHING_LENGTH];
  FIXP_DBL origQuotaMeanStrongest, sbrQuotaMeanStrongest;
  FIXP_DBL origQuota, sbrQuota;
  FIXP_DBL invIndex, invChannel, invTemp;
  FIXP_DBL quotaVecOrig[64], quotaVecSbr[64];

  FDKmemclear(quotaVecOrig,64*sizeof(FIXP_DBL));
  FDKmemclear(quotaVecSbr,64*sizeof(FIXP_DBL));

  invIndex = GetInvInt(stopIndex-startIndex);
  invChannel = GetInvInt(stopChannel-startChannel);

  /*
   Calculate the mean value, over the current time segment, for the original, the HFR
   and the difference, over all channels in the current frequency range.
   NOTE: the averaging is done on the values quota/(1 - quota + RELAXATION).
   */

  /* The original, the sbr signal and the total energy */
  detectorValues->avgNrg = FL2FXCONST_DBL(0.0f);
  for(j=startIndex; j<stopIndex; j++) {
    for(i=startChannel; i<stopChannel; i++) {
      quotaVecOrig[i] += fMult(quotaMatrixOrig[j][i], invIndex);

      if(indexVector[i] != -1)
        quotaVecSbr[i] += fMult(quotaMatrixOrig[j][indexVector[i]], invIndex);
    }
    detectorValues->avgNrg += fMult(nrgVector[j], invIndex);
  }

  /*
   Calculate the mean value, over the current frequency range, for the original, the HFR
   and the difference. Also calculate the same mean values for the three vectors, but only
   includeing the x strongest copmponents.
   */

  origQuota = FL2FXCONST_DBL(0.0f);
  sbrQuota  = FL2FXCONST_DBL(0.0f);
  for(i=startChannel; i<stopChannel; i++) {
    origQuota += fMultDiv2(quotaVecOrig[i], invChannel);
    sbrQuota  += fMultDiv2(quotaVecSbr[i], invChannel);
  }

  /*
   Calculate the mean value for the x strongest components
  */
  FDKsbrEnc_Shellsort_fract(quotaVecOrig+startChannel,stopChannel-startChannel);
  FDKsbrEnc_Shellsort_fract(quotaVecSbr+startChannel,stopChannel-startChannel);

  origQuotaMeanStrongest = FL2FXCONST_DBL(0.0f);
  sbrQuotaMeanStrongest  = FL2FXCONST_DBL(0.0f);

  temp = min(stopChannel - startChannel, numberOfStrongest);
  invTemp = GetInvInt(temp);

  for(i=0; i<temp; i++) {
    origQuotaMeanStrongest += fMultDiv2(quotaVecOrig[i + stopChannel - temp], invTemp);
    sbrQuotaMeanStrongest  += fMultDiv2(quotaVecSbr[i + stopChannel - temp], invTemp);
  }

  /*
   The value for the strongest component
  */
  detectorValues->origQuotaMax = quotaVecOrig[stopChannel - 1];
  detectorValues->sbrQuotaMax  = quotaVecSbr[stopChannel - 1];

  /*
   Buffer values
  */
  FDKmemmove(detectorValues->origQuotaMean, detectorValues->origQuotaMean + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
  FDKmemmove(detectorValues->sbrQuotaMean, detectorValues->sbrQuotaMean + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
  FDKmemmove(detectorValues->origQuotaMeanStrongest, detectorValues->origQuotaMeanStrongest + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
  FDKmemmove(detectorValues->sbrQuotaMeanStrongest, detectorValues->sbrQuotaMeanStrongest + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));

  detectorValues->origQuotaMean[INVF_SMOOTHING_LENGTH]          = origQuota<<1;
  detectorValues->sbrQuotaMean[INVF_SMOOTHING_LENGTH]           = sbrQuota<<1;
  detectorValues->origQuotaMeanStrongest[INVF_SMOOTHING_LENGTH] = origQuotaMeanStrongest<<1;
  detectorValues->sbrQuotaMeanStrongest[INVF_SMOOTHING_LENGTH]  = sbrQuotaMeanStrongest<<1;

  /*
   Filter values
  */
  detectorValues->origQuotaMeanFilt = FL2FXCONST_DBL(0.0f);
  detectorValues->sbrQuotaMeanFilt = FL2FXCONST_DBL(0.0f);
  detectorValues->origQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f);
  detectorValues->sbrQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f);

  for(i=0;i<INVF_SMOOTHING_LENGTH+1;i++) {
    detectorValues->origQuotaMeanFilt += fMult(detectorValues->origQuotaMean[i], filter[i]);
    detectorValues->sbrQuotaMeanFilt  += fMult(detectorValues->sbrQuotaMean[i], filter[i]);
    detectorValues->origQuotaMeanStrongestFilt += fMult(detectorValues->origQuotaMeanStrongest[i], filter[i]);
    detectorValues->sbrQuotaMeanStrongestFilt  += fMult(detectorValues->sbrQuotaMeanStrongest[i], filter[i]);
  }
}
Beispiel #2
0
SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER   self,
                             INT_PCM            *timeData,
                             int                *numChannels,
                             int                *sampleRate,
                             const UCHAR         channelMapping[(8)],
                             const int           interleaved,
                             const int           coreDecodedOk,
                             UCHAR              *psDecoded )
{
  SBR_ERROR errorStatus = SBRDEC_OK;

  int   psPossible = 0;
  int   sbrElementNum;
  int   numCoreChannels = *numChannels;
  int   numSbrChannels  = 0;

  psPossible = *psDecoded;

  if (self->numSbrElements < 1) {
    /* exit immediately to avoid access violations */
    return SBRDEC_CREATE_ERROR;
  }

  /* Sanity check of allocated SBR elements. */
  for (sbrElementNum=0; sbrElementNum<self->numSbrElements; sbrElementNum++) {
    if (self->pSbrElement[sbrElementNum] == NULL) {
      return SBRDEC_CREATE_ERROR;
    }
  }

  if (self->numSbrElements != 1 || self->pSbrElement[0]->elementID != ID_SCE) {
    psPossible = 0;
  }


  /* In case of non-interleaved time domain data and upsampling, make room for bigger SBR output. */
  if (self->synDownsampleFac == 1 && interleaved == 0) {
    int c, outputFrameSize;

    outputFrameSize =
            self->pSbrElement[0]->pSbrChannel[0]->SbrDec.SynthesisQMF.no_channels
            * self->pSbrElement[0]->pSbrChannel[0]->SbrDec.SynthesisQMF.no_col;

    for (c=numCoreChannels-1; c>0; c--) {
      FDKmemmove(timeData + c*outputFrameSize, timeData + c*self->codecFrameSize , self->codecFrameSize*sizeof(INT_PCM));
    }
  }


  /* Make sure that even if no SBR data was found/parsed *psDecoded is returned 1 if psPossible was 0. */
  if (psPossible == 0) {
    self->flags &= ~SBRDEC_PS_DECODED;
  }

  /* Loop over SBR elements */
  for (sbrElementNum = 0; sbrElementNum<self->numSbrElements; sbrElementNum++)
  {
    int numElementChan;

    if (psPossible && self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) {
      errorStatus = SBRDEC_UNSUPPORTED_CONFIG;
      goto bail;
    }

    numElementChan = (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1;

    /* If core signal is bad then force upsampling */
    if ( ! coreDecodedOk ) {
      self->pSbrElement[sbrElementNum]->frameErrorFlag[self->pSbrElement[sbrElementNum]->useFrameSlot] = 1;
    }

    errorStatus = sbrDecoder_DecodeElement (
                                 self,
                                 timeData,
                                 interleaved,
                                 channelMapping,
                                 sbrElementNum,
                                 numCoreChannels,
                                &numElementChan,
                                 psPossible
                               );

    if (errorStatus != SBRDEC_OK) {
      goto bail;
    }

    numSbrChannels += numElementChan;
    channelMapping += numElementChan;

    if (numSbrChannels >= numCoreChannels) {
      break;
    }
  }

  /* Update numChannels and samplerate */
  *numChannels = numSbrChannels;
  *sampleRate = self->sampleRateOut;
  *psDecoded = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0;



  /* Clear reset and flush flag because everything seems to be done successfully. */
  self->flags &= ~SBRDEC_FORCE_RESET;
  self->flags &= ~SBRDEC_FLUSH;

bail:

  return errorStatus;
}