/*
 *
 * Calculates the expected counts
 * based on the observed counts class
 * member. It must be called after
 * calculate observed counts for 
 * meaningful results.
 */
void WFST_Trainer_Local::calculate_expected_counts() {
  int arc_id = 0;

  for (StateIterator<VectorFst<LogArc> > siter(*fst); !siter.Done(); siter.Next()) {
    int state_id = siter.Value();
    int tmp_arc_id = arc_id;

    vector<double> total_traversals(symbol_bound,-DBL_MAX);

    for (ArcIterator<VectorFst<LogArc> > aiter(*fst,state_id); !aiter.Done(); aiter.Next()) {

      const LogArc &arc = aiter.Value();
      total_traversals[arc.ilabel] 
	= logadd(total_traversals[arc.ilabel],this->observed_counts[tmp_arc_id]);
      tmp_arc_id += 1;
    }
    for (ArcIterator<VectorFst<LogArc> > aiter(*fst,state_id); !aiter.Done(); aiter.Next()) {
      const LogArc &arc = aiter.Value();
      double arc_prob = arc.weight.Value();
     
      this->expected_counts[arc_id] = logadd(this->expected_counts[arc_id],
					     total_traversals[arc.ilabel] - arc_prob);
      arc_id += 1;
    }
  }
}
示例#2
0
void mpeg3audio_ac3_ba_compute_psd(int start, 
		int end, 
		short exps[], 
		short psd[], 
		short bndpsd[])
{
	int bin,i,j,k;
	int lastbin = 0;
	
/* Map the exponents into dBs */
	for (bin = start; bin < end; bin++) 
	{ 
		psd[bin] = (3072 - (exps[bin] << 7)); 
	}

/* Integrate the psd function over each bit allocation band */
	j = start; 
	k = mpeg3_masktab[start]; 
	
	do 
	{ 
		lastbin = mpeg3_min(mpeg3_bndtab[k] + mpeg3_bndsz[k], end); 
		bndpsd[k] = psd[j]; 
		j++; 

		for(i = j; i < lastbin; i++) 
		{ 
			bndpsd[k] = logadd(bndpsd[k], psd[j]);
			j++; 
		}

		k++; 
	}while(end > lastbin);
}
示例#3
0
void S_remake(double a) {
  int N, M;
  for (N=2; N<usedN; N++) {
    S_m[1][N] = log(N-a-1.0) + S_m[1][N-1];
    for (M=2; M<=usedM && M<N; M++) {
      tblSNM(N,M) = logadd(tblSNM(N-1,M-1),log(N-(M*a)-1.0)+tblSNM(N-1,M));
    }
  }    
}
示例#4
0
static
prob_t prombs_simple_(
        prob_t *result,
        size_t j,
        prob_t (*f)(int, int, void*),
        void *data)
{
        if (j == 0) {
                return (*f)(0, 0, data);
        }
        else {
                size_t i;
                prob_t sum = -HUGE_VAL;

                for (i = 0; i < j; i++) {
                        if (result[i] == -HUGE_VAL) {
                                result[i] = prombs_simple_(result, i, f, data);
                        }
                        sum = logadd(sum, result[i] + f(i+1, j, data));
                }
                return logadd(sum, f(0, j, data));
        }
}
示例#5
0
文件: fhmm.c 项目: benihana/chmm
void update_prob() {
  float pisum = - INFINITY;
  float gmmsum[nstates];
  float xisum[nstates];
  size_t i, j;

  for (i = 0; i < nstates; i++) {
    gmmsum[i] = - INFINITY;
    xisum[i] = - INFINITY;

    pisum = logadd(pi[i], pisum);
  }

  for (i = 0; i < nstates; i++) {
    prior[i] = pi[i] - pisum;
  }

  for (i = 0; i < nstates; i++) {
    for (j = 0; j < nstates; j++) {
      xisum[i] = logadd(xisum[i], xi[IDX(i,j,nstates)]);
    }
    for (j = 0; j < nobvs; j++) {
      gmmsum[i] = logadd(gmmsum[i], gmm[IDX(i,j,nobvs)]);
    }
  }

  for (i = 0; i < nstates; i++) {
    for (j = 0; j < nstates; j++) {
      trans[IDX(i,j,nstates)] = xi[IDX(i,j,nstates)] - xisum[i];
    }
    for (j = 0; j < nobvs; j++) {
      obvs[IDX(i,j,nobvs)] = gmm[IDX(i,j,nobvs)] - gmmsum[i];
    }
  }

}
示例#6
0
void ba_compute_psd (int16_t start)
{
  int i,j,k;
  int16_t lastbin = 4;

  j = start; 
  k = masktab[start]; 

  bndpsd[k] = psd[j]; 
  j++; 

  for (i = j; i < lastbin; i++) { 
    bndpsd[k] = logadd(&bndpsd[k], &psd[j]);
    j++; 
  } 
}
示例#7
0
double prob_locus_coal_recon_topology_samples(
    int *ptree, int nnodes, int *recon, 
    int *plocus_tree, int nlocus_nodes, 
    int *locus_recon, int *locus_events,
    double *popsizes, 
    int *pstree, int nsnodes, double *stimes,
    int *daughters, int ndaughters, 
    double birth, double death,
    int nsamples, double pretime, double premean)
{
    // alloc datastructures
    double *ltimes = new double [nlocus_nodes];
    intnode *iltree = make_itree(nlocus_nodes, plocus_tree);
    int *stack = new int [nnodes];
    
    // integrate over duplication times using sampling
    double prob = -INFINITY;
    for (int i=0; i<nsamples; i++) {
        // sample duplication times
        sample_dup_times(ltimes,
                         iltree, nlocus_nodes, pstree, nsnodes,
                         stimes,
                         locus_recon, locus_events, birth, death,
                         pretime, premean, stack);
        
        // coal topology probability
        double const coal_prob = prob_locus_coal_recon_topology(
            ptree, nnodes, recon, 
            plocus_tree, iltree, nlocus_nodes, 
            popsizes, ltimes,
            daughters, ndaughters);

        prob = logadd(prob, coal_prob);
    }

    // clean up
    delete [] ltimes;
    free_itree(iltree);
    delete [] stack;

    return prob - log(nsamples);
}
/*
 * Calculates the observed counts (without parallelization)
 *
 * @param exemplar_num - the training examplar number
 * @param fst - the FST in with FeatureArcs
 * @param fst_log - the FST with the actual weights in log space
 * @param alpha - the alpha values
 * @param beta - the beta values
 *
 */
void WFST_Trainer_Local::calculate_observed_counts(int exemplar_num, 
					    VectorFst<FeatureArc> *fst, 
					    VectorFst<LogArc> *fst_log, 
					    vector<LogWeight> *alpha, 
					    vector<LogWeight> *beta) 
{
  //normalizing constant
  LogWeight Z = Times((*alpha)[0], (*beta)[0]);
  
  int arc_id = 0;
  for (StateIterator<VectorFst<FeatureArc> > siter(*fst); 
       !siter.Done(); siter.Next()) {
    int state_id = siter.Value();
    map<int,int> arc_mapper;
    int tmp = arc_id;
    
    for (ArcIterator<VectorFst<FeatureArc> > aiter1(*fst,state_id); 
	 !aiter1.Done(); aiter1.Next()) {
      const FeatureArc &arc = aiter1.Value();
      int old_arc_id = round(exp(-arc.weight.Value2().Value()));
      arc_mapper[tmp] = old_arc_id - 1;
      ++tmp;
    }

    for (ArcIterator<VectorFst<LogArc> > aiter2(*fst_log,state_id); 
	 !aiter2.Done(); aiter2.Next()) {
      const LogArc &arc = aiter2.Value();
      int old_arc_id2 = arc_mapper[arc_id];
      LogWeight val = ((Times(Times((*alpha)[state_id],arc.weight.Value()), 
			      (*beta)[arc.nextstate])));

      double log_val = Divide(val,Z).Value();
      this->observed_counts[old_arc_id2] = logadd(this->observed_counts[old_arc_id2],-log_val);
      ++arc_id;
    }
  }
}
示例#9
0
AUD_Int32s wov_adapt_gmm_si()
{
	AUD_Error  error = AUD_ERROR_NONE;
	AUD_Int32s ret   = 0;
	AUD_Int8s  wavPath[256] = { 0, };
	AUD_Int32s data;

	setbuf( stdout, NULL );
	setbuf( stdin, NULL );
	AUDLOG( "pls give adapt wav stream's folder path:\n" );
	wavPath[0] = '\0';
	data = scanf( "%s", wavPath );
	AUDLOG( "adapt wav stream's folder path is: %s\n", wavPath );

	// step 1: read UBM model from file
	void *hUbm = NULL;
	FILE *fpUbm = fopen( WOV_UBM_GMMMODEL_FILE, "rb" );
	if ( fpUbm == NULL )
	{
		AUDLOG( "cannot open ubm model file: [%s]\n", WOV_UBM_GMMMODEL_FILE );
		return AUD_ERROR_IOFAILED;
	}
	error = gmm_import( &hUbm, fpUbm );
	AUD_ASSERT( error == AUD_ERROR_NONE );
	fclose( fpUbm );
	fpUbm = NULL;

	// AUDLOG( "ubm GMM as:\n" );
	// gmm_show( hUbm );

	AUD_Int32s i = 0, j = 0;
	entry      *pEntry = NULL;
	dir        *pDir   = NULL;

	AUD_Int32s totalWinNum = 0;
	pDir = openDir( (const char*)wavPath );
	if ( pDir == NULL )
	{
		AUDLOG( "cannot open folder: %s\n", wavPath );
		return -1;
	}

	while ( ( pEntry = scanDir( pDir ) ) )
	{
		AUD_Int8s   keywordFile[256] = { 0, };
		AUD_Summary fileSummary;
		AUD_Int32s  sampleNum = 0;

		snprintf( (char*)keywordFile, 256, "%s/%s", wavPath, pEntry->name );
		// AUDLOG( "%s\n", keywordFile );

		ret = parseWavFromFile( keywordFile, &fileSummary );
		if ( ret < 0 )
		{
			continue;
		}
		AUD_ASSERT( fileSummary.channelNum == CHANNEL_NUM && fileSummary.bytesPerSample == BYTES_PER_SAMPLE && fileSummary.sampleRate == SAMPLE_RATE );

		// request memeory for template
		sampleNum = fileSummary.dataChunkBytes / fileSummary.bytesPerSample;
		for ( j = 0; j * FRAME_STRIDE + FRAME_LEN <= sampleNum; j++ )
		{
			;
		}
		j = j - MFCC_DELAY;

		totalWinNum += j;
	}
	closeDir( pDir );
	pDir = NULL;

	AUD_Matrix featureMatrix;
	featureMatrix.rows     = totalWinNum;
	featureMatrix.cols     = MFCC_FEATDIM;
	featureMatrix.dataType = AUD_DATATYPE_INT32S;
	ret = createMatrix( &featureMatrix );
	AUD_ASSERT( ret == 0 );

	AUD_Int32s currentRow  = 0;
	pDir = openDir( (const char*)wavPath );
	while ( ( pEntry = scanDir( pDir ) ) )
	{
		AUD_Int8s   keywordFile[256] = { 0, };
		AUD_Summary fileSummary;
		AUD_Int32s  sampleNum        = 0;
		void        *hMfccHandle     = NULL;

		snprintf( (char*)keywordFile, 256, "%s/%s", wavPath, pEntry->name );
		// AUDLOG( "%s\n", keywordFile );

		ret = parseWavFromFile( keywordFile, &fileSummary );
		if ( ret < 0 )
		{
			continue;
		}
		AUD_ASSERT( fileSummary.channelNum == CHANNEL_NUM && fileSummary.bytesPerSample == BYTES_PER_SAMPLE && fileSummary.sampleRate == SAMPLE_RATE );

		AUD_Int32s bufLen = fileSummary.dataChunkBytes;
		AUD_Int16s *pBuf  = (AUD_Int16s*)calloc( bufLen, 1 );
		AUD_ASSERT( pBuf );

		sampleNum = readWavFromFile( (AUD_Int8s*)keywordFile, pBuf, bufLen );
		AUD_ASSERT( sampleNum > 0 );

		// pre-processing

		 // pre-emphasis
		sig_preemphasis( pBuf, pBuf, sampleNum );

		 // calc framing number
		for ( j = 0; j * FRAME_STRIDE + FRAME_LEN <= sampleNum; j++ )
		{
			;
		}

		 // XXX: select salient frames
		AUD_Feature feature;
		feature.featureMatrix.rows     = j - MFCC_DELAY;
		feature.featureMatrix.cols     = MFCC_FEATDIM;
		feature.featureMatrix.dataType = AUD_DATATYPE_INT32S;
		feature.featureMatrix.pInt32s  = featureMatrix.pInt32s + currentRow * feature.featureMatrix.cols;

		feature.featureNorm.len      = j - MFCC_DELAY;
		feature.featureNorm.dataType = AUD_DATATYPE_INT64S;
		ret = createVector( &(feature.featureNorm) );
		AUD_ASSERT( ret == 0 );

		error = mfcc16s32s_init( &hMfccHandle, FRAME_LEN, WINDOW_TYPE, MFCC_ORDER, FRAME_STRIDE, SAMPLE_RATE, COMPRESS_TYPE );
		AUD_ASSERT( error == AUD_ERROR_NONE );

		error = mfcc16s32s_calc( hMfccHandle, pBuf, sampleNum, &feature );
		AUD_ASSERT( error == AUD_ERROR_NONE );

		error = mfcc16s32s_deinit( &hMfccHandle );
		AUD_ASSERT( error == AUD_ERROR_NONE );

		free( pBuf );
		pBuf   = NULL;
		bufLen = 0;

		ret = destroyVector( &(feature.featureNorm) );
		AUD_ASSERT( ret == 0 );

		currentRow += feature.featureMatrix.rows;
	}
	closeDir( pDir );
	pDir = NULL;

	AUD_Matrix llrMatrix;
	llrMatrix.rows     = totalWinNum;
	llrMatrix.cols     = gmm_getmixnum( hUbm );
	llrMatrix.dataType = AUD_DATATYPE_DOUBLE;
	ret = createMatrix( &llrMatrix );
	AUD_ASSERT( ret == 0 );

	AUD_Double llr = 0.;
	for ( j = 0; j < featureMatrix.rows; j++ )
	{
		AUD_Vector componentLLR;
		componentLLR.len      = llrMatrix.cols;
		componentLLR.dataType = AUD_DATATYPE_DOUBLE;
		componentLLR.pDouble  = llrMatrix.pDouble + j * llrMatrix.cols;

		llr = gmm_llr( hUbm, &(featureMatrix), j, &componentLLR );
	}

	AUD_Vector sumLlr;
	sumLlr.len      = llrMatrix.cols;
	sumLlr.dataType = AUD_DATATYPE_DOUBLE;
	ret = createVector( &sumLlr );
	AUD_ASSERT( ret == 0 );

	AUD_Double *pSumLlr = sumLlr.pDouble;
	for ( j = 0; j < llrMatrix.cols; j++ )
	{
		pSumLlr[j] = llrMatrix.pDouble[j];
	}
	for ( i = 1; i < llrMatrix.rows; i++ )
	{
		for ( j = 0; j < llrMatrix.cols; j++ )
		{
			pSumLlr[j] = logadd( pSumLlr[j],  *(llrMatrix.pDouble + i * llrMatrix.cols + j) );
		}
	}

#if 0
	AUD_Vector bestIndex;
	bestIndex.len      = TOP_N;
	bestIndex.dataType = AUD_DATATYPE_INT32S;
	ret = createVector( &bestIndex );
	AUD_ASSERT( ret == 0 );

	// get top TOP_N component
	ret = sortVector( &sumLlr, &bestIndex );
	AUD_ASSERT( ret == 0 );
#else
	llr = pSumLlr[0];
	for ( j = 1; j < sumLlr.len; j++ )
	{
		llr = logadd( llr, pSumLlr[j] );
	}
	// AUDLOG( "llr: %.f\n", llr );

	AUD_Vector sortIndex;
	sortIndex.len      = sumLlr.len;
	sortIndex.dataType = AUD_DATATYPE_INT32S;
	ret = createVector( &sortIndex );
	AUD_ASSERT( ret == 0 );

	ret = sortVector( &sumLlr, &sortIndex );
	AUD_ASSERT( ret == 0 );

	int    num = 0;
	double val = 0.;
	for ( i = 0; i < sortIndex.len; i++ )
	{
		// ln( 0.001 ) ~= -7.
		val =  pSumLlr[sortIndex.pInt32s[i]] - llr + 7.;
		// AUDLOG( "%f, \n", val );
		if ( val < 0 )
		{
			break;
		}
		num++;
	}
	// AUDLOG( "\n" );
	AUD_ASSERT( num > 0 );

	AUDLOG( "computed component num: %d\n", num );

	num = AUD_MAX( num, TOP_N );
	AUDLOG( "normalized component num: %d\n", num );

	AUD_Vector bestIndex;
	bestIndex.len      = num;
	bestIndex.dataType = AUD_DATATYPE_INT32S;
	bestIndex.pInt32s  = sortIndex.pInt32s;
#endif

	int slash = '/';
	char *ptr = strrchr( (char*)wavPath, slash );
	ptr++;

	// select imposter GMM
	void      *hImposterGmm        = NULL;
	AUD_Int8s imposterGmmName[256] = { 0, };
	snprintf( (char*)imposterGmmName, 256, "%s-imposter", ptr );
	error = gmm_select( &hImposterGmm, hUbm, &bestIndex, 0 | GMM_INVERTSELECT_MASK, imposterGmmName );
	AUD_ASSERT( error == AUD_ERROR_NONE );

	gmm_show( hImposterGmm );

	// export gmm
	char imposterFile[256] = { 0 };
	snprintf( imposterFile, 256, "%s/%s-imposter.gmm", WOV_IMPOSTER_GMMMODEL_DIR, ptr );
	AUDLOG( "Export imposter GMM Model to: %s\n", imposterFile );
	FILE *fpImposterGmm = fopen( imposterFile, "wb" );
	AUD_ASSERT( fpImposterGmm );

	error = gmm_export( hImposterGmm, fpImposterGmm );
	AUD_ASSERT( error == AUD_ERROR_NONE );
	AUDLOG( "Export imposter GMM Model File Done\n" );

	fclose( fpImposterGmm );
	fpImposterGmm = NULL;

	error = gmm_free( &hImposterGmm );
	AUD_ASSERT( error == AUD_ERROR_NONE );

	// select keyword GMM
	void      *hAdaptedGmm        = NULL;
	AUD_Int8s adaptedGmmName[256] = { 0, };
	snprintf( (char*)adaptedGmmName, 256, "%s", ptr );
	// AUDLOG( "%s\n", adaptedGmmName );
	error = gmm_select( &hAdaptedGmm, hUbm, &bestIndex, 0, adaptedGmmName );
	AUD_ASSERT( error == AUD_ERROR_NONE );

	ret = destroyVector( &sumLlr );
	AUD_ASSERT( ret == 0 );

	ret = destroyMatrix( &llrMatrix );
	AUD_ASSERT( ret == 0 );

#if 0
	ret = destroyVector( &bestIndex );
	AUD_ASSERT( ret == 0 );
#else
	ret = destroyVector( &sortIndex );
	AUD_ASSERT( ret == 0 );
#endif

#if 1
	// adapt GMM
	error = gmm_adapt( hAdaptedGmm, &featureMatrix );
	AUD_ASSERT( error == AUD_ERROR_NONE );
#endif

	gmm_show( hAdaptedGmm );

	// export gmm
	char modelFile[256] = { 0 };
	snprintf( modelFile, 256, "%s/%s.gmm", WOV_KEYWORD_GMMMODEL_DIR, ptr );
	AUDLOG( "Export GMM Model to: %s\n", modelFile );
	FILE *fpGmm = fopen( modelFile, "wb" );
	AUD_ASSERT( fpGmm );

	error = gmm_export( hAdaptedGmm, fpGmm );
	AUD_ASSERT( error == AUD_ERROR_NONE );
	AUDLOG( "Export GMM Model File Done\n" );

	fclose( fpGmm );
	fpGmm = NULL;

	ret = destroyMatrix( &featureMatrix );
	AUD_ASSERT( ret == 0 );

	error = gmm_free( &hAdaptedGmm );
	AUD_ASSERT( error == AUD_ERROR_NONE );

	error = gmm_free( &hUbm );
	AUD_ASSERT( error == AUD_ERROR_NONE );

	AUDLOG( "keyword model adapt2 done\n" );

	return 0;
}
示例#10
0
文件: fhmm.c 项目: benihana/chmm
/* forward backward algoritm: return observation likelihood */
float forward_backward(int *data, size_t len, int backward)
{
  /* construct trellis */
  float alpha[len][nstates];
  float beta[len][nstates];

  size_t i, j, k;
  float p, e;
  float loglik;

  for (i = 0; i < len; i++) {
    for (j = 0; j < nstates; j++) {
      alpha[i][j] = - INFINITY;
      beta[i][j] = - INFINITY;
    }
  }

  /* forward pass */
  for (i = 0; i < nstates; i++) {
    alpha[0][i] = prior[i] + obvs[IDX(i,data[0],nobvs)];
  }
  for (i = 1; i < len; i++) {
    for (j = 0; j < nstates; j++) {
      for (k = 0; k < nstates; k++) {
        p = alpha[i-1][k] + trans[IDX(k,j,nstates)] + obvs[IDX(j,data[i],nobvs)];
        alpha[i][j] = logadd(alpha[i][j], p);
      }
    }
  }
  loglik = -INFINITY;
  for (i = 0; i < nstates; i++) {
    loglik = logadd(loglik, alpha[len-1][i]);
  }

  if (! backward)
    return loglik;

  /* backward pass & update counts */
  for (i = 0; i < nstates; i++) {
    beta[len-1][i] = 0;         /* 0 = log (1.0) */
  }
  for (i = 1; i < len; i++) {
    for (j = 0; j < nstates; j++) {

      e = alpha[len-i][j] + beta[len-i][j] - loglik;
      gmm[IDX(j,data[len-i],nobvs)] = logadd(gmm[IDX(j,data[len-i],nobvs)], e);

      for (k = 0; k < nstates; k++) {
        p = beta[len-i][k] + trans[IDX(j,k,nstates)] + obvs[IDX(k,data[len-i],nobvs)];
        beta[len-1-i][j] = logadd(beta[len-1-i][j], p);

        e = alpha[len-1-i][j] + beta[len-i][k]
          + trans[IDX(j,k,nstates)] + obvs[IDX(k,data[len-i],nobvs)] - loglik;
        xi[IDX(j,k,nstates)] = logadd(xi[IDX(j,k,nstates)], e);
      }
    }
  }
  p = -INFINITY;
  for (i = 0; i < nstates; i++) {
    p = logadd(p, prior[i] + beta[0][i] + obvs[IDX(i,data[0],nobvs)]);

    e = alpha[0][i] + beta[0][i] - loglik;
    gmm[IDX(i,data[0],nobvs)] = logadd(gmm[IDX(i,data[0],nobvs)], e);

    pi[i] = logadd(pi[i], e);
  }

#ifdef DEBUG
  /* verify if forward prob == backward prob */
  if (fabs(p - loglik) > 1e-3) {
    fprintf(stderr, "Error: forward and backward incompatible: %f, %f\n", loglik, p);
  }
#endif

  return loglik;
}
示例#11
0
void bit_alloc(
  int8_t *bap,    // [256]
  int8_t *exp,    // [256]
  int deltbae,
  int8_t *deltba, // [50]
  int start, int end, 
  int fscod, int halfratecod,
  int sdecay, int fdecay, 
  int sgain, int fgain, 
  int dbknee, int floor, 
  int fastleak, int slowleak, 
  int snroffset)

{
  int bin, lastbin, i, j, k, begin, bndstrt, bndend, lowcomp;
  int psd[256];   // PSD
  int bndpsd[50]; // integrated PSD
  int excite[50]; // excitation
  int mask[50];   // masking value

  // Step 1: Exponent mapping into PSD

  for (bin = start; bin < end; bin++)
    psd[bin] = (3072 - (exp[bin] << 7));

  // Step 2: PSD integration

  j = start;
  k = masktab[start];

  do
  {
    lastbin = min(bndtab[k] + bndsz[k], end);
    bndpsd[k] = psd[j];
    j++;

    for (i = j; i < lastbin; i++)
    {
      bndpsd[k] = logadd(bndpsd[k], psd[j]);
      j++;
    }

    k++;
  }
  while (end > lastbin);

  // Step 3: Compute excition function

  bndstrt = masktab[start];
  bndend = masktab[end - 1] + 1;

  if (bndstrt == 0) // for fbw and lfe channels
  {
    // note: do not calc_lowcomp() for the last band of the lfe channel, (bin = 6)
    lowcomp = 0;
    lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0);
    excite[0] = bndpsd[0] - fgain - lowcomp;
    lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1);
    excite[1] = bndpsd[1] - fgain - lowcomp;
    begin = 7;

    for (bin = 2; bin < 7; bin++)
    {
      if ((bndend != 7) || (bin != 6)) // skip for last bin of lfe channel
        lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);

      fastleak = bndpsd[bin] - fgain;
      slowleak = bndpsd[bin] - sgain;
      excite[bin] = fastleak - lowcomp;

      if ((bndend != 7) || (bin != 6)) // skip for last bin of lfe channel
      {
        if (bndpsd[bin] <= bndpsd[bin+1])
        {
          begin = bin + 1;
          break;
        }
      }
    }

    for (bin = begin; bin < min(bndend, 22); bin++)
    {
      if ((bndend != 7) || (bin != 6)) // skip for last bin of lfe channel
        lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);

      fastleak -= fdecay;
      fastleak = max(fastleak, bndpsd[bin] - fgain);
      slowleak -= sdecay;
      slowleak = max(slowleak, bndpsd[bin] - sgain);
      excite[bin] = max(fastleak - lowcomp, slowleak);
    }

    begin = 22;
  }
  else // for coupling channel
    begin = bndstrt;


  for (bin = begin; bin < bndend; bin++)
  {
    fastleak -= fdecay;
    fastleak = max(fastleak, bndpsd[bin] - fgain);
    slowleak -= sdecay;
    slowleak = max(slowleak, bndpsd[bin] - sgain);
    excite[bin] = max(fastleak, slowleak); 
  }

  // Step 4: Compute masking curve

  for (bin = bndstrt; bin < bndend; bin++)
  {
    if (bndpsd[bin] < dbknee)
      excite[bin] += ((dbknee - bndpsd[bin]) >> 2);
    mask[bin] = max(excite[bin], hth[fscod][bin >> halfratecod]);
  }

  // Step 5: Apply delta bit allocation

  if (deltbae == DELTA_BIT_NEW || deltbae == DELTA_BIT_REUSE)
    for (i = 0; i < 50; i++)
      mask[i] += deltba[i];

  // Step 6: Compute bit allocation

  i = start;
  j = masktab[start];

  do
  {
    lastbin = min(bndtab[j] + bndsz[j], end);
    mask[j] -= snroffset;

    mask[j] -= floor;
    if (mask[j] < 0)
      mask[j] = 0;

    mask[j] &= 0x1fe0; // 0001 1111 1110 0000
    mask[j] += floor;

    for (k = i; k < lastbin; k++)
    {
      int address = (psd[i] - mask[j]) >> 5;
      address = min(63, max(0, address));
      bap[i] = baptab[address];
      i++;
    }
    j++;
  }
  while (end > lastbin);

}
示例#12
0
/*
 *    assumes s->usedN/M already set to new values and memory filled
 *    startN/M = 0  --->  refill everything
 *    startN/M > 0  --->  memory extended so refill from here,
 *                        i.e.,  these were *last* values set, start +1
 */
 static int S_remake_part(stable_t *sp, double a, 
			  unsigned startN, unsigned startM,
			  unsigned usedN, unsigned usedM, unsigned usedN1) {
  int N, M;
  
  if ( startN==0 )
    startM = 0;
  sp->a = a;
  sp->lga = lgamma(1.0-a);

  // yaps_message("S_remake_part(a=%lf,N=%u, M=%u)\n", a, startN, startM);

  /*
   *  need to reset at sp->S1[] least to usedN1;
   *  up to usedN used by sp->S[][],
   *  and data needs overwriting up to usedN1
   */
   if ( startN==0 ) {
    sp->S1[0] = 0;
    N = 2;
  } else {
    N = startN+1;
    assert(sp->S1[startN-1]>0 );
  }
  for ( ; N<=usedN; N++)
    sp->S1[N-1] = sp->S1[N-2] + log(N-1-a);
  
  if ( startN==0 )
    //   a has changed, so reset others
    for ( ; N<=usedN1; N++)
      sp->S1[N-1] = 0;
  
  if ( sp->flags&S_STABLE ) {
    if ( (sp->flags&S_FLOAT)==0 ) {
      if ( startM>0 && startM<usedM ) {
	/*
	 *   extend for M upto startN
	 */
	for (N=startM+1; N<=startN; N++) {
	  for (M=startM+1; M<N && M<=usedM; M++) {
	    sp->S[N-3][M-2] = 
	      logadd(log(N-M*a-1.0)+((M<N-1)?sp->S[N-4][M-2]:0), 
		     sp->S[N-4][M-3]);
	    assert(isfinite(sp->S[N-3][M-2]));
	  }
	}
      }
      /*
       *   now fill from 0 after startN ... just like usual
       */
      if ( startN==0 ) {
	sp->S[0][0] = logadd(sp->S1[1],log(2-2*a));
	N = 4;
      } else {
	N = startN+1;
	assert(sp->S[N-4][0]>0);
      }
      for (; N<=usedN; N++) {
	sp->S[N-3][0] = logadd(log(N-2*a-1.0)+sp->S[N-4][0], 
			       sp->S1[N-2]);
	for (M=3; M<=usedM && M<N; M++) {
	  sp->S[N-3][M-2] = 
	    logadd(log(N-M*a-1.0)+((M<N-1)?sp->S[N-4][M-2]:0), sp->S[N-4][M-3]);
	  assert(isfinite(sp->S[N-3][M-2]));
	}
       }
    } else {
      /*
       *   computation done in double by storing in sp->SfrontN+M[]
       */
      if ( startM>0 && startM<usedM ) {
	/*
	 *   extend for M upto startN
	 */
	for (N=startM+2; N<=startN; N++) {
	  double lastS;
	  if (startM+1<N-1)
	    lastS = sp->Sf[N-4][startM-1];
	  else
	    lastS = 0 ;
	  sp->Sf[N-3][startM-1] = sp->SfrontN[startM-1]
	    = logadd(log(N-(startM+1)*a-1.0)+lastS,
		     sp->SfrontM[N-startM-2]);
	  for (M=startM+2; M<N && M<=usedM; M++) {
	    double saveS = sp->SfrontN[M-2];
	    if ( M==N-1 ) saveS = 0;
	    sp->SfrontN[M-2] = logadd(log(N-M*a-1.0)+saveS, lastS);
	    sp->Sf[N-3][M-2] = sp->SfrontN[M-2];
	    assert(isfinite(sp->Sf[N-3][M-2]));
	    lastS = saveS;
	  }
	  //   save the SfrontM value
	  if ( N>usedM )
	    sp->SfrontM[N-usedM-1] = sp->SfrontN[usedM-2];
	}
      }
      if ( startN==0 ) {
	sp->Sf[0][0] = sp->SfrontN[0] = logadd(sp->S1[1],log(2-2*a));
	N = 4;
      } else {
	N = startN+1;
	assert(sp->Sf[N-4][0]>0);
      }
      for ( ; N<=usedN; N++) {
	double lastS;
	lastS = sp->SfrontN[0];
	sp->Sf[N-3][0] = sp->SfrontN[0] =
	  logadd(log(N-2*a-1.0)+lastS, sp->S1[N-2]);
	for (M=3; M<=usedM && M<N; M++) {
	  double saveS = sp->SfrontN[M-2];
	  if (M==N-1) saveS = 0;
	  sp->SfrontN[M-2] =
	    logadd(log(N-M*a-1.0)+saveS, lastS);
	  sp->Sf[N-3][M-2] = sp->SfrontN[M-2];
#ifndef NDEBUG
	  if ( !isfinite(sp->Sf[N-3][M-2]) ) 
	    yaps_quit("Building '%s' N to %d, sp->Sf[%d][%d] not finite, from %lf,%lf\n",
		      sp->tag, usedN, N-3, M-2,  saveS, lastS);
#endif
	  assert(isfinite(sp->Sf[N-3][M-2]));
	  lastS = saveS;
	}
	//   save the SfrontM value
	if ( N>usedM )
	  sp->SfrontM[N-usedM-1] = sp->SfrontN[usedM-2];
      }
    }
  }    
  if ( sp->flags&S_UVTABLE ) {
    if ( (sp->flags&S_FLOAT)==0 ) {
      if ( startM>0 && startM<usedM ) {
	/*
	 *   extend for M upto startN
	 */
	for (N=startM+1; N<=startN; N++) {
	  for (M=startM+1; M<=N && M<=usedM; M++) {
	    sp->V[N-2][M-2] = 
	      (1.0+((M<N)?((N-1-M*a)*sp->V[N-3][M-2]):0))
	      / (1.0/sp->V[N-3][M-3]+(N-1-(M-1)*a));
	  }
	}
      }
      /*
       *   now fill from 0 after startN ... just like usual
       */
      if ( startN==0 ) {
	sp->V[0][0] = 1.0/(1.0-a);
	N = 3;
      } else {
	N = startN+1;
	assert(sp->V[N-3][0]>0);
      }
      for (; N<=usedN; N++) {
	sp->V[N-2][0] = (1.0+(N-1-2*a)*sp->V[N-3][0])/(N-1-a);
	for (M=3; M<=usedM && M<=N; M++) {
	  sp->V[N-2][M-2] = 
	    (1.0+((M<N)?((N-1-M*a)*sp->V[N-3][M-2]):0))
	    / (1.0/sp->V[N-3][M-3]+(N-1-(M-1)*a));
	}
      }
    } else {
      if ( startM>0 && startM<usedM ) {
	/*
	 *   extend for M upto startN
	 */
	for (N=startM+1; N<=startN; N++) {
	  double lastS;
	  if ( startM+1<N) 
	    lastS = sp->VfrontN[startM-1];
	  else 
	    lastS = 0;  
	  sp->Vf[N-2][startM-1] = sp->VfrontN[startM-1] = 
	    (1.0+(N-1-(startM+1)*a)*lastS)
	    / (1.0/sp->VfrontM[N-1-startM]+(N-1-(startM)*a));
	  for (M=startM+2; M<=N && M<=usedM; M++) {
	    double saveS = sp->VfrontN[M-2];
	    assert(lastS!=0);
	    sp->Vf[N-2][M-2] = sp->VfrontN[M-2] = 
	      (1.0+((M<N)?((N-1-M*a)*saveS):0))
	      / (1.0/lastS+(N-1-(M-1)*a));
	    lastS = saveS;
	  }
	  //   save the VfrontM value
	  if ( N>=usedM )
	    sp->VfrontM[N-usedM] = sp->VfrontN[usedM-2];
	}
      }
      /*
       *   now fill from 0 after startN ... just like usual
       */
      if ( startN==0 ) {
	sp->Vf[0][0] = sp->VfrontN[0] = 1.0/(1.0-a);
	N = 3;
      } else {
	N = startN+1;
	assert(sp->Vf[N-3][0]>0);
      }
      for (; N<=usedN; N++) {
	double lastS;
	lastS = sp->VfrontN[0];
	sp->Vf[N-2][0] = sp->VfrontN[0] =
	  (1.0+(N-1-2*a)*lastS)/(N-1-a);
	for (M=3; M<=usedM && M<=N; M++) {
	  double saveS = sp->VfrontN[M-2];
	  assert(lastS!=0);
	  sp->Vf[N-2][M-2] = sp->VfrontN[M-2] = 
	    (1.0+((M<N)?((N-1-M*a)*saveS):0))
	    / (1.0/lastS+(N-1-(M-1)*a));
	  lastS = saveS;
	}
	//   save the VfrontM value
	if ( N>=usedM )
	  sp->VfrontM[N-usedM] = sp->VfrontN[usedM-2];
      }
    }
  }
  /*
   *  change bounds at end only after data filled;
   *  in case other threads running
   */
  sp->usedN = usedN;
  sp->usedN1 = usedN1;
  sp->usedM = usedM;
  return 0;
 }