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;i wh+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;i wh[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;i hdev,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;i wh+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;i wh[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;i hdev,pctx->wh+i,sizeof(WAVEHDR)); } //Close device result=waveOutClose(pctx->hdev); for(i=0;i wh[i].lpData); } CloseHandle(pctx->event); WaitForSingleObject(pctx->event,INFINITE); pctx->hdev=NULL; return 1; }