www.pudn.com > WinceWave.rar > winDev.cpp


#include  
#include  
 
#include "waveinfo.h" 
#include "winDev.h" 
 
void prerecord(recctx *pctx) 
{ 
	long bps=1; 
 
	pctx->wfm.wFormatTag=WAVE_FORMAT_PCM; 
	pctx->wfm.cbSize=sizeof(WAVEFORMATEX); 
 
	pctx->wfm.nChannels=pctx->info.channel; 
	bps*=pctx->info.channel; 
	 
	pctx->wfm.wBitsPerSample=pctx->info.bitspersample; 
	bps*=(pctx->info.bitspersample >> 1); 
 
	pctx->wfm.nBlockAlign=(unsigned short)bps; 
 
	pctx->wfm.nSamplesPerSec=pctx->info.freq; 
	bps*=pctx->info.freq; 
 
	pctx->wfm.nAvgBytesPerSec=bps; 
} 
 
void CALLBACK waveinproc(HWAVEIN hwi, 
						 UINT uMsg, 
						 DWORD dwInstance, 
						 DWORD dwParam1, 
						 DWORD dwParam2) 
{ 
	recctx *pctx=(recctx *)dwInstance; 
 
	if(pctx == NULL || pctx->cbdatain == NULL) 
		return; 
 
	if(uMsg == WIM_DATA) 
	{ 
		WAVEHDR *pwh; 
 
		pwh=(WAVEHDR *)dwParam1; 
		pctx->cbdatain(pctx,(unsigned char *)pwh->lpData,pwh->dwBytesRecorded); 
 
		waveInPrepareHeader(pctx->hdev,pwh,sizeof(WAVEHDR)); 
		waveInAddBuffer(pctx->hdev,pwh,sizeof(WAVEHDR)); 
	} 
} 
 
int startrecord(recctx *pctx, 
				int	(*datainproc)(recctx *pctx,unsigned char *buf,int buflen)) 
{ 
	int i; 
	MMRESULT result; 
	 
	prerecord(pctx); 
	pctx->cbdatain=datainproc; 
 
	result=waveInOpen(&(pctx->hdev), 
					  pctx->devid, 
					  &(pctx->wfm), 
					  (unsigned long)waveinproc, 
					  (unsigned long)pctx, 
					  CALLBACK_FUNCTION); 
 
	if(result != MMSYSERR_NOERROR) 
		goto ERROR_END; 
 
	for(i=0;iwh+i,0,sizeof(WAVEHDR)); 
		pctx->wh[i].lpData=(char *)malloc(WAVEIN_BUF_SIZE); 
		pctx->wh[i].dwBufferLength=WAVEIN_BUF_SIZE; 
 
		//Prepare buffers 
		result=waveInPrepareHeader(pctx->hdev,pctx->wh+i,sizeof(WAVEHDR)); 
		if(result != MMSYSERR_NOERROR) 
			goto ERROR_END; 
 
		//Add buffers 
		result=waveInAddBuffer(pctx->hdev,pctx->wh+i,sizeof(WAVEHDR)); 
		if(result != MMSYSERR_NOERROR) 
			goto ERROR_END; 
	} 
 
	//Start recording 
	result=waveInStart(pctx->hdev); 
	if(result != MMSYSERR_NOERROR) 
		goto ERROR_END; 
 
	return 1; 
 
ERROR_END: 
	for(i=0;iwh[i].lpData != NULL) 
		{ 
			waveInUnprepareHeader(pctx->hdev,pctx->wh+i,sizeof(WAVEHDR)); 
			free(pctx->wh[i].lpData); 
		} 
	} 
	if(pctx->hdev != NULL) 
	{ 
		waveInClose(pctx->hdev); 
		pctx->hdev=NULL; 
	} 
	return 0; 
} 
 
int stoprecord(recctx *pctx) 
{ 
	int i; 
 
	if(pctx->hdev == NULL) 
		return 0; 
 
	MMRESULT result; 
 
	//Reset buffers 
	//result=waveInReset(pctx->hdev); 
 
	//Stop 
	result=waveInStop(pctx->hdev); 
 
	for(i=0;ihdev,pctx->wh+i,sizeof(WAVEHDR)); 
		free(pctx->wh[i].lpData); 
	} 
 
	//Close device 
	result=waveInClose(pctx->hdev); 
	pctx->hdev=NULL; 
 
	return 1; 
} 
 
void preplay(playctx *pctx) 
{ 
	long bps=1; 
 
	pctx->wfm.wFormatTag=WAVE_FORMAT_PCM; 
	pctx->wfm.cbSize=sizeof(WAVEFORMATEX); 
 
	pctx->wfm.nChannels=pctx->info.channel; 
	bps*=pctx->info.channel; 
	 
	pctx->wfm.wBitsPerSample=pctx->info.bitspersample; 
	bps*=(pctx->info.bitspersample >> 1); 
 
	pctx->wfm.nBlockAlign=(unsigned short)bps; 
 
	pctx->wfm.nSamplesPerSec=pctx->info.freq; 
	bps*=pctx->info.freq; 
 
	pctx->wfm.nAvgBytesPerSec=bps; 
 
	pctx->event=CreateEvent(NULL,FALSE,FALSE,NULL); 
} 
 
DWORD WINAPI waveoutloop(LPVOID param) 
{ 
	playctx *pctx=(playctx *)param; 
	int len; 
	int bs=0; 
 
	while(1) 
	{ 
		if(waveOutPrepareHeader(pctx->hdev,pctx->wh+bs,sizeof(WAVEHDR)) != MMSYSERR_NOERROR) 
			break; 
		len=pctx->cbdataout(pctx,(unsigned char *)pctx->wh[bs].lpData,WAVEOUT_BUF_SIZE); 
		if(len != 0) 
		{ 
			pctx->wh[bs].dwBufferLength=len; 
			if(WaitForSingleObject(pctx->event,INFINITE) == WAIT_OBJECT_0) 
			{ 
				waveOutWrite(pctx->hdev,pctx->wh,sizeof(WAVEHDR));// != MMSYSERR_NOERROR) 
				bs=1-bs; 
			} 
			else 
				break; 
		} 
	} 
 
	return 0; 
} 
 
void CALLBACK waveoutproc(HWAVEIN hwo, 
						  UINT uMsg, 
						  DWORD dwInstance, 
						  DWORD dwParam1, 
						  DWORD dwParam2) 
{ 
	playctx *pctx=(playctx *)dwInstance; 
 
	if(pctx == NULL || pctx->cbdataout == NULL) 
		return; 
 
	if(uMsg == WOM_DONE) 
	{ 
		WAVEHDR *pwh; 
 
		pwh=(WAVEHDR *)dwParam1; 
		//pctx->cbdataout(pctx,(unsigned char *)pwh->lpData,pwh->dwBytesRecorded); 
		SetEvent(pctx->event); 
	} 
} 
 
int startplay(playctx *pctx, 
			  unsigned long	(*dataproc)(playctx *pctx,unsigned char *buf,int buflen)) 
{ 
	int i; 
	MMRESULT result; 
 
	preplay(pctx); 
	pctx->cbdataout=dataproc; 
 
	result=waveOutOpen(&(pctx->hdev), 
					   pctx->devid, 
					   &(pctx->wfm), 
					   (unsigned long)waveoutproc, 
					   (unsigned long)pctx, 
					   CALLBACK_FUNCTION); 
 
	if(result != MMSYSERR_NOERROR) 
		goto ERROR_END; 
 
	//Alloc buffers 
	for(i=0;iwh+i,0,sizeof(WAVEHDR)); 
		pctx->wh[i].lpData=(char *)malloc(WAVEOUT_BUF_SIZE); 
		pctx->wh[i].dwBufferLength=WAVEOUT_BUF_SIZE; 
	} 
 
	pctx->thread=CreateThread(NULL, 
							  0, 
							  waveoutloop, 
							  pctx, 
							  0, 
							  NULL); 
 
	SetEvent(pctx->event); 
 
	return 1; 
 
ERROR_END: 
	for(i=0;iwh[i].lpData != NULL) 
		{ 
			free(pctx->wh[i].lpData); 
		} 
	} 
	if(pctx->hdev != NULL) 
	{ 
		waveOutClose(pctx->hdev); 
		pctx->hdev=NULL; 
	} 
	return 0; 
} 
 
int stopplay(playctx *pctx) 
{ 
	int i; 
 
	if(pctx->hdev == NULL) 
		return 0; 
 
	MMRESULT result; 
 
	result=waveOutReset(pctx->hdev); 
 
	//Unprepare and release buffers 
	for(i=0;ihdev,pctx->wh+i,sizeof(WAVEHDR)); 
	} 
 
	//Close device 
	result=waveOutClose(pctx->hdev); 
	for(i=0;iwh[i].lpData); 
	} 
 
	CloseHandle(pctx->event); 
	WaitForSingleObject(pctx->event,INFINITE); 
 
	pctx->hdev=NULL; 
 
	return 1; 
}