⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aacquant.c

📁 《Visual C++小波变换技术与工程实践》作者:靳济芳。书上的代码。第3章:语音的去噪处理
💻 C
📖 第 1 页 / 共 2 页
字号:

static int InnerLoop(CoderInfo *coderInfo,
					 double *xr_pow,
					 int *xi,
					 int max_bits)
{
	int bits;

	/*  count bits */
	bits = CountBits(coderInfo, xi, xr_pow);

	/*  increase quantizer stepsize until needed bits are below maximum */
	while (bits > max_bits) {
		coderInfo->global_gain += 1;
		bits = CountBits(coderInfo, xi, xr_pow);
	}

	return bits;
}

static void CalcAllowedDist(PsyInfo *psyInfo, int *cb_width, int num_cb,
							double *xr, double *xmin)
{
	int sfb, start, end, i;
	double en0, xmin0;

	end = 0;
	for (sfb = 0; sfb < num_cb; sfb++)
	{
		start = end;
		end += cb_width[sfb];

		for (en0 = 0.0, i = start; i < end; i++)
		{
			en0 += xr[i] * xr[i];
		}
		en0 /= cb_width[sfb];

		xmin0 = psyInfo->maskEn[sfb];
		if (xmin0 > 0.0)
			xmin0 = en0 * psyInfo->maskThr[sfb] / xmin0;
		xmin[sfb] = xmin0;
	}
}

static int OuterLoop(CoderInfo *coderInfo,
					 double *xr,
					 double *xr_pow,
					 int *xi,
					 double *xmin,
					 int target_bits)
{
	int sb;
	int notdone, over, better;
	int store_global_gain, outer_loop_count;
	int best_global_gain, age;

    calcNoiseResult noiseInfo;
    calcNoiseResult bestNoiseInfo;

	double sfQuantFac = pow(2.0, 0.1875);
	int *scale_factor = coderInfo->scale_factor;

	int *best_scale_factor;
	int *save_xi;
	double *distort;

	distort = (double*)AllocMemory(MAX_SCFAC_BANDS*sizeof(double));
	best_scale_factor = (int*)AllocMemory(MAX_SCFAC_BANDS*sizeof(int));

	save_xi = (int*)AllocMemory(FRAME_LEN*sizeof(int));

	notdone = 1;
	outer_loop_count = 0;

	do { /* outer iteration loop */

		over = 0;
		outer_loop_count++;

		InnerLoop(coderInfo, xr_pow, xi, target_bits);

		store_global_gain = coderInfo->global_gain;

		over = CalcNoise(coderInfo, xr, xi, coderInfo->requantFreq, distort, xmin, &noiseInfo);

		if (outer_loop_count == 1)
			better = 1;
		else
			better = QuantCompare(&bestNoiseInfo, &noiseInfo);

		if (better) {
			bestNoiseInfo = noiseInfo;
			best_global_gain = store_global_gain;

			for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
				best_scale_factor[sb] = scale_factor[sb];
			}
			memcpy(save_xi, xi, sizeof(int)*BLOCK_LEN_LONG);
			age = 0;
		} else
			age++;

        if (age > 3 && bestNoiseInfo.over_count == 0)
            break;

        notdone = BalanceNoise(coderInfo, distort, xr_pow);

		for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
			if (scale_factor[sb] > 30)
				notdone = 0;

		if (notdone == 0) 
            break;

	} while (1);

	coderInfo->global_gain = best_global_gain;
	for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
		scale_factor[sb] = best_scale_factor[sb];
	}
	memcpy(xi, save_xi, sizeof(int)*BLOCK_LEN_LONG);

	if (best_scale_factor) FreeMemory(best_scale_factor);
	if (save_xi) FreeMemory(save_xi);
	if (distort) FreeMemory(distort);

	return 0;
}

static int CalcNoise(CoderInfo *coderInfo,
					 double *xr,
					 int *xi,
					 double *requant_xr,
					 double *error_energy,
					 double *xmin,
					 calcNoiseResult *res
					 )
{
	int i, sb, sbw;
	int over = 0, count = 0;
	double invQuantFac;
	double linediff, noise;

	double over_noise = 1;
	double tot_noise = 1;
	double max_noise = 1E-20;

	for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {

		sbw = coderInfo->sfb_offset[sb+1] - coderInfo->sfb_offset[sb];

		invQuantFac = pow(2.0, -0.25*(coderInfo->scale_factor[sb] - coderInfo->global_gain));

		error_energy[sb] = 0.0;

		for (i = coderInfo->sfb_offset[sb]; i < coderInfo->sfb_offset[sb+1]; i++){
			requant_xr[i] = pow43[xi[i]] * invQuantFac; 

			/* measure the distortion in each scalefactor band */
			linediff = fabs(xr[i]) - requant_xr[i];
			error_energy[sb] += linediff * linediff;
		}
		error_energy[sb] = error_energy[sb] / sbw;		
		
		noise = error_energy[sb] / xmin[sb];

		/* multiplying here is adding in dB */
		tot_noise *= max(noise, 1E-20);
		if (noise>1) {
			over++;
			/* multiplying here is adding in dB */
			over_noise *= noise;
		}
		max_noise = max(max_noise,noise);
		error_energy[sb] = noise;
		count++;
  	}

	res->tot_count  = count;
	res->over_count = over;
	res->tot_noise   = 10.*log10(max(1e-20,tot_noise )); 
	res->over_noise  = 10.*log10(max(1e+00,over_noise)); 
	res->max_noise   = 10.*log10(max(1e-20,max_noise ));

	return over;
}


static int QuantCompare(calcNoiseResult *best,
						calcNoiseResult *calc)
{
	int better;

	better = calc->over_count  < best->over_count
		||  ( calc->over_count == best->over_count  &&
		calc->over_noise  < best->over_noise )
		||  ( calc->over_count == best->over_count  &&
		calc->over_noise == best->over_noise  &&
		calc->tot_noise   < best->tot_noise  ); 

	return better;
}

static int BalanceNoise(CoderInfo *coderInfo,
						double *distort,
						double *xrpow)
{
	int status = 0, sb;

	AmpScalefacBands(coderInfo, distort, xrpow);

	for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
		if (coderInfo->scale_factor[sb] == 0)
			status = 1;

	return status;
}

static void AmpScalefacBands(CoderInfo *coderInfo,
							 double *distort,
							 double *xr_pow)
{
	int start, end, l, sfb;
	double ifqstep, distort_thresh;

	ifqstep = pow(2.0, 0.1875);

	distort_thresh = -900;
	for (sfb = 0; sfb < coderInfo->nr_of_sfb; sfb++) {
		distort_thresh = max(distort[sfb], distort_thresh);
	}

	if (distort_thresh>1.0)
		distort_thresh=1.0;
	else
		distort_thresh *= .95;

    for ( sfb = 0; sfb < coderInfo->nr_of_sfb; sfb++ ) {
		if (distort[sfb] > distort_thresh) {
			coderInfo->scale_factor[sfb]++;
			start = coderInfo->sfb_offset[sfb];
			end   = coderInfo->sfb_offset[sfb+1];
			for ( l = start; l < end; l++ ) {
				xr_pow[l] *= ifqstep;
			}
		}
    }
}


static int SortForGrouping(CoderInfo* coderInfo,
						   PsyInfo *psyInfo,
						   ChannelInfo *channelInfo,
						   int *sfb_width_table,
						   double *xr)
{
	int i,j,ii;
	int index = 0;
	double xr_tmp[1024];
	double thr_tmp[150];
	double en_tmp[150];
	int book=1;
	int group_offset=0;
	int k=0;
	int windowOffset = 0;


	/* set up local variables for used quantInfo elements */
	int* sfb_offset = coderInfo->sfb_offset;
	int* nr_of_sfb = &(coderInfo->nr_of_sfb);
	int* window_group_length;
	int num_window_groups;
	*nr_of_sfb = coderInfo->max_sfb;              /* Init to max_sfb */
	window_group_length = coderInfo->window_group_length;
	num_window_groups = coderInfo->num_window_groups;

	/* calc org sfb_offset just for shortblock */
	sfb_offset[k]=0;
	for (k=1 ; k <*nr_of_sfb+1; k++) {
		sfb_offset[k] = sfb_offset[k-1] + sfb_width_table[k-1];
	}

	/* sort the input spectral coefficients */
	index = 0;
	group_offset=0;
	for (i=0; i< num_window_groups; i++) {
		for (k=0; k<*nr_of_sfb; k++) {
			for (j=0; j < window_group_length[i]; j++) {
				for (ii=0;ii< sfb_width_table[k];ii++)
					xr_tmp[index++] = xr[ii+ sfb_offset[k] + 128*j +group_offset];
			}
		}
		group_offset +=  128*window_group_length[i];     
	}

	for (k=0; k<1024; k++){
		xr[k] = xr_tmp[k];
	}


	/* now calc the new sfb_offset table for the whole p_spectrum vector*/
	index = 0;
	sfb_offset[index++] = 0;
	windowOffset = 0;
	for (i=0; i < num_window_groups; i++) {
		for (k=0 ; k <*nr_of_sfb; k++) {
			int w;
			double worstTHR;
			double worstEN;

			/* for this window group and this band, find worst case inverse sig-mask-ratio */
			if (channelInfo->msInfo.is_present && channelInfo->msInfo.ms_usedS[windowOffset][k]) {
				worstTHR = psyInfo->maskThrSMS[windowOffset][k];
				worstEN = psyInfo->maskEnSMS[windowOffset][k];
			} else {
				worstTHR = psyInfo->maskThrS[windowOffset][k];
				worstEN = psyInfo->maskEnS[windowOffset][k];
			}

			for (w=1;w<window_group_length[i];w++) {
				if (channelInfo->msInfo.is_present && channelInfo->msInfo.ms_usedS[w+windowOffset][k]) {
					if (psyInfo->maskThrSMS[w+windowOffset][k] < worstTHR) {
						worstTHR = psyInfo->maskThrSMS[w+windowOffset][k];
						worstEN = psyInfo->maskEnSMS[w+windowOffset][k];
					}
				} else {
					if (psyInfo->maskThrS[w+windowOffset][k] < worstTHR) {
						worstTHR = psyInfo->maskThrS[w+windowOffset][k];
						worstEN = psyInfo->maskEnS[w+windowOffset][k];
					}
				}
			}
			thr_tmp[k+ i* *nr_of_sfb] = worstTHR;
			en_tmp[k+ i* *nr_of_sfb] = worstEN;
			sfb_offset[index] = sfb_offset[index-1] + sfb_width_table[k]*window_group_length[i] ;
			index++;
		}
		windowOffset += window_group_length[i];
	}

	*nr_of_sfb = *nr_of_sfb * num_window_groups;  /* Number interleaved bands. */

	for (k = 0; k < *nr_of_sfb; k++){
		psyInfo->maskThr[k] = thr_tmp[k];
		psyInfo->maskEn[k] = en_tmp[k];
	}

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -