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

📄 sample.cpp

📁 语音开发中的重要算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    xip->imag = tm.real * u.imag + tm.imag * u.real;
                    *xi = temp;
               }
               wptr = wptr + step;
          }
          step = 2 * step;
     }
     for (x = 0; x < length; x++)
     {
          trans = 0;
          for (int y = 0; y < rank; ++y)
              trans = (trans << 1) | (1 & (x >> y));
          if (x < trans)
          {
              xi = list + x;
              xj = list + trans;
              temp = *xj;
              *xj = *xi;
              *xi = temp;
          }
     }
     delete [] w;
     w = NULL;
}

void ConvertArray (short *in, int nr);
short Convert (short in);
//balance and adjust the mic volume
HRESULT	CSample::EchoOutData(short* poutData,LONG nLen, BYTE* pmic)
{
//for AudioMultiEqu
	int i, number_1=0, number_2=0, number_3=0,number_6=0;
	short sample_max=0;	
	double energy=0, Minenergy=0, Maxenergy=0, Standenergy=0, rate=0.6;
	double gain=1.0;
	int silence_counter = 0;

	short* Data = (short*) poutData;
	BYTE* Temp = (BYTE*)pmic;
	
	for (i=0; i < nLen/2; i++)
	{
		if((*(Data+i))<32767&&(*(Data+i))>-32767)
		{
			if ((unsigned int)abs(*(Data+i)) > sample_max)    
			sample_max = abs (*(Data+i));
		}
		if(abs(*(Data+i))>Threshold)
		{
			number_3++;
			number_2++;
			number_1++;
		}
		else
		{ 
			if(abs(*(Data+i))>1000)
			{
				number_2++;
				number_1++;
			}
			else
			{
				if(abs(*(Data+i))>800)
					number_1++;
				else
				{
					if(abs(*(Data+i))<800)
					number_6++;
				}
			}
		}
	}

//	Log6(_QTEXT("\t\t$$$$$$sample_max=%d, total=%d \r\n"),sample_max,total);
//	Log6(_QTEXT("\t\t\tnumber_3=%d, number_2=%d, number_1=%d, number_6=%d \r\n"),number_3,number_2,number_1,number_6);
	
	total++;

	if(total==10)
	{
//		if(sample_max > 20000 && number > (nLen/80))//only change volume
		if(sample_max > 20000 && number_3 > (nLen/160))
			*Temp = 3;
		else 
		{
//			if(sample_max > 1000 && number > (nLen/80))//only change volume
			if(sample_max > 1000 && number_2 > (nLen/160))
				*Temp = 2;
			else
			{	
//				if(sample_max > 500 && number > (nLen/80))//only change volume
				if(sample_max > 500 && number_1 > (nLen/160))
					*Temp = 1;
				else
				{
//					if(sample_max < 800 && number < (nLen/80))//only change volume
					if(sample_max < 500 && number_6 > (nLen/160))
						*Temp = 6;
					else	*Temp = 0;
				}
			}
		}
		total = 0;
	}
	else *Temp = 0;

//	Log6(_QTEXT("\t\t\tTemp=%d\r\n"),*Temp);

//use AudioOpt.cpp agc
///	ConvertArray((short*)Data,nLen/2);


//add energy process refer to VAD
//	energy = (float) 0.0;
//	for (i=0; i < nLen/2; i++)
//	{
//		short temp = *(Data+i);
//		energy += temp*temp;
//	}

//	Log6(_QTEXT("\t\t\tenergy=%f\r\n"),energy);

//	Minenergy = (float)preEnergy*0.9;
//	Maxenergy = (float)preEnergy*1.1; //	Standenergy = 528617608;

///	rate = 10*(Standenergy/energy);

//	if(energy>Minenergy&&energy<Maxenergy)//	if(energy<Standenergy/3)
//	{
//		rate = 0.1;
//	}
//	else rate = 1.0;

//method 2
	if(sample_max<300)
	{
		silence_counter++;
	}

	if(sample_max > 30000)
	{
		gain = 1.0*rate;
	}
	else 
	{
		if(sample_max < 1000)//800
		{
			if(sample_max < 800)//500
			{
				if(sample_max<300)
				{
					gain = 60*rate;
//					if (silence_counter > 40)  // pause -> speaking
//						gain += (gain - pregain) * 0.25f;
//					else
//						gain += (gain - pregain) * 0.05f;	
//					silence_counter = 0;
				}
				else
					gain = 40*rate;
			}
			else 
			{
				gain = 30.0*rate;
			}
		}
		else
		{
			gain = 32700.0/(double)sample_max;//32600.0
			gain = gain*rate;	//0.5*(gain*rate);
		}
	}

//	Log6(_QTEXT("\t\t\tgain=%f\r\n"),gain);
//	Log6(_QTEXT("\t\t\tpregain=%f\r\n"),pregain);

	if(pregain!=1.0)
	{
		if(gain<(0.8*pregain))
			gain = pregain*0.9;
		else if(gain>(1.2*pregain))
			gain = pregain*1.1;
	}

	if(gain*sample_max>32700.0)
	{
		gain = 32700.0/(double)sample_max;//32600.0
		gain = gain*rate;	//0.5*(gain*rate);
	}
		
//	for (i=0; i < nLen/2; i++)
//	{
//		Data[i] = (int)(Data[i]*rate);
//	}
	
	for (i=0; i < nLen/2; i++)
	{
		Data[i] = (int)(Data[i]*gain);
	}

	preEnergy = energy;
	pregain = gain;

//	Log6(_QTEXT("\t\tLastgain=%f\r\n"),gain);
//	Log6(_QTEXT("\t\tsample_max*gain=%f\r\n"),(sample_max*gain));

	return S_OK;
}

/**********************************************************/
/*!
*  Applies the automatic gain control to an array of
*  values.
*
*   \param in input buffer
*   \param out output buffer
*   \param nr number of elements
*/
/**********************************************************/

void CSample::ConvertArray (short *in, int nr)
{
	int i;
	short temp;
	
	for (i=0; i < nr; i++)
	{
		temp = Convert (in[i]);
		in[i] = temp;
		//out[i] = Convert (in[i]);
	}
}

/**********************************************************/
/*!
*  Calculates a new gain factor and applies the gain
*  factor to the given audio sample.
*
*   \param in old audio sample
*   \return new audio sample
*/
/**********************************************************/

short CSample::Convert (short in)
{
	float  gain_new;
	
	if ((unsigned int) abs (in) > sample_max_Con)    // get max
		sample_max_Con = abs (in);
	counter ++;
	
	// Will we get a overflow with the gain factor?
	// Yes: Calculate new gain.
	if (abs (in) * gain > 32000.0)
	{
		gain = ((float) SHRT_MAX / (float) sample_max_Con) * 0.95f;
		silence_counter = 0;
		return ((short) (in * gain));
	}
	
	// Calculate new gain factor 10x per second
	if (counter >= SAMPLE_RATE/10) 
	{
		if (sample_max_Con > 800)        // speaking?
		{
			gain_new = ((float) SHRT_MAX / (float) sample_max_Con) * 0.95f;
			
			if (silence_counter > 40)  // pause -> speaking
				gain += (gain_new - gain) * 0.25f;
			else
				gain += (gain_new - gain) * 0.05f;
			
			silence_counter = 0;
			
		}
		else                         // silence
		{
			silence_counter++;
			// silence > 2s: reduce gain
			if ((gain > 1.0) && (silence_counter >= 20))
				gain *= 0.95f; 
		}
		
		counter = 0;
		sample_max_Con = 1;
	}
//	Log6(_QTEXT("\t\tgain=%f\r\n"),gain);
	return ((short) (in * gain));
}


//only for balance audio but not to adjust the mic volume
HRESULT	CSample::EchoOutData(short* poutData,LONG nLen)
{
//for AudioMultiEqu
	int i, j, number_1=0, number_2=0, number_3=0,number_6=0;
	short sample_max=0;	
	double rate=0.6;
	double gain=1.0;
	int silence_counter = 0;

	short* Data = (short*) poutData;
	
	for (i=0; i < nLen/2; i++)
	{
		if((*(Data+i))<32767&&(*(Data+i))>-32767)
		{
			if ((unsigned int)abs(*(Data+i)) > sample_max)    
			sample_max = abs (*(Data+i));
		}
	}
	if(sample_max > 30000)
	{
		gain = 1.0*rate;
	}
	else
	{
		if(sample_max < 1000)//800
		{
			if(sample_max < 800)//500
			{
				gain = 40*rate;
			}
			else 
			{
				gain = 30.0*rate;
			}
		}
		else
		{
			gain = 32700.0/(double)sample_max;//32600.0
			gain = gain*rate;	//0.5*(gain*rate);
		}
	}

	if(pregain!=1.0)
	{
		if(gain<(0.8*pregain))
			gain = pregain*0.9;
		else if(gain>(1.2*pregain))
			gain = pregain*1.1;
	}

	if(gain*sample_max>32700.0)
	{
		gain = 32700.0/(double)sample_max;//32600.0
		gain = gain*rate;	//0.5*(gain*rate);
	}	


	for (i=0; i < nLen; i++)
	{
		Data[i] = (int)(Data[i]*gain);
	}
	pregain = gain;

//	Log6(_QTEXT("\t\tLastgain=%f\r\n"),gain);
//	Log6(_QTEXT("\t\tsample_max*gain=%f\r\n"),(sample_max*gain));

	return S_OK;

}


⌨️ 快捷键说明

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