www.pudn.com > audioTest.rar > WaveIn.cpp


// WaveIn.cpp: implementation of the CWaveIn class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "WaveIn.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
double avg;// 
///////////////////////////////////////////////////////////////////// 
//当系统返回一个音频数据块时,系统调用回调函数,此时,hwi设置为录音设备句柄, 
//第二个参数是消息,一般为WIM_DATA;第三个参数则是在waveInOpen第五个参数中给出的 
//实例数据;其他参数是与消息有关的参数 
void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1, 
						 DWORD dwParam2)//系统反馈回来的消息通过这个指定函数来处理 
{ 
	switch(uMsg) 
	{ 
	case MM_WIM_DATA: 
		WAVEHDR *pWaveHdr = ((WAVEHDR*)dwParam1);//WAVEHDR为缓存格式 
		 
		CWaveIn *pWaveIn=(CWaveIn*)(pWaveHdr->dwUser);//dwUser为用户的数据 
		if(pWaveHdr && hwi && pWaveIn) 
		{ 
			if(pWaveHdr->dwFlags & (WHDR_DONE == WHDR_DONE))//缓存使用结束时,将缓存中的数据返回给应用程序 
			{ 
				pWaveHdr->dwFlags =0; 
				//在保存系统返回的音频数据之前,需要调用waveInUnprepareHeader发送一个通知 
				//告诉设备驱动程序该数据块已经不能用于录音 
				if(pWaveIn->IsError(waveInUnprepareHeader(hwi,pWaveHdr,sizeof(WAVEHDR)))) 
				{ 
					break; 
				} 
				if(pWaveHdr->dwBytesRecorded > 0) 
				{ 
					//pWaveIn->AddNewBuffer(pWaveHdr);//分析波形 
					//调用这个的时间差为:缓存大小/采样频率*最小数据格式大小 
					pWaveIn->BufferDill(pWaveHdr,dwInstance); 
				} 
				delete []pWaveHdr->lpData; 
				pWaveHdr->lpData=NULL; 
			} 
			if(!pWaveIn->ResetRequired(pWaveIn)) 
			{//给录音设备添加数据块以继续录音,否则会因为数据块耗尽而停止录音 
				if(!pWaveIn->AddNewHeader(hwi)) 
				{ 
					break; 
				} 
			} 
		} 
		break; 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
CWaveIn::CWaveIn(WAVEFORMATEX tagFormat,const CWaveDevice &aDevice):m_waveDevice(aDevice),\ 
		m_hWaveIn(0),m_nIndexWaveHdr(/*NUMWAVEINHDR-1*/-1),m_bResetRequired(true) 
{ 
	SetWaveFormat(tagFormat); 
	InitListOfHeader(); 
} 
CWaveIn::CWaveIn():m_hWaveIn(0),m_bResetRequired(true) 
{ 
	InitListOfHeader(); 
} 
 
CWaveIn::~CWaveIn() 
{ 
	Close(); 
	FreeListOfBuffer(); 
	FreeListOfHeader(); 
} 
////////////////////////////////////////////////////////// 
//Initialisation 
////////////////////////////////////////////////////////// 
void CWaveIn::SetDevice(const CWaveDevice &aDevice) 
{ 
	m_waveDevice = aDevice; 
} 
//////////////////////////////////////////// 
void CWaveIn::SetWaveFormat(WAVEFORMATEX tagFormat) 
{ 
	m_wave.BuildFormat(tagFormat.nChannels,tagFormat.nSamplesPerSec,tagFormat.wBitsPerSample); 
} 
 
void CWaveIn::regist(LPVOID wnd) 
{ 
	//m_wnd = (CWnd* )wnd; 
	m_wnd=(CWinThread*)wnd; 
} 
///////////////////////////////////////////// 
void CWaveIn::InitListOfHeader() 
{ 
	for(int i = 0; i < NUMWAVEINHDR;i++) 
	{ 
		m_tagWaveHdr[i].lpData=NULL; 
	} 
} 
/////////////////////////////////////////////////////// 
//son 
/////////////////////////////////////////////////////// 
bool CWaveIn::Close() 
{ 
	if(m_hWaveIn != NULL) 
	{ 
		if(!Stop()) 
		{ 
			return false; 
		} 
		if(IsError(waveInClose(m_hWaveIn))) 
		{ 
			return false; 
		} 
		m_hWaveIn =0; 
	} 
	return true; 
} 
////////////////////////////////////////////////////////// 
bool CWaveIn::Continue() 
{ 
	if(m_hWaveIn) 
	{ 
		return !IsError(waveInStart(m_hWaveIn)); 
	} 
	return true; 
} 
////////////////////////////////////// 
bool CWaveIn::Open() 
{ 
	return !IsError(waveInOpen(&m_hWaveIn,m_waveDevice.GetDevice(),&m_wave.GetFormat(),\ 
		(DWORD)waveInProc,m_waveDevice.GetDevice(),CALLBACK_FUNCTION)); 
} 
//////////////////////////////// 
bool CWaveIn::Pause() 
{ 
	if(m_hWaveIn) 
	{ 
		return !IsError(waveInStop(m_hWaveIn)); 
	} 
	return true; 
} 
///////////////////////////////////////// 
bool CWaveIn::Record(UINT nTaille/*=4096*/) 
{ 
	ASSERT(nTaille > 0); 
	ASSERT(m_hWaveIn); 
 
	if(!Stop()) 
	{ 
		return false; 
	} 
	m_bResetRequired = false; 
	FreeListOfBuffer(); 
	FreeListOfHeader(); 
	SetWaveFormat(m_wave.GetFormat()); 
	//m_nIndexWaveHdr = NUMWAVEINHDR-1; 
	m_nIndexWaveHdr=-1; 
	m_nBufferSize = nTaille; 
	for(int i =0 ; iCopyBuffer(pWaveHdr->lpData,\ 
		pWaveHdr->dwBytesRecorded/m_wave.GetFormat().nBlockAlign,\ 
		m_wave.GetFormat().nBlockAlign); 
 
	return true; 
} 
 
void CWaveIn::BufferDill(WAVEHDR *pWaveHdr,DWORD deviceNo) 
{ 
	wimm_data *wd=new wimm_data; 
	wd->len=pWaveHdr->dwBufferLength; 
	wd->data_buffer=new int[wd->len]; 
	wd->deviceNo=deviceNo; 
	 
	for(unsigned int dw=0;dw < wd->len; dw++) 
	{ 
		wd->data_buffer[dw]=(int)(pWaveHdr->lpData[dw]); 
	} 
	 
	//CWnd *cwnd = AfxGetApp()->GetMainWnd(); 
 
	bool postresul = m_wnd->PostThreadMessage(WM_MSG_1,(WPARAM)wd,0); 
} 
/////////////////////////// 
bool CWaveIn::AddNewHeader(HWAVEIN hwi) 
{ 
	ASSERT(m_nBufferSize > 0); 
	 
	m_nIndexWaveHdr++; 
	if(m_nIndexWaveHdr==NUMWAVEINHDR) 
		m_nIndexWaveHdr=0; 
	if(m_tagWaveHdr[m_nIndexWaveHdr].lpData==NULL) 
	{ 
		m_tagWaveHdr[m_nIndexWaveHdr].lpData=new char[m_nBufferSize]; 
	} 
	ZeroMemory(m_tagWaveHdr[m_nIndexWaveHdr].lpData,m_nBufferSize); 
	m_tagWaveHdr[m_nIndexWaveHdr].dwBufferLength=m_nBufferSize; 
	m_tagWaveHdr[m_nIndexWaveHdr].dwFlags=0; 
	m_tagWaveHdr[m_nIndexWaveHdr].dwUser=(DWORD)(void *)this; 
	//为录音设备配置数据块,而在此之前要调用waveInPrepareHeader准备数据块 
	if(IsError(waveInPrepareHeader(hwi,&m_tagWaveHdr[m_nIndexWaveHdr],sizeof(WAVEHDR)))) 
		return false;//第二个参数为描述数据块的结构WAVEHDR,第三个参数为该结构的大小 
	if(IsError(waveInAddBuffer(hwi,&m_tagWaveHdr[m_nIndexWaveHdr],sizeof(WAVEHDR)))) 
		return false; 
	return true; 
} 
/////////////////////////// 
void CWaveIn::FreeListOfHeader() 
{ 
	for(int i = 0 ; i GetNumSamples(); 
	} 
	return dwTotal; 
} 
CString CWaveIn::GetError() const 
{ 
	if(m_nError!=MMSYSERR_NOERROR) 
	{ 
		TCHAR szText[MAXERRORLENGTH+1]; 
		if(waveInGetErrorText(m_nError,szText,MAXERRORLENGTH)==MMSYSERR_NOERROR) 
			return szText; 
	} 
	return ""; 
} 
//////////////////////////////////////////////// 
DWORD CWaveIn::GetPosition() 
{ 
	if(m_hWaveIn) 
	{ 
		MMTIME mmt; 
		mmt.wType = TIME_SAMPLES; 
		if(IsError(waveInGetPosition(m_hWaveIn,&mmt,sizeof(MMTIME)))) 
			return -1; 
		else 
			return mmt.u.sample; 
	} 
	return -1; 
} 
bool CWaveIn::IsError(MMRESULT nResult) 
{ 
	m_nError= nResult; 
	return (m_nError !=MMSYSERR_NOERROR); 
} 
////////////////////////////////////////// 
bool CWaveIn::ResetRequired(CWaveIn *pWaveIn) 
{ 
	return m_bResetRequired; 
} 
bool CWaveIn::IsRecording() 
{ 
	bool bResult = false; 
	if(m_nIndexWaveHdr > -1&& m_tagWaveHdr[m_nIndexWaveHdr].dwFlags!=0) 
	{ 
		bResult|=!(m_tagWaveHdr[m_nIndexWaveHdr].dwFlags & (WHDR_DONE == WHDR_DONE)); 
	} 
	return bResult; 
} 
///////////////////////////////////////// 
CWave CWaveIn::MakeWave() 
{ 
	void *pBuffer = new char[GetNumSamples()*m_wave.GetFormat().nBlockAlign]; 
	DWORD dwPosInBuffer = 0L; 
	POSITION pos= m_listOfBuffer.GetHeadPosition(); 
	while(pos) 
	{ 
		CWaveBuffer *p_waveBuffer = (CWaveBuffer *)m_listOfBuffer.GetNext(pos); 
		CopyMemory((char*)pBuffer+dwPosInBuffer,p_waveBuffer->GetBuffer(),\ 
			p_waveBuffer->GetNumSamples()*p_waveBuffer->GetSampleSize()); 
		dwPosInBuffer+=p_waveBuffer->GetNumSamples()*p_waveBuffer->GetSampleSize(); 
	} 
	m_wave.SetBuffer(pBuffer,GetNumSamples()); 
	return m_wave; 
}