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

📄 audiorec.cpp

📁 windows下实现的FFT算法的实现
💻 CPP
字号:
#include "StdAfx.h"
#include ".\audiorec.h"
#include "AudioTestDlg.h"
#include "Fft.h"
#include <math.h>

const int FFT_POINTS = 8192;
//static double MinEnergy = 10000;
static int count = 0, Nmute = 0, Nhigh = 0, Nlow = 0, Nmin = 0;
BOOL flag = 0, MUTE = 0;
static double MinEnergy = 0, Minhigh = 0, Minlow = 0;


IMPLEMENT_DYNCREATE(CAudioRec, CWinThread)

BEGIN_MESSAGE_MAP(CAudioRec,CWinThread)
	ON_THREAD_MESSAGE(MM_WIM_DATA, OnSoundData)
	ON_THREAD_MESSAGE(WM_RECORDSOUND_STARTRECORDING,OnStartRecording)
	ON_THREAD_MESSAGE(WM_RECORDSOUND_STOPRECORDING,OnStopRecording)
	ON_THREAD_MESSAGE(WM_RECORDSOUND_ENDTHREAD,OnEndThread)
END_MESSAGE_MAP()

CAudioRec::CAudioRec(void)
{
}

CAudioRec::CAudioRec(CDialog *dialog)
{
//	TRACE("CAudioRec::CAudioRec(CDialog *dialog)\n");
	pDlg=dialog;
	
	recording=FALSE;
	isallocated=0;

	PreCreateHeader();

	//Setting WAVEFORMATEX  structure for the audio input
	memset(&m_WaveFormatEx,0x00,sizeof(m_WaveFormatEx));
	m_WaveFormatEx.wFormatTag		=	WAVE_FORMAT_PCM;
	m_WaveFormatEx.nChannels		=	1;
	m_WaveFormatEx.wBitsPerSample	=	16;
	m_WaveFormatEx.cbSize			=	0;
	m_WaveFormatEx.nSamplesPerSec	=	SAMPLEPSEC;  //22.05 KHz
	m_WaveFormatEx.nBlockAlign		=	m_WaveFormatEx.wBitsPerSample/8;
	m_WaveFormatEx.nAvgBytesPerSec	=	m_WaveFormatEx.nBlockAlign * m_WaveFormatEx.nSamplesPerSec;
}


CAudioRec::~CAudioRec()
{
//	TRACE("CAudioRec::~CAudioRec\n");
	if(!isallocated)	return;

	for(int i=0;i<MAXRECBUFFER;i++)
	{
		if(rechead[i])
		{
			if(rechead[i]->lpData )
				delete [](rechead[i]->lpData);
			delete rechead[i];
		}
	}
}

BOOL CAudioRec::InitInstance()
{
//	TRACE("CAudioRec::InitInstance()\n");
	return TRUE;
}

int CAudioRec::ExitInstance()
{
//	TRACE("CAudioRec::ExitInstance()\n");
	return CWinThread::ExitInstance();
}

void CAudioRec::PreCreateHeader()
{
//	TRACE("CAudioRec::PreCreateHeader()\n");
	auducmp = new char[RECBUFFER];
	for(int i=0;i<MAXRECBUFFER;i++)
		rechead[i]=CreateWaveHeader();
	isallocated=1;
}

void CAudioRec::OnStartRecording(WPARAM wp,LPARAM lp)
{
//	TRACE("CAudioRec::OnStartRecording()\n");
	if(recording)	return;
	
	MMRESULT mmReturn = 
		::waveInOpen( &m_hRecord, WAVE_MAPPER,
			&m_WaveFormatEx, ::GetCurrentThreadId(), 0, CALLBACK_THREAD);
	if(mmReturn!=MMSYSERR_NOERROR )		return;

	if(mmReturn==MMSYSERR_NOERROR )
	{
		for(int i=0; i < MAXRECBUFFER ; i++)
		{
			mmReturn = ::waveInPrepareHeader(m_hRecord,rechead[i], sizeof(WAVEHDR));
			mmReturn = ::waveInAddBuffer(m_hRecord, rechead[i], sizeof(WAVEHDR));
		}
		mmReturn = ::waveInStart(m_hRecord);
		if(mmReturn==MMSYSERR_NOERROR ) 	recording=TRUE;
	}
	return;
}

void CAudioRec::OnStopRecording(WPARAM wp,LPARAM lp)
{
//	TRACE("CAudioRec::OnStopRecording()\n");

	if(!recording)		return;

	::waveInStop(m_hRecord);
	recording = FALSE;		

	::waveInReset(m_hRecord);  
	Sleep(500); 

	::waveInClose(m_hRecord);
	return;
}

void CAudioRec::OnSoundData(WPARAM wParam, LPARAM lParam)
{
//	TRACE("CAudioRec::OnSoundData()\n");

	int clen=1;
	if(recording==FALSE)	return;

	LPWAVEHDR lpHdr = (LPWAVEHDR) lParam;
	
	if(lpHdr->dwBytesRecorded==0 || lpHdr==NULL)	return;
		
	::waveInUnprepareHeader(m_hRecord, lpHdr, sizeof(WAVEHDR));

	
	// Send recorded audio to remote host...
	if(lpHdr->lpData!=NULL)
	{
		CopyMemory(auducmp, lpHdr->lpData, lpHdr->dwBytesRecorded);
		//pDlg->PostMessage(WM_AUD_BUFF, (WPARAM)auducmp, (LPARAM)lpHdr->dwBytesRecorded);
		int i;
		int fftPoints = FFT_POINTS;
		int cSample = lpHdr->dwBytesRecorded / (m_WaveFormatEx.wBitsPerSample / 8);
		int samplesPerSec = m_WaveFormatEx.nSamplesPerSec;
		double Energy;
		double likelihood = 1;

		short* _auducmp = (short*)auducmp;
		double* _audin = new double[cSample];
		Energy = 0;
		
		for (i=0; i<cSample; i++)
		{
			_audin[i] = (double)_auducmp[i];
		}

		//double *ptr = (double*) auducmp;
		Fft* _pFftTransformer = new Fft (fftPoints, cSample);
		_pFftTransformer->CopyIn(_audin,cSample);
		_pFftTransformer->Transform();
		
		for (i=0; i<fftPoints; i=i++)
		{
			Energy += _pFftTransformer->GetIntensity(i);
		}
		//Energy = _pFftTransformer->GetEnergy();
		//if (MinEnergy > Energy)
		//	MinEnergy = Energy;

		//if (MinEnergy < 1000)
  //          MinEnergy = 6000;
		( (CAudioTestDlg*) pDlg )->m_InsEnergy.Format("%f",MinEnergy);
		//Energy =Energy - MinEnergy;
		//Energy =20 *  log(Energy / MinEnergy);
		if (flag==1){
			likelihood = Energy / MinEnergy;

			( (CAudioTestDlg*) pDlg )->m_CalEnergy.Format("%f",likelihood);
			for (i=Prelude-1;i>0;i--)
				( (CAudioTestDlg*) pDlg )->m_WeightValue[0][i]=( (CAudioTestDlg*) pDlg )->m_WeightValue[0][i-1];
		
			if (Minhigh == 0 && Minlow == 0){
			Minhigh = Energy;
			Minlow = Energy;
			Nmin = 0;
			}
			else if (Minhigh < Energy){
				Minhigh = Energy;
				Nmin++;
			}
			else if (Minlow > Energy){
				Minlow = Energy;
				Nmin++;
			}
            
			if (((Minhigh - Minlow)  / MinEnergy) <0.6 && Nmin >= 4){
				MinEnergy = (Minhigh + Minlow) / 2;
				Nmin = 0;
			}

			if (likelihood < 1.5){
				Nmute++;
			}
			else {
				Nmute = 0;
				MUTE = 0;
			}

			if(Nmute >= 5)
				MUTE = 1;
	
			if (likelihood < 0.5){
				likelihood = 1;
			}
			//if (likelihood < 1.5 && likelihood >=1.2){
			//	Nlow++;
			//}
			//else {
			//	Nlow = 0;
			//}
	
			//if(Nlow >= 3)
			//	MinEnergy = MinEnergy * 1.1;

			//if (likelihood <= 0.8){
			//	Nhigh++;
			//}
			//else {
			//	Nhigh = 0;
			//}

			//if(Nhigh >= 3)
			//	MinEnergy = MinEnergy * 0.8;

			////if (likelihood > 50 && likelihood <= 100)
			////	likelihood = likelihood - 30;
			////if (likelihood > 100 && likelihood <= 150)
			////	likelihood = likelihood - 60;			
			////if (likelihood > 150)
			////	likelihood = likelihood - 150;

			if (likelihood > 45 && ( (CAudioTestDlg*) pDlg )->m_WeightValue[0][1]<1.8)
				likelihood = 1;

			( (CAudioTestDlg*) pDlg )->m_WeightValue[0][0]=likelihood;
			( (CAudioTestDlg*) pDlg )->m_TotalValue[0]=0;
		}
		else{
				if (Energy>1000){
					MinEnergy +=  Energy;
					count ++;
				}
				if(count >= (Prelude-2))
				{
					MinEnergy =  MinEnergy/ (Prelude-1);
					flag =1;
				}
		}

		if (MUTE ==0){
		for (i=Prelude-1;i>=0;i--)
			( (CAudioTestDlg*) pDlg )->m_TotalValue[0]+=( (CAudioTestDlg*) pDlg )->m_WeightValue[0][i]*( (CAudioTestDlg*) pDlg )->m_Coefficient[i];
		}
		else 
			( (CAudioTestDlg*) pDlg )->m_TotalValue[0] = 0;

		( (CAudioTestDlg*) pDlg )->m_WgtEnergy.Format("%f",( (CAudioTestDlg*) pDlg )->m_TotalValue[0]);
		if ( ((CAudioTestDlg*) pDlg)->m_LocalJudge==FALSE){
			( (CAudioTestDlg*) pDlg )->dcontrol.SendEnergyData(likelihood);
		}else{
			( (CAudioTestDlg*) pDlg )->CheckTop();
		}	
		//int temp;
//		( (CAudioTestDlg*) pDlg )->m_G729aCompress .Compress  (lpHdr->lpData,lpHdr->dwBytesRecorded,((CAudioTestDlg*) pDlg )->m_AComped,&clen);
		//((CAudioTestDlg*)pDlg)->m_G729aCompress.UnCompress(((CAudioTestDlg*)pDlg)->m_AComped, clen, ((CAudioTestDlg*)pDlg)->m_AUnComped, &temp);
		//((CAudioTestDlg*)pDlg)->m_AudioPlay->PostThreadMessage(WM_PLAYSOUND_PLAYBLOCK,  (WPARAM)temp, (LPARAM)((CAudioTestDlg*)pDlg)->m_AUnComped);
//		if(clen>0)
//			( (CAudioTestDlg*) pDlg )->dcontrol.SendAudioData((unsigned char *)(((CAudioTestDlg*) pDlg )->m_AComped),clen);
//		( (CAudioTestDlg*) pDlg )->m_ABytesSent +=clen;
//		( (CAudioTestDlg*) pDlg )->m_AFrames  ++;
		( (CAudioTestDlg*) pDlg )->SendMessage(WM_UPDATE_DATA);
//		( (CAudioTestDlg*) pDlg )->dcontrol.SendAudioData((unsigned char *)lpHdr->lpData,lpHdr->dwBytesRecorded);
		delete[] _audin;
	}
		
	if(recording)
	{	//Reuse the old buffer
		::waveInPrepareHeader(m_hRecord,lpHdr, sizeof(WAVEHDR));
		::waveInAddBuffer(m_hRecord, lpHdr, sizeof(WAVEHDR));
	}

	return;
}

void CAudioRec::OnEndThread(WPARAM wp,LPARAM lp)
{
//	TRACE("CAudioRec::OnEndThread()\n");
	if(recording)	OnStopRecording(0,0);

	::PostQuitMessage(0);
	return;
}

LPWAVEHDR  CAudioRec::CreateWaveHeader()
{
//	TRACE("CAudioRec::CreateWaveHeader()\n");
	LPWAVEHDR lpHdr = new WAVEHDR;
	if(lpHdr==NULL)		return NULL;
	
	ZeroMemory(lpHdr, sizeof(WAVEHDR));
	char* lpByte = new char[RECBUFFER+1];
	
	if(lpByte==NULL)	return NULL;

	lpHdr->lpData =  lpByte;
	lpHdr->dwBufferLength =RECBUFFER;
	return lpHdr;
}

⌨️ 快捷键说明

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