Пример #1
0
void CalcBandEnergyMS(const float *mdctSpectrumLeft,
                      const float *mdctSpectrumRight,
                      const int   *bandOffset,
                      const int    numBands,
                      float      *bandEnergyMid,
                      float       *bandEnergyMidSum,
                      float      *bandEnergySide,
                      float       *bandEnergySideSum) {

    int i, j;

    COUNT_sub_start("CalcBandEnergyMS");

    MOVE(3);
    j = 0;
    *bandEnergyMidSum = 0.0f;
    *bandEnergySideSum = 0.0f;

    PTR_INIT(5); /* pointers for bandEnergyMid[],
                               bandEnergySide[],
                               bandOffset[],
                               mdctSpectrumLeft[],
                               mdctSpectrumRight[]
               */
    LOOP(1);
    for(i=0; i<numBands; i++) {

        MOVE(2);
        bandEnergyMid[i] = 0.0f;
        bandEnergySide[i] = 0.0f;

        LOOP(1);
        while (j < bandOffset[i+1]) {
            float specm, specs;

            ADD(2);
            MULT(2);
            specm = 0.5f * (mdctSpectrumLeft[j] + mdctSpectrumRight[j]);
            specs = 0.5f * (mdctSpectrumLeft[j] - mdctSpectrumRight[j]);

            MAC(2);
            STORE(2);
            bandEnergyMid[i]  += specm * specm;
            bandEnergySide[i] += specs * specs;

            j++;
        }
        ADD(2);
        STORE(2);
        *bandEnergyMidSum += bandEnergyMid[i];
        *bandEnergySideSum += bandEnergySide[i];

    }

    COUNT_sub_end();
}
Пример #2
0
/*****************************************************************************

    functionname: atan_approx
    description:  Calculates atan , val >=0
    returns:      approx of atan(val), error is less then 0.5 %
    input:
    output:

*****************************************************************************/
static float atan_approx(float val)
{
  COUNT_sub_start("atan_approx");

  ADD(1); BRANCH(1);
  if(val < (float)1.0)
  {
    DIV(1); MULT(2); ADD(1); /* counting post-operations */
    COUNT_sub_end();
    return(val/((float)1.0f+(float)0.280872f*val*val));
  }
  else
  {
    DIV(1); MULT(1); ADD(2); /* counting post-operations */
    COUNT_sub_end();
    return((float)1.57079633f-val/((float)0.280872f +val*val));
  }

}
Пример #3
0
static void
AdvanceARFilter( IIR_FILTER *iirFilter,
                 float input
                 )

{
  int j;
  float y;
  int ptr = iirFilter->ptr;
  int i = ptr + (BUFFER_SIZE-1);

  COUNT_sub_start("AdvanceARFilter");

  INDIRECT(1); MOVE(1); ADD(1); /* counting previous operations */

  INDIRECT(2); MULT(1); ADD(1);
  y = input + (iirFilter->coeffIIRb[1] * (-iirFilter->ring_buf_2[i & (BUFFER_SIZE-1)]));

  PTR_INIT(4); /* iirFilter->noOffCoeffs
                  iirFilter->coeffIIRb[]
                  iirFilter->ring_buf_2[i]
                  iirFilter->ring_buf_2[ptr]
               */

  LOOP(1);
  for (j=2; j<iirFilter->noOffCoeffs; j++) {
    i--;

    MULT(1); MAC(1);
    y += (iirFilter->coeffIIRb[j] * (-iirFilter->ring_buf_2[i & (BUFFER_SIZE-1)]));
  }

  MOVE(1);
  iirFilter->ring_buf_2[ptr] = y;

  /* pointer update */
  iirFilter->ptr = (ptr+1) & (BUFFER_SIZE-1);

  COUNT_sub_end();

}
Пример #4
0
/*
 *
 * \brief Perform complex-valued inverse modulation of the subband
 *        samples stored in rSubband (real part) and iSubband (imaginary
 *        part) and stores the result in timeOut
 *
 */
static void
inverseModulation (float *qmfReal,
                   float *qmfImag,
                   HANDLE_SBR_QMF_FILTER_BANK synQmf
                   )
{
  int i, no_synthesis_channels, M;

  float r1, i1, r2, i2;

  COUNT_sub_start("inverseModulation");

  INDIRECT(1); MOVE(1);
  no_synthesis_channels = synQmf->no_channels;

  MULT(1);
  M = no_synthesis_channels / 2;
  PTR_INIT(2);  /* pointer for qmfReal[],
                               qmfImag[] */
  INDIRECT(1); LOOP(1);
  for (i = synQmf->usb; i < no_synthesis_channels; i++) {
    MOVE(2);

    qmfReal[i]=qmfImag[i]=0;
  }

  FUNC(2);
  cosMod (qmfReal, synQmf);
  FUNC(2);
  sinMod (qmfImag, synQmf);

  PTR_INIT(4);  /* pointer for qmfReal[],
                               qmfImag[],
                               qmfImag[no_synthesis_channels - 1 - i],
                               qmfReal[no_synthesis_channels - i - 1]   */
  LOOP(1);
  for (i = 0; i < M; i++) {

    MOVE(4);
    r1 = qmfReal[i];
    i2 = qmfImag[no_synthesis_channels - 1 - i];
    r2 = qmfReal[no_synthesis_channels - i - 1];
    i1 = qmfImag[i];

    ADD(4); STORE(4);
    qmfReal[i] = (r1 - i1);
    qmfImag[no_synthesis_channels - 1 - i] = -(r1 + i1);
    qmfReal[no_synthesis_channels - i - 1] = (r2 - i2);
    qmfImag[i] = -(r2 + i2);
  }

  COUNT_sub_end();
}
Пример #5
0
/*
 *
 * \brief Perform real-valued forward modulation of the time domain
 *        data of timeIn and stores the real part of the subband
 *        samples in rSubband
 *
 */
static void
sbrForwardModulationLP (const float *timeIn,
                        float *rSubband,
                        HANDLE_SBR_QMF_FILTER_BANK qmfBank
                        )
{
  int i, L, M;

  COUNT_sub_start("sbrForwardModulationLP");

  MOVE(1);
  L = NO_ANALYSIS_CHANNELS;

  MULT(1);
  M = L/2;

  PTR_INIT(1);  /* pointers for rSubband[] */
  MULT(1); MOVE(1);
  rSubband[0] = timeIn[3 * M];

  PTR_INIT(2);  /* pointers for timeIn[3 * M - i],
                                timeIn[3 * M + i]  */
  LOOP(1);
  for (i = 1; i < M; i++) {
    ADD(1); STORE(1);
    rSubband[i] = timeIn[3 * M - i] + timeIn[3 * M + i];
  }

  LOOP(1);
  for (i = M; i < L; i++) {
    ADD(1); STORE(1);
    rSubband[i] = timeIn[3 * M - i] - timeIn[i - M];
  }

  FUNC(3);
  dct3 (rSubband, L, qmfBank);

  COUNT_sub_end();
}
Пример #6
0
int main(int argc, char *argv[]){

		if (argc > 1 && atoi(argv[1]) > 10) limit = atoi(argv[1]);

		clock_t start, end;
		srand(clock());

		M = rand() % limit/2 + limit/2;
		N = rand() % limit/2 + limit/2;
		O = (rand() % limit/8 + 1 + limit/16) * 4;


		float* A = random_matrix(M, N, 10);
		float* B = random_matrix(N, O, 10);
		float* C = malloc(sizeof(float) * M * O);
		float* D;

		printf("Generadas dos matrices aleatorias de (%zu x %zu) y (%zu x %zu)\n", M, N, N, O);

		if (print) {
			print_matrix(A, M, N);
			printf("\n");
			print_matrix(B, N, O);
			printf("\n");
		}

		start = clock();
		D = MULT(A, B, M, N, O);
		end = clock();

		printf("RESULTADO FUERZA BRUTA: (%f)\n", ((double)(end - start))/CLOCKS_PER_SEC);
		if (print) print_matrix(D, M, O);



		start = clock();
		SIMD_MULT(A, B, C, M, N, O);
		end = clock();

		printf("RESULTADO SIMD: (%f)\n", ((double)(end - start))/CLOCKS_PER_SEC);
		if (print) print_matrix(C, M, O);

		if (equal_mtrx(C, D, M*O)) printf("Son iguales!\n");
		else printf("NO son iguales!\n");

		free(A);
		free(B);
		free(C);
		free(D);
}
Пример #7
0
/*****************************************************************************

    functionname: BarcLineValue
    description:  Calculates barc value for one frequency line
    returns:      barc value of line
    input:        number of lines in transform, index of line to check, Fs
    output:

*****************************************************************************/
static float BarcLineValue(int noOfLines, int fftLine, long samplingFreq) {

  float center_freq, temp, bvalFFTLine;

  COUNT_sub_start("BarcLineValue");

  /*
    center frequency of fft line
  */
  MULT(2); DIV(1);
  center_freq = (float) fftLine * ((float)samplingFreq * (float)0.5f)/(float)noOfLines;

  MULT(1); FUNC(1);
  temp = (float) atan_approx((float)1.3333333e-4f * center_freq);

  MULT(4); ADD(1); FUNC(1);
  bvalFFTLine = (float)13.3f * atan_approx((float)0.00076f * center_freq) + (float)3.5f * temp * temp;

  COUNT_sub_end();

  return(bvalFFTLine);

}
Пример #8
0
void SpreadingMax(const int    pbCnt,
                  const float *maskLowFactor,
                  const float *maskHighFactor,
                  float       *pbSpreadedEnergy)
{
   int i;

   COUNT_sub_start("SpreadingMax");

   /* slope to higher frequencies */
   PTR_INIT(2); /* pointers for pbSpreadedEnergy[],
                                maskHighFactor[]
                */
   LOOP(1);
   for (i=1; i<pbCnt; i++) {

      MULT(1); ADD(1); BRANCH(1); MOVE(1);
      pbSpreadedEnergy[i] = max(pbSpreadedEnergy[i],
                                maskHighFactor[i] * pbSpreadedEnergy[i-1]);
   }

   /* slope to lower frequencies */
   PTR_INIT(2); /* pointers for pbSpreadedEnergy[],
                                maskLowFactor[]
                */
   LOOP(1);
   for (i=pbCnt-2; i>=0; i--) {

      MULT(1); ADD(1); BRANCH(1); MOVE(1);
      pbSpreadedEnergy[i] = max(pbSpreadedEnergy[i],
                                maskLowFactor[i] * pbSpreadedEnergy[i+1]);
   }

   COUNT_sub_end();

}
static void apply_window(const float *buf, const float *win1,
                         const float *win2, float *sum1, float *sum2, int len)
{
	const vector float *win1a = (const vector float *) win1;
	const vector float *win2a = (const vector float *) win2;
	const vector float *bufa  = (const vector float *) buf;
	vector float *sum1a = (vector float *) sum1;
	vector float *sum2a = (vector float *) sum2;
	vector float av_uninit(v0), av_uninit(v4);
	vector float v1, v2, v3;

	len = len >> 2;

#define MULT(a, b)                         \
    {                                      \
        v1 = vec_ld(a, win1a);             \
        v2 = vec_ld(b, win2a);             \
        v3 = vec_ld(a, bufa);              \
        v0 = vec_madd(v3, v1, v0);         \
        v4 = vec_madd(v2, v3, v4);         \
    }

	while (len--)
	{
		v0 = vec_xor(v0, v0);
		v4 = vec_xor(v4, v4);

		MULT(   0,   0);
		MULT( 256,  64);
		MULT( 512, 128);
		MULT( 768, 192);
		MULT(1024, 256);
		MULT(1280, 320);
		MULT(1536, 384);
		MULT(1792, 448);

		vec_st(v0, 0, sum1a);
		vec_st(v4, 0, sum2a);
		sum1a++;
		sum2a++;
		win1a++;
		win2a++;
		bufa++;
	}
}
Пример #10
0
int
IIR32GetResamplerFeed( int blockSizeOut)
{
  int size;

  COUNT_sub_start("IIR32GetResamplerFeed");

  MULT(1);
  size  = blockSizeOut * 3;

  DIV(1);
  size /= 2;

  COUNT_sub_end();

  return size;
}
Пример #11
0
/*
  \brief     crc
*/
static int
getCrc (HANDLE_BIT_BUFFER hBitBuf, unsigned long NrBits)
{

  int i;
  int CrcStep = NrBits / MAXCRCSTEP;
  int CrcNrBitsRest = (NrBits - CrcStep * MAXCRCSTEP);
  unsigned long bValue;

  CRC_BUFFER CrcBuf;

  FLC_sub_start("getCrc");

  DIV(1); MULT(1); ADD(1); /* counting previous operations */

  MOVE(3);
  CrcBuf.crcState = SBR_CRC_START;
  CrcBuf.crcPoly  = SBR_CRC_POLY;
  CrcBuf.crcMask  = SBR_CRC_MASK;

  LOOP(1);
  for (i = 0; i < CrcStep; i++) {

    FUNC(2);
    bValue = getbits (hBitBuf, MAXCRCSTEP);

    PTR_INIT(1); FUNC(3);
    calcCRC (&CrcBuf, bValue, MAXCRCSTEP);
  }

  FUNC(2);
  bValue = getbits (hBitBuf, CrcNrBitsRest);

  PTR_INIT(1); FUNC(3);
  calcCRC (&CrcBuf, bValue, CrcNrBitsRest);

  LOGIC(1); /* counting post operation */

  FLC_sub_end();

  return (CrcBuf.crcState & SBR_CRC_RANGE);

}
Пример #12
0
static float calcBitSave(float fillLevel,
                         const float clipLow,
                         const float clipHigh,
                         const float minBitSave,
                         const float maxBitSave)
{
   float bitsave;

   COUNT_sub_start("calcBitSave");

   ADD(2); BRANCH(2); MOVE(2);
   fillLevel = max(fillLevel, clipLow);
   fillLevel = min(fillLevel, clipHigh);

   ADD(4); DIV(1); MULT(1);
   bitsave = maxBitSave - ((maxBitSave-minBitSave) / (clipHigh-clipLow)) *
                          (fillLevel-clipLow);

   COUNT_sub_end();

   return (bitsave);
}
Пример #13
0
static float calcBitSpend(float fillLevel,
                          const float clipLow,
                          const float clipHigh,
                          const float minBitSpend,
                          const float maxBitSpend)
{
   float bitspend;

   COUNT_sub_start("calcBitSpend");

   ADD(2); BRANCH(2); MOVE(2);
   fillLevel = max(fillLevel, clipLow);
   fillLevel = min(fillLevel, clipHigh);

   ADD(4); DIV(1); MULT(1);
   bitspend = minBitSpend + ((maxBitSpend-minBitSpend) / (clipHigh-clipLow)) *
                            (fillLevel-clipLow);

   COUNT_sub_end();

   return (bitspend);
}
Пример #14
0
static float
AdvanceIIRFilter(IIR_FILTER *iirFilter,
                 float input
                 )

{
  float y = 0.0f;
  int j = 0;
  int i;

  COUNT_sub_start("AdvanceIIRFilter");

  MOVE(2); /* counting previous operations */

  INDIRECT(1); MOVE(1);
  iirFilter->ring_buf_1[iirFilter->ptr] = input;

  PTR_INIT(4); /* pointer for iirFilter->ring_buf_1,
                              iirFilter->ring_buf_2,
                              iirFilter->coeffIIRa,
                              iirFilter->coeffIIRb
               */
  ADD(1); LOOP(1);
  for (i = iirFilter->ptr; i > iirFilter->ptr - iirFilter->noOffCoeffs; i--, j++) {
    MULT(2); ADD(1);
    y += iirFilter->coeffIIRa[j] * iirFilter->ring_buf_1[i & (BUFFER_SIZE - 1)] - iirFilter->coeffIIRb[j] * iirFilter->ring_buf_2[i & (BUFFER_SIZE - 1)];
  }

  MOVE(1);
  iirFilter->ring_buf_2[(iirFilter->ptr) & (BUFFER_SIZE - 1)] = y;

  
  iirFilter->ptr = (iirFilter->ptr+1) & (BUFFER_SIZE - 1);

  COUNT_sub_end();

  return y;
}
Пример #15
0
Файл: io.c Проект: soywiz/nwebp
static WEBP_INLINE void ImportRow(const uint8_t* const src,
                                  WebPRescaler* const wrk) {
  int x_in = 0;
  int x_out;
  int accum = 0;
  if (!wrk->x_expand) {
    int sum = 0;
    for (x_out = 0; x_out < wrk->dst_width; ++x_out) {
      accum += wrk->x_add;
      for (; accum > 0; accum -= wrk->x_sub) {
        sum += src[x_in++];
      }
      {        // Emit next horizontal pixel.
        const int32_t base = src[x_in++];
        const int32_t frac = base * (-accum);
        wrk->frow[x_out] = (sum + base) * wrk->x_sub - frac;
        // fresh fractional start for next pixel
        sum = MULT(frac, wrk->fx_scale);
      }
    }
  } else {        // simple bilinear interpolation
    int left = src[0], right = src[0];
    for (x_out = 0; x_out < wrk->dst_width; ++x_out) {
      if (accum < 0) {
        left = right;
        right = src[++x_in];
        accum += wrk->x_add;
      }
      wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum;
      accum -= wrk->x_sub;
    }
  }
  // Accumulate the new row's contribution
  for (x_out = 0; x_out < wrk->dst_width; ++x_out) {
    wrk->irow[x_out] += wrk->frow[x_out];
  }
}
Пример #16
0
static void
cairo_to_pixbuf (GOImage *image)
{
	guint i,j, rowstride;
	unsigned char *src, *dst;
	guint t;

	g_return_if_fail (IS_GO_IMAGE (image) && image->data && image->pixbuf);

#define MULT(d,c,a,t) G_STMT_START { t = (a)? c * 255 / a: 0; d = t;} G_STMT_END

	dst = gdk_pixbuf_get_pixels (image->pixbuf);
	rowstride = gdk_pixbuf_get_rowstride (image->pixbuf);
	src = image->data;

	for (i = 0; i < image->height; i++) {
		for (j = 0; j < image->width; j++) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
			MULT(dst[0], src[2], src[3], t);
			MULT(dst[1], src[1], src[3], t);
			MULT(dst[2], src[0], src[3], t);
			dst[3] = src[3];
#else
			MULT(dst[3], src[2], src[3], t);
			MULT(dst[2], src[1], src[3], t);
			MULT(dst[1], src[0], src[3], t);
			dst[0] = src[3];
#endif
			src += 4;
			dst += 4;
		}
		dst += rowstride - image->width * 4;
		src += image->rowstride - image->width * 4;
	}
#undef MULT
}
Пример #17
0
/*
 * \brief Perform transposition by patching of subband samples.
 */
void lppTransposer (HANDLE_SBR_LPP_TRANS hLppTrans,
                    float **qmfBufferReal,
#ifndef LP_SBR_ONLY
                    float **qmfBufferImag,
#endif
                    float *degreeAlias,
                    int timeStep,
                    int firstSlotOffs,
                    int lastSlotOffs,
                    unsigned char nInvfBands,
                    INVF_MODE *sbr_invf_mode,
                    INVF_MODE *sbr_invf_mode_prev,
                    int   bUseLP
                    )
{
  int    bwIndex[MAX_NUM_PATCHES];
  float  bwVector[MAX_NUM_PATCHES];

  int    i,j;
  int    loBand, hiBand;

  PATCH_PARAM *patchParam;

  int    patch;

  float  alphar[LPC_ORDER], a0r, a1r;
  float  alphai[LPC_ORDER], a0i, a1i;

  float  bw;

  int    autoCorrLength;

  float k1, k1_below, k1_below2;

  ACORR_COEFS ac;
  int    startSample;
  int    stopSample;
  int    stopSampleClear;
  int    lb, hb;

  int targetStopBand;

  COUNT_sub_start("lppTransposer");

  INDIRECT(1); PTR_INIT(1);
  patchParam = hLppTrans->pSettings->patchParam;

  MOVE(1);
  bw = 0.0f;

  MOVE(2);
  k1_below=0, k1_below2=0;

  MULT(1);
  startSample = firstSlotOffs * timeStep;

  INDIRECT(1); MULT(1); ADD(1);
  stopSample  = hLppTrans->pSettings->nCols + lastSlotOffs * timeStep;

  FUNC(5);
  inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode, sbr_invf_mode_prev, bwVector);


  MOVE(1);
  stopSampleClear = stopSample;

  PTR_INIT(2); /* pointers for qmfBufferReal[],
                               qmfBufferImag[]  */
  INDIRECT(1); LOOP(1);
  for ( patch = 0; patch < hLppTrans->pSettings->noOfPatches; patch++ ) {
    LOOP(1);
    for (i = startSample; i < stopSampleClear; i++) {
      INDIRECT(1); ADD(1); LOOP(1);
      for(j=patchParam[patch].guardStartBand; j<patchParam[patch].guardStartBand+GUARDBANDS; j++){
        MOVE(1);
        qmfBufferReal[i][j] = 0.0;
#ifndef LP_SBR_ONLY
        BRANCH(1);
        if (!bUseLP) {
          MOVE(1);
          qmfBufferImag[i][j] = 0.0;
        }
#endif
      }
    }
  }

  INDIRECT(4); ADD(1);
  targetStopBand = patchParam[hLppTrans->pSettings->noOfPatches-1].targetStartBand +
    patchParam[hLppTrans->pSettings->noOfPatches-1].numBandsInPatch;

  PTR_INIT(2); /* pointers for qmfBufferReal[],
                               qmfBufferImag[]  */
  LOOP(1);
  for (i = startSample; i < stopSampleClear; i++) {
    LOOP(1);
    for (j=targetStopBand; j<NO_SYNTHESIS_CHANNELS; j++) {
      MOVE(1);
      qmfBufferReal[i][j] = 0.0;
#ifndef LP_SBR_ONLY
      BRANCH(1);
      if (!bUseLP) {
        MOVE(1);
        qmfBufferImag[i][j] = 0.0;
      }
#endif
    }
  }

  INDIRECT(1); ADD(1);
  autoCorrLength = hLppTrans->pSettings->nCols + 6;

  PTR_INIT(1); /* pointer for bwIndex[patch] */
  INDIRECT(1); LOOP(1);
  for ( patch=0; patch<hLppTrans->pSettings->noOfPatches; patch++ ) {
    MOVE(1);
    bwIndex[patch] = 0;
  }



  BRANCH(1);
  if (bUseLP) {

    INDIRECT(1); ADD(1); BRANCH(1); MOVE(1);
    lb = max(1, hLppTrans->pSettings->lbStartPatching - 2);

    INDIRECT(1);
    hb = patchParam[0].targetStartBand;
  }
#ifndef LP_SBR_ONLY
  else {

    INDIRECT(2); MOVE(2);
    lb = hLppTrans->pSettings->lbStartPatching;
    hb = hLppTrans->pSettings->lbStopPatching;
  }
#endif


  PTR_INIT(2); /* pointers for qmfBufferReal[],
                               qmfBufferImag[]  */
  INDIRECT(1); LOOP(1);
  for ( loBand = lb; loBand < hb; loBand++ ) {

    float  lowBandReal[MAX_ENV_COLS+LPC_ORDER];
#ifndef LP_SBR_ONLY
    float  lowBandImag[MAX_ENV_COLS+LPC_ORDER];
#endif
    int lowBandPtr =0;
    int resetLPCCoeffs=0;

    PTR_INIT(4); /* pointers for lowBandReal[],
                                 lowBandImag[],
                                 lpcFilterStatesReal,
                                 lpcFilterStatesImag  */
    LOOP(1);
    for(i=0;i<LPC_ORDER;i++){
      MOVE(1);
      lowBandReal[lowBandPtr] = hLppTrans->lpcFilterStatesReal[i][loBand];

#ifndef LP_SBR_ONLY
      if (!bUseLP) {
        MOVE(1);
        lowBandImag[lowBandPtr] = hLppTrans->lpcFilterStatesImag[i][loBand];
      }
#endif
      lowBandPtr++;
    }

    LOOP(1);
    for(i=0;i< 6;i++){

      MOVE(1);
      lowBandReal[lowBandPtr] = (float) qmfBufferReal[i][loBand];

#ifndef LP_SBR_ONLY
      BRANCH(1);
      if (!bUseLP) {
        MOVE(1);
        lowBandImag[lowBandPtr] = (float) qmfBufferImag[i][loBand];
      }
#endif
      lowBandPtr++;
    }


    INDIRECT(1); ADD(1); LOOP(1);
    for(i=6;i<hLppTrans->pSettings->nCols+6;i++){

        MOVE(1);
        lowBandReal[lowBandPtr] = (float) qmfBufferReal[i][loBand];

#ifndef LP_SBR_ONLY
        BRANCH(1);
        if (!bUseLP) {
          MOVE(1);
          lowBandImag[lowBandPtr] = (float) qmfBufferImag[i][loBand];
        }
#endif
        lowBandPtr++;
    }


    BRANCH(1);
    if (bUseLP) {
      PTR_INIT(1); ADD(1); FUNC(3);
      autoCorrelation2ndLP(&ac,
                           lowBandReal+LPC_ORDER,
                           autoCorrLength);
    }
#ifndef LP_SBR_ONLY
    else {
      PTR_INIT(1); ADD(2); FUNC(3);
      autoCorrelation2nd(&ac,
                         lowBandReal+LPC_ORDER,
                         lowBandImag+LPC_ORDER,
                         autoCorrLength);
    }
#endif

    MOVE(2);
    alphar[1] = 0;
    alphai[1] = 0;

    INDIRECT(1); BRANCH(1);
    if (ac.det != 0.0f) {
      float fac;

      DIV(1);
      fac = 1.0f / ac.det;

      MULT(4); ADD(2); STORE(1);
      alphar[1] = ( ac.r01r * ac.r12r - ac.r01i * ac.r12i - ac.r02r * ac.r11r ) * fac;

#ifndef LP_SBR_ONLY
      BRANCH(1);
      if (!bUseLP) {
        MULT(3); MAC(1); ADD(1); STORE(1);
        alphai[1] = ( ac.r01i * ac.r12r + ac.r01r * ac.r12i - ac.r02i * ac.r11r ) * fac;
      }
#endif
    }

    MOVE(2);
    alphar[0] = 0;
    alphai[0] = 0;


    INDIRECT(1); BRANCH(1);
    if ( ac.r11r != 0.0f ) {
      float fac;

      DIV(1);
      fac = 1.0f / ac.r11r;

      MULT(3); MAC(1); ADD(1); STORE(1);
      alphar[0] = - ( ac.r01r + alphar[1] * ac.r12r + alphai[1] * ac.r12i ) * fac;

#ifndef LP_SBR_ONLY
      BRANCH(1);
      if (!bUseLP) {
        MULT(4); ADD(2); STORE(1);
        alphai[0] = - ( ac.r01i + alphai[1] * ac.r12r - alphar[1] * ac.r12i ) * fac;
      }
#endif

    }
    
    MULT(1); MAC(1); ADD(1); BRANCH(1);
    if(alphar[0]*alphar[0] + alphai[0]*alphai[0] >= 16.0f) {
      MOVE(1);
      resetLPCCoeffs=1;
    }
    MULT(1); MAC(1); ADD(1); BRANCH(1);
    if(alphar[1]*alphar[1] + alphai[1]*alphai[1] >= 16.0f) {
      MOVE(1);
      resetLPCCoeffs=1;
    }

    BRANCH(1);
    if(resetLPCCoeffs){
      MOVE(4);
      alphar[0] = alphar[1] = 0;
      alphai[0] = alphai[1] = 0;
    }

    BRANCH(1);
    if (bUseLP) {

      INDIRECT(1); BRANCH(1);
      if(ac.r11r==0.0f) {
        MOVE(1);
        k1 = 0.0f;
      }
      else {
        INDIRECT(2); DIV(1); MULT(1);
        k1 = -(ac.r01r/ac.r11r);

        ADD(1); BRANCH(1); MOVE(1);
        k1 = min(k1, 1.0f);
        ADD(1); BRANCH(1); MOVE(1);
        k1 = max(k1,-1.0f);
      }

      ADD(1); BRANCH(1);
      if(loBand > 1){
        float deg;

        MULT(1); ADD(1);
        deg = 1.0f - (k1_below * k1_below);

        MOVE(1);
        degreeAlias[loBand] = 0;

        PTR_INIT(1); /* pointer for degreeAlias[] */

        LOGIC(2); BRANCH(1);
        if (((loBand & 1) == 0) && (k1 < 0)){

          BRANCH(1);
          if (k1_below < 0) {

            MOVE(1);
            degreeAlias[loBand] = 1.0f;

            BRANCH(1);
            if ( k1_below2 > 0 ) {

              MOVE(1);
              degreeAlias[loBand-1] = deg;
            }
          }
          else {
            BRANCH(1);
            if ( k1_below2 > 0 ) {
              MOVE(1);
              degreeAlias[loBand] = deg;
            }
          }
        }

        LOGIC(2); BRANCH(1);
        if (((loBand & 1) == 1) && (k1 > 0)){

          BRANCH(1);
          if (k1_below > 0) {

            MOVE(1);
            degreeAlias[loBand] = 1.0f;

            BRANCH(1);
            if ( k1_below2 < 0 ) {

              MOVE(1);
              degreeAlias[loBand-1] = deg;
            }
          }
          else {
            BRANCH(1);
            if ( k1_below2 < 0 ) {
              MOVE(1);
              degreeAlias[loBand] = deg;
            }
          }
        }
      }
      MOVE(2);
      k1_below2 = k1_below;
      k1_below = k1;
    }

    MOVE(1);
    patch = 0;

    PTR_INIT(1); /* pointer for patchParam[patch] */
    INDIRECT(1); LOOP(1);
    while ( patch < hLppTrans->pSettings->noOfPatches ) {

      ADD(1);
      hiBand = loBand + patchParam[patch].targetBandOffs;

      ADD(2); LOGIC(1); BRANCH(1);
      if ( loBand < patchParam[patch].sourceStartBand || loBand >= patchParam[patch].sourceStopBand ) {
        ADD(1);
        patch++;
        continue;
      }
      assert( hiBand < NO_SYNTHESIS_CHANNELS );

      LOOP(1);
      while (hiBand >= hLppTrans->pSettings->bwBorders[bwIndex[patch]]) {
        INDIRECT(1); /* while() condition */

        ADD(1); STORE(1);
        bwIndex[patch]++;
      }

      INDIRECT(1);
      bw = bwVector[bwIndex[patch]];

      INDIRECT(4); MULT(5);
      a0r = bw * alphar[0];
      a0i = bw * alphai[0];
      bw =  bw*bw;
      a1r = bw * alphar[1];
      a1i = bw * alphai[1];


      PTR_INIT(4); /* pointers for lowBandReal[],
                                   lowBandImag[],
                                   qmfBufferReal[],
                                   qmfBufferImag[]  */
      LOOP(1);
      for(i = startSample; i < stopSample; i++ ) {

        MOVE(1);
        qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER+i];

        BRANCH(1);
        if (bUseLP) {

          BRANCH(1);
          if ( bw > 0 ) {

            MAC(2); STORE(1);
            qmfBufferReal[i][hiBand] = qmfBufferReal[i][hiBand] +
              a0r * lowBandReal[LPC_ORDER+i-1] +
              a1r * lowBandReal[LPC_ORDER+i-2];
          }
        }
#ifndef LP_SBR_ONLY
        else {

          MOVE(1);
          qmfBufferImag[i][hiBand] = lowBandImag[LPC_ORDER+i];

          BRANCH(1);
          if ( bw > 0 ) {
            float accu;

            MULT(4); ADD(3);
            accu = a0r * lowBandReal[LPC_ORDER+i-1] -  a0i * lowBandImag[LPC_ORDER+i-1]+
              a1r * lowBandReal[LPC_ORDER+i-2] -  a1i * lowBandImag[LPC_ORDER+i-2];

            ADD(1); STORE(1);
            qmfBufferReal[i][hiBand] = qmfBufferReal[i][hiBand] + accu;

            MAC(4);
            accu = a0i * lowBandReal[LPC_ORDER+i-1] +  a0r * lowBandImag[LPC_ORDER+i-1]+
              a1i * lowBandReal[LPC_ORDER+i-2] +  a1r * lowBandImag[LPC_ORDER+i-2];

            ADD(1); STORE(1);
            qmfBufferImag[i][hiBand] = qmfBufferImag[i][hiBand] + accu;
          }
        }
#endif

      }


      patch++;

    }  /* Patch */

  }  /* loBand (band) */


  PTR_INIT(4); /* pointers for lpcFilterStatesReal[][loBand],
                               lpcFilterStatesImag[][loBand],
                               qmfBufferReal[],
                               qmfBufferImag[]  */
  LOOP(1);
  for(i=0;i<LPC_ORDER;i++){
    INDIRECT(1); LOOP(1);
    for (loBand=0; loBand<patchParam[0].targetStartBand; loBand++) {
      MOVE(1);
      hLppTrans->lpcFilterStatesReal[i][loBand] = qmfBufferReal[hLppTrans->pSettings->nCols-LPC_ORDER+i][loBand];
#ifndef LP_SBR_ONLY
      BRANCH(1);
      if (!bUseLP) {
        MOVE(1);
        hLppTrans->lpcFilterStatesImag[i][loBand] = qmfBufferImag[hLppTrans->pSettings->nCols-LPC_ORDER+i][loBand];
      }
#endif
    }
  }

  BRANCH(1);
  if (bUseLP) {

    PTR_INIT(2); /* pointers for degreeAlias[loBand],
                                 degreeAlias[hiBand]  */
    INDIRECT(2); LOOP(1);
    for ( loBand = hLppTrans->pSettings->lbStartPatching; loBand <  hLppTrans->pSettings->lbStopPatching; loBand++ ) {

      MOVE(1);
      patch = 0;

      INDIRECT(1); LOOP(1);
      while ( patch < hLppTrans->pSettings->noOfPatches ) {

        INDIRECT(1); ADD(1);
        hiBand = loBand + patchParam[patch].targetBandOffs;

        LOGIC(2); ADD(3); BRANCH(1);
        if ( loBand < patchParam[patch].sourceStartBand
             || loBand >= patchParam[patch].sourceStopBand
             || hiBand >= NO_SYNTHESIS_CHANNELS
             ) {
          ADD(1);
          patch++;
          continue;
        }

        INDIRECT(1); ADD(1); BRANCH(1);
        if(hiBand != patchParam[patch].targetStartBand) {
          MOVE(1);
          degreeAlias[hiBand] = degreeAlias[loBand];
        }
        else {
          MOVE(1);
          degreeAlias[hiBand] = 0;
        }

        patch++;
      }
    }/* end  for loop */
  }

  PTR_INIT(2); /* pointers for bwVectorOld[],
                               bwVector[]     */
  LOOP(1);
  for (i = 0; i < nInvfBands; i++ ) {
    MOVE(1);
    hLppTrans->bwVectorOld[i] = bwVector[i];
  }

  COUNT_sub_end();
}
Пример #18
0
/*
 *
 * \brief Calculate second order autocorrelation using 2 accumulators
 *
 */
static void
autoCorrelation2ndLP(ACORR_COEFS *ac,
                     float *realBuf,
                     int len
                     )
{
  int   j;
  float accu1, accu2;

  COUNT_sub_start("autoCorrelation2ndLP");


  MOVE(1);
  accu1 = 0.0;

  PTR_INIT(1); /* pointer for realBuf[]  */
  ADD(1); LOOP(1);
  for ( j = 0; j < len - 1; j++ ) {

    MAC(1);
    accu1 += realBuf[j-1] * realBuf[j-1];
  }

  MULT(1);
  accu2 = realBuf[-2] * realBuf[-2];

  ADD(1);
  accu2 += accu1;

  MAC(1);
  accu1 += realBuf[j-1] * realBuf[j-1];

  MOVE(2);
  ac->r11r = accu1;
  ac->r22r = accu2;


  MOVE(1);
  accu1 = 0.0;

  PTR_INIT(1); /* pointer for realBuf[] */
  LOOP(1);
  for ( j = 0; j < len - 1; j++ ) {

    MAC(1);
    accu1 += realBuf[j] * realBuf[j-1];
  }

  MULT(1);
  accu2 = realBuf[-1] * realBuf[-2];

  ADD(1);
  accu2 += accu1;

  MAC(1);
  accu1 += realBuf[j] * realBuf[j-1];

  MOVE(2);
  ac->r01r = accu1;
  ac->r12r = accu2;


  MOVE(1);
  accu1=0.0;

  PTR_INIT(1); /* pointer for realBuf[] */
  LOOP(1);
  for ( j = 0; j < len; j++ ) {

    MAC(1);
    accu1 += realBuf[j] * realBuf[j-2];
  }

  MOVE(1);
  ac->r02r = accu1;

  MULT(2); ADD(1); STORE(1);
  ac->det = ac->r11r * ac->r22r - ac->r12r * ac->r12r;

  MOVE(3);
  ac->r01i = ac->r02i = ac->r12i = 0.0f;

  INDIRECT(10); MOVE(10); /* move all register variables to the structure ac->... */

  COUNT_sub_end();
}
Пример #19
0
/*!
 
  \brief  create and initialize a handle for stereo preprocessing
 
  \return an error state
 
****************************************************************************/
int InitStereoPreProcessing(HANDLE_STEREO_PREPRO hStPrePro, /*! handle (modified) */
                            int nChannels,    /*! number of channels */ 
                            int bitRate,      /*! the bit rate */
                            int sampleRate,   /*! the sample rate */
                            float usedScfRatio /*! the amount of scalefactors used (0-1.0) */
                            )
{
  float bpf = bitRate*1024.0f/sampleRate;
  float tmp;
  
  COUNT_sub_start("InitStereoPreProcessing");

  MULT(1); DIV(1); /* counting previous operation */

  FUNC(2); LOOP(1); PTR_INIT(1); MOVE(1); STORE(sizeof(struct STEREO_PREPRO));
  memset(hStPrePro,0,sizeof(struct STEREO_PREPRO));
  
  ADD(1); BRANCH(1);
  if(nChannels == 2) {

    INDIRECT(1); MOVE(1);
    (hStPrePro)->stereoAttenuationFlag = 1;


    INDIRECT(1); MULT(1); DIV(1); STORE(1);
    (hStPrePro)->normPeFac    = 230.0f * usedScfRatio / bpf;

    INDIRECT(1); DIV(2); MULT(1); ADD(2); BRANCH(1); MOVE(1);
    (hStPrePro)->ImpactFactor = max (1, 400000.0f / (float) (bitRate - sampleRate*sampleRate/72000.0f) );

    INDIRECT(2); DIV(3); MULT(2); STORE(2);
    (hStPrePro)->stereoAttenuationInc = 22050.0f / sampleRate * 400.0f / bpf;
    (hStPrePro)->stereoAttenuationDec = 22050.0f / sampleRate * 200.0f / bpf;

    INDIRECT(2); MOVE(2);
    (hStPrePro)->ConstAtt     = 0.0f;
    (hStPrePro)->stereoAttMax = 12.0f;

    /* energy ratio thresholds (dB) */
    INDIRECT(4); MOVE(4);
    (hStPrePro)->SMMin = 0.0f;
    (hStPrePro)->SMMax = 15.0f;
    (hStPrePro)->LRMin = 10.0f;
    (hStPrePro)->LRMax = 30.0f;

    /* pe thresholds */
    INDIRECT(3); MOVE(3);
    (hStPrePro)->PeCrit =  1200.0f; 
    (hStPrePro)->PeMin  =  700.0f;
    (hStPrePro)->PeImpactMax = 100.0f;  

    /* init start values */
    INDIRECT(8); MOVE(8);
    (hStPrePro)->avrgFreqEnergyL  = 0.0f;
    (hStPrePro)->avrgFreqEnergyR  = 0.0f;
    (hStPrePro)->avrgFreqEnergyS  = 0.0f;
    (hStPrePro)->avrgFreqEnergyM  = 0.0f;
    (hStPrePro)->smoothedPeSumSum = 7000.0f; /* typical start value */
    (hStPrePro)->avgStoM          = -10.0f;  /* typical start value */
    (hStPrePro)->lastLtoR         = 0.0f;
    (hStPrePro)->lastNrgLR        = 0.0f;

    DIV(1); ADD(1);
    tmp = 1.0f - (bpf / 2600.0f);

    BRANCH(1); MOVE(1);
    tmp = max (tmp, 0.0f);
    
    INDIRECT(2); MULT(1); STORE(1);
    (hStPrePro)->stereoAttenuation =  tmp * (hStPrePro)->stereoAttMax;
  }

  COUNT_sub_end();

  return 0;
}
Пример #20
0
/*!
 
  \brief  do an appropriate attenuation on the side channel of a stereo
          signal
 
  \return nothing
 
****************************************************************************/
void ApplyStereoPreProcess(HANDLE_STEREO_PREPRO hStPrePro, /*!st.-preproc handle */
                           int                 nChannels, /*! total number of channels */              
                           ELEMENT_INFO        *elemInfo,
                           float *timeData,     /*! lr time data (modified) */
                           int granuleLen) /*! num. samples to be processed */
{
  /* inplace operation on inData ! */

  float SMRatio, StoM;
  float LRRatio, LtoR, deltaLtoR, deltaNrg;
  float EnImpact, PeImpact, PeNorm;
  float Att, AttAimed;
  float maxInc, maxDec, swiftfactor;
  float DELTA=0.1f;
  
  float fac = hStPrePro->stereoAttFac;
  float mPart, upper, div;
  float lFac,rFac;

  int i;

  COUNT_sub_start("ApplyStereoPreProcess");

  INDIRECT(1); MOVE(2); /* counting previous operations */

  INDIRECT(1); BRANCH(1);
  if (!hStPrePro->stereoAttenuationFlag) {
    COUNT_sub_end();
    return;
  }

  
  /* calc L/R ratio */
  INDIRECT(1); MULT(3); ADD(1);
  mPart = 2.0f * hStPrePro->avrgFreqEnergyM * (1.0f - fac*fac);

  INDIRECT(2); ADD(4); MULT(2); MAC(2);
  upper = hStPrePro->avrgFreqEnergyL * (1.0f+fac) + hStPrePro->avrgFreqEnergyR * (1.0f-fac) - mPart;
  div   = hStPrePro->avrgFreqEnergyR * (1.0f+fac) + hStPrePro->avrgFreqEnergyL * (1.0f-fac) - mPart;
  
  LOGIC(1); BRANCH(1);
  if (div == 0.0f || upper == 0.0f) {

    INDIRECT(1); MOVE(1);
    LtoR = hStPrePro->LRMax;
  }
  else {

    DIV(1); MISC(1);
    LRRatio = (float) fabs ( upper / div ) ;

    TRANS(1); MULT(1); MISC(1);
    LtoR = (float) fabs(10.0 * log10(LRRatio));
  }
  

  /* calc delta energy to previous frame */
  INDIRECT(3); ADD(3); DIV(1);
  deltaNrg = ( hStPrePro->avrgFreqEnergyL + hStPrePro->avrgFreqEnergyR + 1.0f) / 
             ( hStPrePro->lastNrgLR + 1.0f );

  TRANS(1); MULT(1); MISC(1);
  deltaNrg = (float) (fabs(10.0 * log10(deltaNrg)));
  
  

  /* Smooth S/M over time */
  INDIRECT(2); ADD(2); DIV(1);
  SMRatio = (hStPrePro->avrgFreqEnergyS + 1.0f) / (hStPrePro->avrgFreqEnergyM + 1.0f);

  TRANS(1); MULT(1);
  StoM = (float) (10.0 * log10(SMRatio));

  INDIRECT(2); MULT(1); MAC(1); STORE(1);
  hStPrePro->avgStoM = DELTA * StoM + (1-DELTA) * hStPrePro->avgStoM;
  
  

  MOVE(1);
  EnImpact = 1.0f;
  
  INDIRECT(2); ADD(1); BRANCH(1);
  if (hStPrePro->avgStoM > hStPrePro->SMMin) {

    INDIRECT(1); ADD(1); BRANCH(1);
    if (hStPrePro->avgStoM > hStPrePro->SMMax) {

      MOVE(1);
      EnImpact = 0.0f;
    }
    else {

      ADD(2); DIV(1);
      EnImpact = (hStPrePro->SMMax - hStPrePro->avgStoM) / (hStPrePro->SMMax - hStPrePro->SMMin);
    }
  }
  
  INDIRECT(1); ADD(1); BRANCH(1);
  if (LtoR > hStPrePro->LRMin) {

    INDIRECT(1); ADD(1); BRANCH(1);
    if ( LtoR > hStPrePro->LRMax) {

      MOVE(1);
      EnImpact = 0.0f;
    }
    else {

      ADD(2); DIV(1); MULT(1);
      EnImpact *= (hStPrePro->LRMax - LtoR) / (hStPrePro->LRMax - hStPrePro->LRMin);
    }
  }
  
  
  MOVE(1);
  PeImpact = 0.0f;
  
  INDIRECT(2); MULT(1);
  PeNorm = hStPrePro->smoothedPeSumSum * hStPrePro->normPeFac;
  
  INDIRECT(1); ADD(1); BRANCH(1);
  if ( PeNorm > hStPrePro->PeMin )  {

    INDIRECT(1); ADD(2); DIV(1);
    PeImpact= ((PeNorm - hStPrePro->PeMin) / (hStPrePro->PeCrit - hStPrePro->PeMin));
  }
  
  INDIRECT(1); ADD(1); BRANCH(1);
  if (PeImpact > hStPrePro->PeImpactMax) {

    MOVE(1);
    PeImpact = hStPrePro->PeImpactMax;
  }
  
  
  INDIRECT(1); MULT(2);
  AttAimed = EnImpact * PeImpact * hStPrePro->ImpactFactor;
  
  
  INDIRECT(1); ADD(1); BRANCH(1);
  if (AttAimed > hStPrePro->stereoAttMax) {

    MOVE(1);
    AttAimed = hStPrePro->stereoAttMax;
  }
  
  /* only accept changes if they are large enough */

  INDIRECT(1); ADD(2); MISC(1); LOGIC(1); BRANCH(1);
  if ( fabs(AttAimed - hStPrePro->stereoAttenuation) < 1.0f && AttAimed != 0.0f) {

    MOVE(1);
    AttAimed = hStPrePro->stereoAttenuation;
  }
  
  MOVE(1);
  Att = AttAimed;


  INDIRECT(1); ADD(1); MULT(1); BRANCH(1); /* max() */ ADD(2); DIV(1); MULT(1);
  swiftfactor = (6.0f + hStPrePro->stereoAttenuation) / (10.0f + LtoR) * max(1.0f, 0.2f * deltaNrg );
  
  INDIRECT(1); ADD(2); BRANCH(1); MOVE(1);
  deltaLtoR = max(3.0f, LtoR - hStPrePro->lastLtoR );
  
  MULT(2); DIV(1);
  maxDec = deltaLtoR * deltaLtoR / 9.0f * swiftfactor;
  
  ADD(1); BRANCH(1); MOVE(1);
  maxDec = min( maxDec, 5.0f );
  
  INDIRECT(1); MULT(1);
  maxDec *= hStPrePro->stereoAttenuationDec;
  
  
  INDIRECT(1); MULT(1); ADD(1); BRANCH(1);
  if (maxDec > hStPrePro->stereoAttenuation * 0.8f) {
    
    MOVE(1);
    maxDec = hStPrePro->stereoAttenuation * 0.8f;
  }
  
  INDIRECT(1); ADD(2); BRANCH(1); MOVE(1);
  deltaLtoR = max(3.0f, hStPrePro->lastLtoR - LtoR );
  
  MULT(2); DIV(1);
  maxInc = deltaLtoR * deltaLtoR / 9.0f * swiftfactor;
  
  ADD(1); BRANCH(1); MOVE(1);
  maxInc = min( maxInc, 5.0f );
  
  INDIRECT(1); MULT(1);
  maxInc *= hStPrePro->stereoAttenuationInc;
  
  
  INDIRECT(1); MULT(1); ADD(1); BRANCH(1);
  if (maxDec > hStPrePro->stereoAttenuation * 0.8f) {
    
    MOVE(1);
    maxDec = hStPrePro->stereoAttenuation * 0.8f;
  }
  
  INDIRECT(1); ADD(2); BRANCH(1); MOVE(1);
  deltaLtoR = max(3.0f, hStPrePro->lastLtoR - LtoR );
  
  MULT(2); DIV(1);
  maxInc = deltaLtoR * deltaLtoR / 9.0f * swiftfactor;
  
  ADD(1); BRANCH(1); MOVE(1);
  maxInc = min( maxInc, 5.0f );
  
  INDIRECT(1); MULT(1);
  maxInc *= hStPrePro->stereoAttenuationInc;
  
  
  INDIRECT(1); ADD(2); BRANCH(1);
  if (Att > hStPrePro->stereoAttenuation + maxInc) {

    MOVE(1);
    Att = hStPrePro->stereoAttenuation + maxInc;
  }

  INDIRECT(1); ADD(2); BRANCH(1);
  if (Att < hStPrePro->stereoAttenuation - maxDec) {

    MOVE(1);
    Att = hStPrePro->stereoAttenuation - maxDec;
  }
  
  INDIRECT(2); BRANCH(1); MOVE(1);
  if (hStPrePro->ConstAtt == 0) hStPrePro->stereoAttenuation = Att;
  else                          hStPrePro->stereoAttenuation = hStPrePro->ConstAtt;
  

  /* perform attenuation of Side Channel */
  
  INDIRECT(2); MULT(1); TRANS(1); STORE(1);
  hStPrePro->stereoAttFac = (float) pow(10.0f, 0.05f*(-hStPrePro->stereoAttenuation ));
  
  INDIRECT(1); ADD(2); MULT(2);
  lFac = 0.5f * (1.0f + hStPrePro->stereoAttFac);
  rFac = 0.5f * (1.0f - hStPrePro->stereoAttFac);
  
  PTR_INIT(2); /* pointer for timeData[nChannels * i + elemInfo->ChannelIndex[0]], 
                              timeData[nChannels * i + elemInfo->ChannelIndex[1]]
               */
  LOOP(1);
  for (i = 0; i < granuleLen; i++){
    float L = lFac * timeData[nChannels * i+elemInfo->ChannelIndex[0]] + rFac * timeData[nChannels * i + elemInfo->ChannelIndex[1]];
    float R = rFac * timeData[nChannels * i+elemInfo->ChannelIndex[0]] + lFac * timeData[nChannels * i + elemInfo->ChannelIndex[1]];

    MULT(2); MAC(2); /* counting operations above */
    
    MOVE(2);
    timeData[nChannels * i + elemInfo->ChannelIndex[0]]= L;
    timeData[nChannels * i + elemInfo->ChannelIndex[1]]= R;
  }
  
  INDIRECT(1); MOVE(1);
  hStPrePro->lastLtoR = LtoR;

  INDIRECT(3); ADD(1); STORE(1);
  hStPrePro->lastNrgLR = hStPrePro->avrgFreqEnergyL + hStPrePro->avrgFreqEnergyR;
  
  COUNT_sub_end();
}
GLOBAL Int UMFPACK_get_determinant
(
    double *Mx,
#ifdef COMPLEX
    double *Mz,
#endif
    double *Ex,
    void *NumericHandle,
    double User_Info [UMFPACK_INFO]
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Entry d_mantissa, d_tmp ;
    double d_exponent, Info2 [UMFPACK_INFO], one [2] = {1.0, 0.0}, d_sign ;
    Entry *D ;
    double *Info, *Rs ;
    NumericType *Numeric ;
    Int i, n, itmp, npiv, *Wi, *Rperm, *Cperm, do_scale ;

#ifndef NRECIPROCAL
    Int do_recip ;
#endif

    /* ---------------------------------------------------------------------- */
    /* check input parameters */
    /* ---------------------------------------------------------------------- */

    if (User_Info != (double *) NULL)
    {
	/* return Info in user's array */
	Info = User_Info ;
    }
    else
    {
	/* no Info array passed - use local one instead */
	Info = Info2 ;
	for (i = 0 ; i < UMFPACK_INFO ; i++)
	{
	    Info [i] = EMPTY ;
	}
    }

    Info [UMFPACK_STATUS] = UMFPACK_OK ;

    Numeric = (NumericType *) NumericHandle ;
    if (!UMF_valid_numeric (Numeric))
    {
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_invalid_Numeric_object ;
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    if (Numeric->n_row != Numeric->n_col)
    {
	/* only square systems can be handled */
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_invalid_system ;
	return (UMFPACK_ERROR_invalid_system) ;
    }

    if (Mx == (double *) NULL)
    {
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_argument_missing ;
	return (UMFPACK_ERROR_argument_missing) ;
    }

    n = Numeric->n_row ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    Wi = (Int *) UMF_malloc (n, sizeof (Int)) ;

    if (!Wi)
    {
	DEBUGm4 (("out of memory: get determinant\n")) ;
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_out_of_memory ;
	return (UMFPACK_ERROR_out_of_memory) ;
    }

    /* ---------------------------------------------------------------------- */
    /* compute the determinant */
    /* ---------------------------------------------------------------------- */

    Rs = Numeric->Rs ;		/* row scale factors */
    do_scale = (Rs != (double *) NULL) ;

#ifndef NRECIPROCAL
    do_recip = Numeric->do_recip ;
#endif

    d_mantissa = ((Entry *) one) [0] ;
    d_exponent = 0.0 ;
    D = Numeric->D ;

    /* compute product of diagonal entries of U */
    for (i = 0 ; i < n ; i++)
    {
	MULT (d_tmp, d_mantissa, D [i]) ;
	d_mantissa = d_tmp ;

	if (!rescale_determinant (&d_mantissa, &d_exponent))
	{
	    /* the determinant is zero or NaN */
	    Info [UMFPACK_STATUS] = UMFPACK_WARNING_singular_matrix ;
	    /* no need to compute the determinant of R */
	    do_scale = FALSE ;
	    break ;
	}
    }

    /* compute product of diagonal entries of R (or its inverse) */
    if (do_scale)
    {
	for (i = 0 ; i < n ; i++)
	{
#ifndef NRECIPROCAL
	    if (do_recip)
	    {
		/* compute determinant of R inverse */
		SCALE_DIV (d_mantissa, Rs [i]) ;
	    }
	    else
#endif
	    {
		/* compute determinant of R */
		SCALE (d_mantissa, Rs [i]) ;
	    }
	    if (!rescale_determinant (&d_mantissa, &d_exponent))
	    {
		/* the determinant is zero or NaN.  This is very unlikey to
		 * occur here, since the scale factors for a tiny or zero row
		 * are set to 1. */
		Info [UMFPACK_STATUS] = UMFPACK_WARNING_singular_matrix ;
		break ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* determine if P and Q are odd or even permutations */
    /* ---------------------------------------------------------------------- */

    npiv = 0 ;
    Rperm = Numeric->Rperm ;

    for (i = 0 ; i < n ; i++)
    {
	Wi [i] = Rperm [i] ;
    }

    for (i = 0 ; i < n ; i++)
    {
	while (Wi [i] != i)
	{
	    itmp = Wi [Wi [i]] ;
	    Wi [Wi [i]] = Wi [i] ;
	    Wi [i] = itmp ;
	    npiv++ ;
	}
    }

    Cperm = Numeric->Cperm ;

    for (i = 0 ; i < n ; i++)
    {
	Wi [i] = Cperm [i] ;
    }

    for (i = 0 ; i < n ; i++)
    {
	while (Wi [i] != i)
	{
	    itmp = Wi [Wi [i]] ;
	    Wi [Wi [i]] = Wi [i] ;
	    Wi [i] = itmp ;
	    npiv++ ;
	}
    }

    /* if npiv is odd, the sign is -1.  if it is even, the sign is +1 */
    d_sign = (npiv % 2) ? -1. : 1. ;

    /* ---------------------------------------------------------------------- */
    /* free workspace */
    /* ---------------------------------------------------------------------- */

    (void) UMF_free ((void *) Wi) ;

    /* ---------------------------------------------------------------------- */
    /* compute the magnitude and exponent of the determinant */
    /* ---------------------------------------------------------------------- */

    if (Ex == (double *) NULL)
    {
	/* Ex is not provided, so return the entire determinant in d_mantissa */
	SCALE (d_mantissa, pow (10.0, d_exponent)) ;
    }
    else
    {
	Ex [0] = d_exponent ;
    }

    Mx [0] = d_sign * REAL_COMPONENT (d_mantissa) ;

#ifdef COMPLEX
    if (SPLIT (Mz))
    {
	Mz [0] = d_sign * IMAG_COMPONENT (d_mantissa) ;
    }
    else
    {
	Mx [1] = d_sign * IMAG_COMPONENT (d_mantissa) ;
    }
#endif

    /* determine if the determinant has (or will) overflow or underflow */
    if (d_exponent + 1.0 > log10 (DBL_MAX))
    {
	Info [UMFPACK_STATUS] = UMFPACK_WARNING_determinant_overflow ;
    }
    else if (d_exponent - 1.0 < log10 (DBL_MIN))
    {
	Info [UMFPACK_STATUS] = UMFPACK_WARNING_determinant_underflow ;
    }

    return (UMFPACK_OK) ;
}
Пример #22
0
/* reduce minSnr requirements for bands with relative low energies */
static void adaptMinSnr(PSY_OUT_CHANNEL     psyOutChannel[MAX_CHANNELS],
                        MINSNR_ADAPT_PARAM *msaParam,
                        const int           nChannels)
{
  int ch, sfb, sfbOffs, nSfb;
  float avgEn, dbRatio, minSnrRed;

  COUNT_sub_start("adaptMinSnr");

  LOOP(1);
  for (ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL* psyOutChan = &psyOutChannel[ch];

    PTR_INIT(1); /* counting operation above */

    /* calc average energy per scalefactor band */
    MOVE(2);
    avgEn = 0.0f;
    nSfb = 0;

    INDIRECT(2); LOOP(1);
    for (sfbOffs=0; 
         sfbOffs<psyOutChan->sfbCnt;
         sfbOffs+=psyOutChan->sfbPerGroup) {

      PTR_INIT(1); /* pointer for psyOutChan->sfbEnergy[] */
      INDIRECT(1); LOOP(1);
      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {

        ADD(1);
        avgEn += psyOutChan->sfbEnergy[sfbOffs+sfb];

        ADD(1);
        nSfb++;
      }
    }

    BRANCH(1);
    if (nSfb > 0) {

      DIV(1);
      avgEn /= nSfb;
    }

    /* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */
    INDIRECT(2); LOOP(1);
    for (sfbOffs=0; 
         sfbOffs<psyOutChan->sfbCnt;
         sfbOffs+=psyOutChan->sfbPerGroup) {

      PTR_INIT(2); /* pointer for psyOutChan->sfbEnergy[],
                                  psyOutChan->sfbMinSnr[]
                   */
      INDIRECT(1); LOOP(1);
      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {

        INDIRECT(1); MULT(1); ADD(1); BRANCH(1);
        if (msaParam->startRatio*psyOutChan->sfbEnergy[sfbOffs+sfb] < avgEn) {

          ADD(2); DIV(1); TRANS(1); MULT(1);
          dbRatio = (float) (10.0*log10((FLT_MIN+avgEn) /
                                        (FLT_MIN+psyOutChan->sfbEnergy[sfbOffs+sfb])));

          INDIRECT(1); MULT(1); ADD(1);
          minSnrRed = msaParam->redOffs + msaParam->redRatioFac * dbRatio;

          INDIRECT(1); ADD(1); BRANCH(1); MOVE(1);
          minSnrRed = max(minSnrRed, msaParam->maxRed);

          TRANS(1); STORE(1);
          psyOutChan->sfbMinSnr[sfbOffs+sfb] =
            (float)pow(psyOutChan->sfbMinSnr[sfbOffs+sfb], minSnrRed);

          ADD(1); BRANCH(1); MOVE(1);
          psyOutChan->sfbMinSnr[sfbOffs+sfb] =
            min(minSnrLimit, psyOutChan->sfbMinSnr[sfbOffs+sfb]);
        }
      }
    }

  }

  COUNT_sub_end();
}
Пример #23
0
static void allowMoreHoles(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS], 
                           PSY_OUT_ELEMENT *psyOutElement,
                           PE_DATA *peData, 
                           int ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                           const AH_PARAM *ahParam,
                           const int nChannels,
                           const float desiredPe)
{
  int ch, sfb;
  float actPe;

  COUNT_sub_start("allowMoreHoles");

  INDIRECT(1); MOVE(1);
  actPe = peData->pe;

  ADD(2); LOGIC(1); BRANCH(1);
  if (nChannels==2 &&
      psyOutChannel[0].windowSequence==psyOutChannel[1].windowSequence) {
    PSY_OUT_CHANNEL *psyOutChanL = &psyOutChannel[0];
    PSY_OUT_CHANNEL *psyOutChanR = &psyOutChannel[1];

    PTR_INIT(2); /* counting previous operations */

    PTR_INIT(11); /* pointers for ahFlag[0][sfb],
                                  ahFlag[1][sfb],
                                  psyOutElement->toolsInfo.msMask[sfb],
                                  psyOutChanL->sfbMinSnr[sfb],
                                  psyOutChanR->sfbMinSnr[sfb],
                                  psyOutChanL->sfbEnergy[sfb],
                                  psyOutChanR->sfbEnergy[sfb],
                                  psyOutChanL->sfbThreshold[sfb],
                                  psyOutChanR->sfbThreshold[sfb],
                                  peData->peChannelData[0].sfbPe[sfb],
                                  peData->peChannelData[1].sfbPe[sfb]
                  */
    INDIRECT(1); LOOP(1);
    for (sfb=0; sfb<psyOutChanL->sfbCnt; sfb++) {

      BRANCH(1);
      if (psyOutElement->toolsInfo.msMask[sfb]) {

        ADD(2); MULT(2); LOGIC(1); BRANCH(1);
        if (ahFlag[1][sfb] != NO_AH &&
            0.4f*psyOutChanL->sfbMinSnr[sfb]*psyOutChanL->sfbEnergy[sfb] >
            psyOutChanR->sfbEnergy[sfb]) {

          MOVE(1);
          ahFlag[1][sfb] = NO_AH;

          MULT(1); STORE(1);
          psyOutChanR->sfbThreshold[sfb] = 2.0f * psyOutChanR->sfbEnergy[sfb];

          ADD(1);
          actPe -= peData->peChannelData[1].sfbPe[sfb];
        }
        else {
          ADD(2); MULT(2); LOGIC(1); BRANCH(1);
          if (ahFlag[0][sfb] != NO_AH &&
            0.4f*psyOutChanR->sfbMinSnr[sfb]*psyOutChanR->sfbEnergy[sfb] >
            psyOutChanL->sfbEnergy[sfb]) {

          MOVE(1);
          ahFlag[0][sfb] = NO_AH;

          MULT(1); STORE(1);
          psyOutChanL->sfbThreshold[sfb] = 2.0f * psyOutChanL->sfbEnergy[sfb];

          ADD(1);
          actPe -= peData->peChannelData[0].sfbPe[sfb];
          }
        }
        ADD(1); BRANCH(1);
        if (actPe < desiredPe)
          break;
      }
    }
  }

  ADD(1); BRANCH(1);
  if (actPe > desiredPe) {
    int startSfb[2];
    float avgEn, minEn;
    int ahCnt;
    int enIdx;
    float en[4];
    int minSfb, maxSfb;
    int done;

    PTR_INIT(2); /* pointers for psyOutChannel[ch].windowSequence,
                                 startSfb[ch]
                 */
    LOOP(1);
    for (ch=0; ch<nChannels; ch++) {

      ADD(1); BRANCH(1); INDIRECT(1); MOVE(1);
      if (psyOutChannel[ch].windowSequence != SHORT_WINDOW)
        startSfb[ch] = ahParam->startSfbL;
      else
        startSfb[ch] = ahParam->startSfbS;
    }

    MOVE(3);
    avgEn = 0.0f;
    minEn = FLT_MAX;
    ahCnt = 0;

    PTR_INIT(1); /* pointers for startSfb[ch] */
    LOOP(1);
    for (ch=0; ch<nChannels; ch++) {
      PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];

      PTR_INIT(1); /* counting previous operation */

      PTR_INIT(4); /* pointers for ahFlag[ch][sfb],
                                   psyOutChan->sfbMinSnr[sfb],
                                   psyOutChan->sfbEnergy[sfb],
                                   psyOutChan->sfbThreshold[sfb],
                   */
      INDIRECT(1); LOOP(1);
      for (sfb=startSfb[ch]; sfb<psyOutChan->sfbCnt; sfb++){

        ADD(2); LOGIC(1); BRANCH(1);
        if ((ahFlag[ch][sfb]!=NO_AH) &&
            (psyOutChan->sfbEnergy[sfb] > psyOutChan->sfbThreshold[sfb])){

          ADD(1); BRANCH(1); MOVE(1);
          minEn = min(minEn, psyOutChan->sfbEnergy[sfb]);

          ADD(1);
          avgEn += psyOutChan->sfbEnergy[sfb];

          ADD(1);
          ahCnt++;
        }
      }
    }
    ADD(1); BRANCH(1); MOVE(1); /* min() */ ADD(1); DIV(1);
    avgEn = min ( FLT_MAX , avgEn /(ahCnt+FLT_MIN));

    /* calc some energy borders between minEn and avgEn */
    PTR_INIT(1); /* pointers for en[enIdx] */
    LOOP(1);
    for (enIdx=0; enIdx<4; enIdx++) {
      ADD(2); MULT(2); DIV(2); TRANS(1); STORE(1);
      en[enIdx] = minEn * (float)pow(avgEn/(minEn+FLT_MIN), (2*enIdx+1)/7.0f);
    }

    ADD(1);
    maxSfb = psyOutChannel[0].sfbCnt - 1;

    MOVE(1);
    minSfb = startSfb[0];

    ADD(1); BRANCH(1);
    if (nChannels==2) {

      ADD(2); BRANCH(1); MOVE(1);
      maxSfb = max(maxSfb, psyOutChannel[1].sfbCnt-1);

      ADD(1); BRANCH(1); MOVE(1);
      minSfb = min(minSfb, startSfb[1]);
    }

    MOVE(3);
    sfb = maxSfb;
    enIdx = 0;
    done = 0;

    LOOP(1);
    while (!done) {

      PTR_INIT(1); /* pointer for en[enIdx] */

      LOOP(1);
      for (ch=0; ch<nChannels; ch++) {
        PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];

        PTR_INIT(1); /* counting previous operation */

        PTR_INIT(4); /* pointers for startSfb[ch]
                                     ahFlag[ch][sfb],
                                     psyOutChan->sfbEnergy[sfb],
                                     psyOutChan->sfbThreshold[sfb]
                     */

        INDIRECT(1); ADD(2); LOGIC(1); BRANCH(1);
        if (sfb>=startSfb[ch] && sfb < psyOutChan->sfbCnt) {

          ADD(2); LOGIC(1); BRANCH(1);
          if (ahFlag[ch][sfb] != NO_AH && psyOutChan->sfbEnergy[sfb] < en[enIdx]){
            
            MOVE(1);
            ahFlag[ch][sfb] = NO_AH;
            
            MULT(1); STORE(1);
            psyOutChan->sfbThreshold[sfb] = 2.0f * psyOutChan->sfbEnergy[sfb];
            
            ADD(1);
            actPe -= peData->peChannelData[ch].sfbPe[sfb];
          }

          ADD(1); BRANCH(1);
          if (actPe < desiredPe) {
            
            MOVE(1);
            done = 1;
            break;
          }
        }
      }
      ADD(1);
      sfb--;

      ADD(1); BRANCH(1);
      if (sfb < minSfb) {
        MOVE(1);
        sfb = maxSfb;

        ADD(1);
        enIdx++;

        ADD(1); BRANCH(1);
        if (enIdx >= 4) {

          MOVE(1);
          done = 1;
        }
      }
    }
  }

  COUNT_sub_end();
}
Пример #24
0
static void reduceMinSnr(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                         PE_DATA *peData, 
                         int ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                         const int nChannels,
                         const float desiredPe)
{
  int ch, sfb, sfbSubWin;
  float deltaPe;

  COUNT_sub_start("reduceMinSnr");

  /* start at highest freq down to 0 */
  MOVE(1);
  sfbSubWin = psyOutChannel[0].maxSfbPerGroup;
  
  PTR_INIT(7); /* pointer for ahFlag[ch][sfb],
                  psyOutChannel[ch].sfbMinSnr[sfb],
                  psyOutChannel[ch].sfbThreshold[sfb],
                  psyOutChannel[ch].sfbEnergy[sfb],
                  peData->peChannelData[ch].sfbNLines[sfb],
                  peData->peChannelData[ch].sfbPe[sfb],
                  peData->peChannelData[ch].pe
               */
  INDIRECT(1); LOOP(1);
  while (peData->pe > desiredPe && sfbSubWin > 0) {
    ADD(1); LOGIC(1); /* while() condition */
    
    ADD(1);
    sfbSubWin--;
    
    /* loop over all subwindows */
    LOOP(1);
    for (sfb=sfbSubWin; sfb<psyOutChannel[0].sfbCnt;
         sfb+=psyOutChannel[0].sfbPerGroup) {
      
      /* loop over all channels */
      LOOP(1);
      for (ch=0; ch<nChannels; ch++) {
        
        ADD(2); BRANCH(1);
        if (ahFlag[ch][sfb] != NO_AH &&
            psyOutChannel[ch].sfbMinSnr[sfb] < minSnrLimit) {
          
          MOVE(1);
          psyOutChannel[ch].sfbMinSnr[sfb] = minSnrLimit;
          
          MULT(1); STORE(1);
          psyOutChannel[ch].sfbThreshold[sfb] =
            psyOutChannel[ch].sfbEnergy[sfb] * psyOutChannel[ch].sfbMinSnr[sfb];
          
          MULT(1); ADD(1);
          deltaPe = peData->peChannelData[ch].sfbNLines[sfb] * 1.5f -
            peData->peChannelData[ch].sfbPe[sfb];
          
          INDIRECT(1); ADD(1); STORE(1);
          peData->pe += deltaPe;
          
          ADD(1); STORE(1);
          peData->peChannelData[ch].pe += deltaPe;
        }
      }
      
      INDIRECT(1); ADD(1); BRANCH(1);
      if (peData->pe <= desiredPe)
        break;
    }
  }
  
  COUNT_sub_end();
}
Пример #25
0
static void correctThresh(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                          int ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                          PE_DATA *peData,
                          float thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
                          const float redVal,
                          const int nChannels,
                          const float deltaPe)
{
   int ch, sfb,sfbGrp;
   PSY_OUT_CHANNEL *psyOutChan;
   PE_CHANNEL_DATA *peChanData;
   float deltaSfbPe;
   float thrFactor;
   float sfbPeFactors[MAX_CHANNELS][MAX_GROUPED_SFB], normFactor;
   float sfbEn, sfbThr, sfbThrReduced;

   COUNT_sub_start("correctThresh");

   /* for each sfb calc relative factors for pe changes */
   MOVE(1);
   normFactor = FLT_MIN; /* to avoid division by zero */

   LOOP(1);
   for(ch=0; ch<nChannels; ch++) {
      psyOutChan = &psyOutChannel[ch];
      peChanData = &peData->peChannelData[ch];

      INDIRECT(1); PTR_INIT(2); /* counting previous operations */

      INDIRECT(2); LOOP(1);
      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){

        PTR_INIT(4); /* pointers for ahFlag[ch][sfbGrp+sfb],
                                     thrExp[ch][sfbGrp+sfb],
                                     sfbPeFactors[ch][sfbGrp+sfb],
                                     peChanData->sfbNActiveLines[sfbGrp+sfb]
                     */
        INDIRECT(1); LOOP(1);
        for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {

         ADD(1); LOGIC(1); BRANCH(1);
         if ((ahFlag[ch][sfbGrp+sfb] < AH_ACTIVE) || (deltaPe > 0)) {

            ADD(1); DIV(1); STORE(1);
            sfbPeFactors[ch][sfbGrp+sfb] = peChanData->sfbNActiveLines[sfbGrp+sfb] /
                                              (thrExp[ch][sfbGrp+sfb] + redVal);

            ADD(1);
            normFactor += sfbPeFactors[ch][sfbGrp+sfb];
         }
         else {
            MOVE(1);
            sfbPeFactors[ch][sfbGrp+sfb] = 0.0f;
         }
        }
      }
   }

   DIV(1);
   normFactor = 1.0f/normFactor;

   LOOP(1);
   for(ch=0; ch<nChannels; ch++) {
      psyOutChan = &psyOutChannel[ch];
      peChanData = &peData->peChannelData[ch];

      INDIRECT(1); PTR_INIT(2); /* counting previous operations */

      INDIRECT(2); LOOP(1);
      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){

        PTR_INIT(6); /* pointers for ahFlag[ch][sfbGrp+sfb],
                                     sfbPeFactors[ch][sfbGrp+sfb],
                                     psyOutChan->sfbMinSnr[sfbGrp+sfb],
                                     peChanData->sfbNActiveLines[sfbGrp+sfb],
                                     psyOutChan->sfbEnergy[sfbGrp+sfb],
                                     psyOutChan->sfbThreshold[sfbGrp+sfb]
                     */
        INDIRECT(1); LOOP(1);
        for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {

         /* pe difference for this sfb */
         MULT(2);
         deltaSfbPe = sfbPeFactors[ch][sfbGrp+sfb] * normFactor * deltaPe;

         ADD(1); BRANCH(1);
         if (peChanData->sfbNActiveLines[sfbGrp+sfb] > (float)0.5f) {

            /* new threshold */
            MOVE(2);
            sfbEn  = psyOutChan->sfbEnergy[sfbGrp+sfb];
            sfbThr = psyOutChan->sfbThreshold[sfbGrp+sfb];

            MULT(1); DIV(1); ADD(1); BRANCH(1); MOVE(1);
            thrFactor = min(-deltaSfbPe/peChanData->sfbNActiveLines[sfbGrp+sfb],20.f);

            TRANS(1);
            thrFactor = (float) pow(2.0f,thrFactor);

            MULT(1);
            sfbThrReduced = sfbThr * thrFactor;
            /* avoid hole */

            MULT(1); ADD(2); BRANCH(1);
            if ((sfbThrReduced > psyOutChan->sfbMinSnr[sfbGrp+sfb] * sfbEn) &&
                (ahFlag[ch][sfbGrp+sfb] == AH_INACTIVE)) {

               ADD(1); BRANCH(1); MOVE(1);
               sfbThrReduced = max(psyOutChan->sfbMinSnr[sfbGrp+sfb] * sfbEn, sfbThr);

               MOVE(1);
               ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE;
            }

            MOVE(1);
            psyOutChan->sfbThreshold[sfbGrp+sfb] = sfbThrReduced;
         }
        }
      }
   }

   COUNT_sub_end();
}
Пример #26
0
int main()
{
    int i;
    char strEntrada[200000];
    No *Raiz;
    pilha Pilha[10000];
    OP = (No*) malloc(sizeof(No));
    FILE *arq = fopen("string.in", "r");
    fscanf(arq,"%s",strEntrada);

    criaNo('@', &Raiz);
    Raiz = criaGrafo(strEntrada, Raiz);
    DecodificaOperacao(Raiz, Pilha);

    //for(i = 0; i<1; i++)
    while(Fim == 0 && Raiz->c != ':' && Raiz->c != '$')
    {
        OP = pop(Pilha);
        switch (OP->c)
        {
        case 'S':
            if(Verifica(3,Pilha, &Raiz))
            {
                S(Pilha, &Raiz);
                #ifdef CONT_FLAG
                    cont_S++;
                #endif
            }
            break;
        case 'K':
            K(Pilha, &Raiz);
            #ifdef CONT_FLAG
                cont_K++;
            #endif
            break;
        case 'B':
            if(Verifica(3,Pilha, &Raiz))
            {
                B(Pilha, &Raiz);
                #ifdef CONT_FLAG
                    cont_B++;
                #endif
            }
            break;
        case 'b':
            if(Verifica(3,Pilha, &Raiz))
            {
                BL(Pilha, &Raiz);
                #ifdef CONT_FLAG
                    cont_BL++;
                #endif
            }
            break;
        case 'P':
            if(Verifica(3,Pilha, &Raiz))
            {
                CL(Pilha, &Raiz);
                #ifdef CONT_FLAG
                    cont_CL++;
                #endif
            }
            break;
        case 'I':
            I(Pilha, &Raiz);
            #ifdef CONT_FLAG
                cont_I++;
            #endif
            break;
        case 'W':
            if(Verifica(3,Pilha, &Raiz))
            {
                SL(Pilha, &Raiz);
                #ifdef CONT_FLAG
                    cont_SL++;
                #endif
            }
            break;
        case 'C':
            if(Verifica(3,Pilha, &Raiz))
            {
                C(Pilha, &Raiz);
                #ifdef CONT_FLAG
                    cont_C++;
                #endif
            }
            break;
        case 'H': //Hd
            Hd(Pilha, &Raiz);
            break;
        case 'T': //Tl
            Tl(Pilha, &Raiz);
            break;
        case '*':
            MULT(Pilha, &Raiz);
            break;
        case '/':
            DIV(Pilha, &Raiz);
            break;
        case '-':
            SUB(Pilha, &Raiz);
            break;
        case '+':
            ADD(Pilha, &Raiz);
            break;
        case '^':
            POT(Pilha, &Raiz);
            break;
        default:
            Fim = 1;
            break;
        }
    }
    printf("Saida: ");
    printaGrafo(Raiz);
    printf("\n");
    printf("\nChamadas ao GC:%d\n", garbage);

#ifdef CONT_FLAG
    printf("S: %d\n",cont_S);
    printf("K: %d\n",cont_K);
    printf("I: %d\n",cont_I);
    printf("C: %d\n",cont_C);
    printf("B: %d\n",cont_B);
    printf("S': %d\n",cont_SL);
    printf("C': %d\n",cont_CL);
    printf("B': %d\n",cont_BL);
#endif

    return 0;
}
Пример #27
0
static void scfCount(const short *scalefacGain,
                     const unsigned short *maxValueInSfb,
                     SECTION_DATA * sectionData)

{
  /* counter */
  int i = 0; /* section counter */
  int j = 0; /* sfb counter */
  int k = 0; /* current section auxiliary counter */
  int m = 0; /* other section auxiliary counter */
  int n = 0; /* other sfb auxiliary counter */

  /* further variables */
  int lastValScf     = 0;
  int deltaScf       = 0;
  int found          = 0;
  int scfSkipCounter = 0;

  COUNT_sub_start("scfCount");

  MOVE(9); /* counting previous operations */

  INDIRECT(1); MOVE(1);
  sectionData->scalefacBits = 0;

  BRANCH(1);
  if (scalefacGain == NULL) {
    COUNT_sub_end();
    return;
  }

  INDIRECT(1); MOVE(2);
  lastValScf = 0;
  sectionData->firstScf = 0;

  PTR_INIT(1); /* sectionData->section[] */
  INDIRECT(1); LOOP(1);
  for (i = 0; i < sectionData->noOfSections; i++) {

    ADD(1); BRANCH(1);
    if (sectionData->section[i].codeBook != CODE_BOOK_ZERO_NO) {

      INDIRECT(1); MOVE(1);
      sectionData->firstScf = sectionData->section[i].sfbStart;

      INDIRECT(1); MOVE(1);
      lastValScf = scalefacGain[sectionData->firstScf];
      break;
    }
  }

  PTR_INIT(1); /* sectionData->section[] */
  INDIRECT(1); LOOP(1);
  for (i = 0; i < sectionData->noOfSections; i++) {

    ADD(2); LOGIC(1); BRANCH(1);
    if ((sectionData->section[i].codeBook != CODE_BOOK_ZERO_NO) &&
        (sectionData->section[i].codeBook != CODE_BOOK_PNS_NO)) {

      PTR_INIT(2); /* maxValueInSfb[]
                      scalefacGain[]
                   */
      ADD(1); LOOP(1);
      for (j = sectionData->section[i].sfbStart;
           j < sectionData->section[i].sfbStart + sectionData->section[i].sfbCnt;
           j++) {

        BRANCH(1);
        if (maxValueInSfb[j] == 0) {

          MOVE(1);
          found = 0;

          BRANCH(1);
          if (scfSkipCounter == 0) {

            ADD(3); BRANCH(1);
            if (j == (sectionData->section[i].sfbStart + sectionData->section[i].sfbCnt - 1) ) {

              MOVE(1);
              found = 0;
            }
            else {

              PTR_INIT(2); /* maxValueInSfb[]
                              scalefacGain[]
                           */
              LOOP(1);
              for (k = (j+1); k < sectionData->section[i].sfbStart + sectionData->section[i].sfbCnt; k++) {
                BRANCH(1);
                if (maxValueInSfb[k] != 0) {
                  MOVE(1);
                  found = 1;

                  ADD(2); MISC(1); BRANCH(1);
                  if ( (abs(scalefacGain[k] - lastValScf)) < CODE_BOOK_SCF_LAV) {
                    MOVE(1);
                    deltaScf = 0;
                  }
                  else {
                    ADD(1); MULT(1);
                    deltaScf = -(scalefacGain[j] - lastValScf);

                    MOVE(2);
                    lastValScf = scalefacGain[j];
                    scfSkipCounter = 0;
                  }
                  break;
                }
                /* count scalefactor skip */
                ADD(1);
                scfSkipCounter = scfSkipCounter + 1;
              }
            }

            /* search for the next maxValueInSfb[] != 0 in all other sections */
            PTR_INIT(1); /* sectionData->section[] */
            INDIRECT(1); LOOP(1);
            for (m = (i+1); (m < sectionData->noOfSections) && (found == 0); m++) {

              ADD(2); LOGIC(1); BRANCH(1);
              if ((sectionData->section[m].codeBook != CODE_BOOK_ZERO_NO) &&
                  (sectionData->section[m].codeBook != CODE_BOOK_PNS_NO)) {
                PTR_INIT(2); /* maxValueInSfb[]
                                scalefacGain[]
                             */
                LOOP(1);
                for (n = sectionData->section[m].sfbStart;
                     n < sectionData->section[m].sfbStart + sectionData->section[m].sfbCnt;
                     n++) {
                  BRANCH(1);
                  if (maxValueInSfb[n] != 0) {
                    MOVE(1);
                    found = 1;

                    ADD(2); MISC(1); BRANCH(1);
                    if ( (abs(scalefacGain[n] - lastValScf)) < CODE_BOOK_SCF_LAV) {
                      MOVE(1);
                      deltaScf = 0;
                    }
                    else {

                      ADD(1); MULT(1);
                      deltaScf = -(scalefacGain[j] - lastValScf);

                      MOVE(2);
                      lastValScf = scalefacGain[j];
                      scfSkipCounter = 0;
                    }
                    break;
                  }

                  ADD(1);
                  scfSkipCounter = scfSkipCounter + 1;
                }
              }
            }

            BRANCH(1);
            if (found == 0)   {
              MOVE(2);
              deltaScf = 0;
              scfSkipCounter = 0;
            }
          }
          else {

            MOVE(1);
            deltaScf = 0;

            ADD(1);
            scfSkipCounter = scfSkipCounter - 1;
          }
        }
        else {
          ADD(1); MULT(1);
          deltaScf = -(scalefacGain[j] - lastValScf);

          MOVE(1);
          lastValScf = scalefacGain[j];
        }

        INDIRECT(1); FUNC(1); ADD(1); STORE(1);
        sectionData->scalefacBits += bitCountScalefactorDelta(deltaScf);
      }
    }
  }

  COUNT_sub_end();
}
Пример #28
0
void AdjustThresholds(ADJ_THR_STATE     *adjThrState,
                      ATS_ELEMENT       *AdjThrStateElement,
                      PSY_OUT_CHANNEL   psyOutChannel[MAX_CHANNELS],
                      PSY_OUT_ELEMENT   *psyOutElement,
                      float             *chBitDistribution,
                      float            sfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
                      const int         nChannels,
                      QC_OUT_ELEMENT    *qcOE,
                      const int         avgBits,
                      const int         bitresBits,
                      const int         maxBitresBits,
                      const float       maxBitFac,
                      const int         sideInfoBits)
{
   float noRedPe, grantedPe, grantedPeCorr;
   int curWindowSequence;
   PE_DATA peData;
   float bitFactor;
   int ch;

   COUNT_sub_start("AdjustThresholds");

   INDIRECT(1); PTR_INIT(1); FUNC(5);
   preparePe(&peData, psyOutChannel, sfbFormFactor, nChannels, AdjThrStateElement->peOffset);

   PTR_INIT(1); FUNC(3);
   calcPe(&peData, psyOutChannel, nChannels);

   MOVE(1);
   noRedPe = peData.pe;

   MOVE(1);
   curWindowSequence = LONG_WINDOW;

   ADD(1); BRANCH(1);
   if (nChannels==2) {

     ADD(2); LOGIC(1);
     if ((psyOutChannel[0].windowSequence == SHORT_WINDOW) ||
         (psyOutChannel[1].windowSequence == SHORT_WINDOW)) {

       MOVE(1);
       curWindowSequence = SHORT_WINDOW;
     }
   }
   else {

     MOVE(1);
     curWindowSequence = psyOutChannel[0].windowSequence;
   }


   MULT(1); ADD(1); FUNC(8);
   bitFactor = bitresCalcBitFac(bitresBits, maxBitresBits,
                                noRedPe+5.0f*sideInfoBits,
                                curWindowSequence, avgBits, maxBitFac,
                                adjThrState,
                                AdjThrStateElement);

   FUNC(1); MULT(1);
   grantedPe = bitFactor * bits2pe((float)avgBits);

   INDIRECT(3); ADD(1); BRANCH(1); MOVE(1); /* min() */ PTR_INIT(1); FUNC(4);
   calcPeCorrection(&(AdjThrStateElement->peCorrectionFactor), 
                    min(grantedPe, noRedPe),
                    AdjThrStateElement->peLast, 
                    AdjThrStateElement->dynBitsLast);

   INDIRECT(1); MULT(1);
   grantedPeCorr = grantedPe * AdjThrStateElement->peCorrectionFactor;

   ADD(1); BRANCH(1);
   if (grantedPeCorr < noRedPe) {

      INDIRECT(2); PTR_INIT(3); FUNC(7);
      adaptThresholdsToPe(psyOutChannel,
                          psyOutElement,
                          &peData,
                          nChannels,
                          grantedPeCorr,
                          &AdjThrStateElement->ahParam,
                          &AdjThrStateElement->minSnrAdaptParam);
   }

   PTR_INIT(2); /* pointers for chBitDistribution[],
                                peData.peChannelData[]
                */
   LOOP(1);
   for (ch=0; ch<nChannels; ch++) {

     BRANCH(1);
     if (peData.pe) {

       DIV(1); MULT(2); ADD(2); STORE(1);
       chBitDistribution[ch] = 0.2f + (float)(1.0f-nChannels*0.2f) * (peData.peChannelData[ch].pe/peData.pe);
     } else {

       MOVE(1);
       chBitDistribution[ch] = 0.2f;
     }
   }

   INDIRECT(1); MOVE(1);
   qcOE->pe= noRedPe;

   INDIRECT(1); MOVE(1);
   AdjThrStateElement->peLast = grantedPe;

   COUNT_sub_end();
}
Пример #29
0
int
IIR32Resample( float *inbuf,
               float *outbuf,
               int    inSamples,
               int    outSamples,
               int    stride)
{
  int i, k, s, ch, r;
  double accu;
  float  scratch[IIR_INTERNAL_BUFSIZE];
  int nProcessRuns  = outSamples  >> 1;

  COUNT_sub_start("IIR32Resample");

  SHIFT(1); /* counting previous operation */

  assert( stride <= IIR_CHANNELS);

  LOOP(1);
  for (ch=0; ch<stride; ch++) {
    int idxIn  = ch;
    int idxOut = ch;

    MOVE(2); /* counting previous operations */

    PTR_INIT(2); /* scratch[s]
                    statesIIR[s*stride+ch]
                 */
    LOOP(1);
    for (s=0; s<IIR_32_ORDER; s++) {

      MOVE(1);
      scratch[s] = statesIIR[s*stride+ch];
    }

    LOOP(1);
    for (r=0; r<nProcessRuns; r++) {

      PTR_INIT(1); /* scratch[s] */
      MOVE(1);
      s=IIR_32_ORDER;

      PTR_INIT(2); /* inbuf[idxIn] 
                      outbuf[idxOut]
                   */
      LOOP(1);
      for (i=0; i<IIR_DOWNSAMPLE_FAC; i++) {

        MOVE(1);
        accu = inbuf[idxIn];

        PTR_INIT(2); /* coeffDen[k]
                        scratch[s-k]
                     */
        LOOP(1);
        for (k=1; k<IIR_32_ORDER; k++) {
          MAC(1);
          accu += coeffDen[k] * scratch[s-k];
        }

        MOVE(1);
        scratch[s] = (float) accu;

        s++;

        assert( s<=IIR_INTERNAL_BUFSIZE);

        MOVE(1);
        accu = 0.0;

        PTR_INIT(2); /* coeffDen[k]
                        scratch[s-k]
                     */
        LOOP(1);
        for (k=1; k<IIR_32_ORDER; k++) {

          MAC(1);
          accu += coeffDen[k] * scratch[s-k];
        }

        MOVE(1);
        scratch[s] = (float) accu;

        s++;

        idxIn += stride;

      }

      PTR_INIT(1); /* scratch[s] */
      MOVE(1);
      s = IIR_32_ORDER;

      LOOP(1);
      for (i=0; i<IIR_UPSAMPLE_FAC; i++) {

        MULT(1);
        accu = coeffNum[0] * scratch[s];

        PTR_INIT(2); /* coeffNum[k]
                        scratch[s-k]
                     */
        LOOP(1);
        for (k=1; k<IIR_32_ORDER; k++) {

          MAC(1);
          accu += coeffNum[k] * scratch[s-k];
        }

        MOVE(1);
        outbuf[idxOut] = (float) accu;

        assert( s<=IIR_INTERNAL_BUFSIZE);

        s += IIR_DOWNSAMPLE_FAC;

        idxOut += stride;

      }

      FUNC(2); LOOP(1); PTR_INIT(2); MOVE(1); STORE(IIR_32_ORDER);
      memmove( &scratch[0], &scratch[IIR_UPSAMPLE_FAC*IIR_DOWNSAMPLE_FAC], IIR_32_ORDER*sizeof(float));

    }

    PTR_INIT(2); /* statesIIR[s*stride+ch]
                    scratch[s]
                 */
    LOOP(1);
    for (s=0; s<IIR_32_ORDER; s++) {

      MOVE(1);
      statesIIR[s*stride+ch] = scratch[s];
    }

    assert(idxIn/stride <= inSamples);

  } /* ch */

  MULT(1); /* counting post-operation */

  COUNT_sub_end();
  
  return outSamples * stride;
}
Пример #30
0
/* determine bands where avoid hole is not necessary resp. possible */
static void initAvoidHoleFlag(int ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                              PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                              PSY_OUT_ELEMENT* psyOutElement,
                              const int nChannels,
                              AH_PARAM *ahParam)
{
  int ch, sfb,sfbGrp;
  float sfbEn;
  float scaleSprEn;

  COUNT_sub_start("initAvoidHoleFlag");
  
  /* decrease spreaded energy by 3dB for long blocks, resp. 2dB for shorts
     (avoid more holes in long blocks) */
  LOOP(1);
  for (ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
    
    PTR_INIT(1); /* counting operation above */
    
    INDIRECT(1); ADD(1); BRANCH(1);
    if (psyOutChan->windowSequence != SHORT_WINDOW) {
      
      MOVE(1);
      scaleSprEn = 0.5f;
    }
    else {
      
      MOVE(1);
      scaleSprEn = 0.63f;
    }
    
    INDIRECT(2); LOOP(1);
    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
      
      PTR_INIT(1); /* pointer for psyOutChan->sfbSpreadedEnergy[] */
      LOOP(1);
      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {

        MULT(1); STORE(1);
        psyOutChan->sfbSpreadedEnergy[sfbGrp+sfb] *= scaleSprEn;
      }
    }
  }


  /* increase minSnr for local peaks, decrease it for valleys */
  
  INDIRECT(1); BRANCH(1);
  if (ahParam->modifyMinSnr) {
    
    LOOP(1);
    for(ch=0; ch<nChannels; ch++) {
      PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
      
      PTR_INIT(1); /* counting operation above */
      
      INDIRECT(2); LOOP(1);
      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
        
        PTR_INIT(3); /* pointers for psyOutChan->sfbEnergy[sfbGrp],
                        psyOutChan->sfbEnergy[sfbGrp+sfb],
                        psyOutChan->sfbMinSnr[]
                     */
        INDIRECT(1); LOOP(1);
        for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
          float sfbEnm1, sfbEnp1, avgEn;
          
          BRANCH(1); MOVE(1);
          if (sfb > 0)
            sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp+sfb-1];
          else
            sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp];
          
          INDIRECT(1); ADD(2); BRANCH(1); MOVE(1);
          if (sfb < psyOutChan->maxSfbPerGroup-1)
            sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb+1];
          else
            sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb];
          
          ADD(1); MULT(1);
          avgEn = (sfbEnm1 + sfbEnp1)/(float)2.0f;
          
          MOVE(1);
          sfbEn = psyOutChan->sfbEnergy[sfbGrp+sfb];
          
          /* peak ? */
          ADD(1); BRANCH(1);
          if (sfbEn > avgEn) {
            float tmpMinSnr = max((float)0.8f*avgEn/sfbEn,
                                  (float)0.316f);
            
            MULT(1); DIV(1); ADD(1); BRANCH(1); MOVE(1); /* counting previous operation */
            
            INDIRECT(1); ADD(1); BRANCH(1); /* if() */ ADD(1); BRANCH(1); MOVE(1); /* max() */
            if (psyOutChan->windowSequence!=SHORT_WINDOW)
              tmpMinSnr = max(tmpMinSnr, (float)0.316f);
            else
              tmpMinSnr = max(tmpMinSnr, (float)0.5f);
            
            ADD(1); BRANCH(1); MOVE(1);
            psyOutChan->sfbMinSnr[sfbGrp+sfb] =
              min(psyOutChan->sfbMinSnr[sfbGrp+sfb], tmpMinSnr);
          }
          
          /* valley ? */
          MULT(1); ADD(1); LOGIC(1); BRANCH(1);
          if (((float)2.0f*sfbEn < avgEn) && (sfbEn > (float)0.0f)) {
            float tmpMinSnr = avgEn/((float)2.0f*sfbEn) *
              psyOutChan->sfbMinSnr[sfbGrp+sfb];
            
            MULT(2); DIV(1); /* counting previous operation */
            
            ADD(1); BRANCH(1); MOVE(1);
            tmpMinSnr = min((float)0.8f, tmpMinSnr);
            
            MULT(1); ADD(1); BRANCH(1); MOVE(1);
            psyOutChan->sfbMinSnr[sfbGrp+sfb] = min(tmpMinSnr,
                                                    psyOutChan->sfbMinSnr[sfbGrp+sfb]*(float)3.16f);
          }
        }
      }
    }
  }
  
  ADD(1); BRANCH(1);
  if (nChannels == 2) {
    PSY_OUT_CHANNEL *psyOutChanM = &psyOutChannel[0];
    PSY_OUT_CHANNEL *psyOutChanS = &psyOutChannel[1];
    
    PTR_INIT(2); /* counting previous operation */
    
    PTR_INIT(7); /* pointers for psyOutElement->toolsInfo.msMask[],
                    psyOutChanM->sfbEnergy[],
                    psyOutChanS->sfbEnergy[],
                    psyOutChanM->sfbMinSnr[],
                    psyOutChanS->sfbMinSnr[],
                    psyOutChanM->sfbSpreadedEnergy[],
                    psyOutChanS->sfbSpreadedEnergy[]
                 */
    INDIRECT(1); LOOP(1);
    for (sfb=0; sfb<psyOutChanM->sfbCnt; sfb++) {
      
      BRANCH(1);
      if (psyOutElement->toolsInfo.msMask[sfb]) {
        float sfbEnM = psyOutChanM->sfbEnergy[sfb];
        float sfbEnS = psyOutChanS->sfbEnergy[sfb];
        float maxSfbEn = max(sfbEnM, sfbEnS);
        float maxThr = 0.25f * psyOutChanM->sfbMinSnr[sfb] * maxSfbEn;
        
        ADD(1); BRANCH(1); MOVE(1); /* max() */ MOVE(2); MULT(2); /* counting previous operations */
        
        ADD(1); DIV(1); ADD(1); BRANCH(1); MOVE(1); /* min() */ ADD(1); BRANCH(1); MOVE(1); /* max() */
        psyOutChanM->sfbMinSnr[sfb] = (float)max(psyOutChanM->sfbMinSnr[sfb],
                                                 min ( FLT_MAX, ((double)maxThr/(FLT_MIN+(double)sfbEnM))));
        
        ADD(1); BRANCH(1);
        if (psyOutChanM->sfbMinSnr[sfb] <= 1.0f) {
          
          ADD(1); BRANCH(1); MOVE(1);
          psyOutChanM->sfbMinSnr[sfb] = min(psyOutChanM->sfbMinSnr[sfb], 0.8f);
        }
        
        ADD(1); DIV(1); ADD(1); BRANCH(1); MOVE(1); /* min() */ ADD(1); BRANCH(1); MOVE(1); /* max() */       
        psyOutChanS->sfbMinSnr[sfb] = (float)max(psyOutChanS->sfbMinSnr[sfb],
                                                 min ( FLT_MAX, ((double)maxThr/(FLT_MIN+(double)sfbEnS))));
        
        ADD(1); BRANCH(1);
        if (psyOutChanS->sfbMinSnr[sfb] <= 1.0f) {
          
          ADD(1); BRANCH(1); MOVE(1);
          psyOutChanS->sfbMinSnr[sfb] = min(psyOutChanS->sfbMinSnr[sfb], 0.8f);
        }
        
        ADD(1); BRANCH(1);
        if (sfbEnM > psyOutChanM->sfbSpreadedEnergy[sfb]) {
          
          MULT(1); STORE(1);
          psyOutChanS->sfbSpreadedEnergy[sfb] = 0.9f * sfbEnS;
        }
        
        ADD(1); BRANCH(1);
        if (sfbEnS > psyOutChanS->sfbSpreadedEnergy[sfb]) {
          
          MULT(1); STORE(1);
          psyOutChanM->sfbSpreadedEnergy[sfb] = 0.9f * sfbEnM;
        }
      }
    }
  }
  
  
  /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
  LOOP(1);
  for(ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
    
    PTR_INIT(1); /* counting previous operation */
    
    INDIRECT(2); LOOP(1);
    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
      
      PTR_INIT(4); /* pointers for psyOutChan->sfbEnergy[],
                      psyOutChan->sfbMinSnr[],
                      psyOutChan->sfbSpreadedEnergy[],
                      ahFlag[][]
                   */
      INDIRECT(1); LOOP(1);
      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
        
        ADD(2); LOGIC(1); BRANCH(1);
        if (psyOutChan->sfbSpreadedEnergy[sfbGrp+sfb] > psyOutChan->sfbEnergy[sfbGrp+sfb] ||
            psyOutChan->sfbMinSnr[sfbGrp+sfb] > (float)1.0) {
          
          MOVE(1);
          ahFlag[ch][sfbGrp+sfb] = NO_AH;
        }
        else {
          
          MOVE(1);
          ahFlag[ch][sfbGrp+sfb] = AH_INACTIVE;
        }
      }
      
      PTR_INIT(1); /* pointer for ahFlag[][] */
      INDIRECT(2); LOOP(1);
      for (sfb=psyOutChan->maxSfbPerGroup; sfb<psyOutChan->sfbPerGroup; sfb++) {
        
        MOVE(1);
        ahFlag[ch][sfbGrp+sfb] = NO_AH;
      }
    }
  }
  
  COUNT_sub_end();
}