📄 windev.cpp
字号:
#include <windows.h>
#include <mmsystem.h>
#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<WAVEIN_BUF_NUM;i++)
{
//Alloc buffers
memset(pctx->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<WAVEIN_BUF_NUM;i++)
{
if(pctx->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<WAVEIN_BUF_NUM;i++)
{
//Unprepare and release buffers
waveInUnprepareHeader(pctx->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<WAVEOUT_BUF_NUM;i++)
{
memset(pctx->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<WAVEOUT_BUF_NUM;i++)
{
if(pctx->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<WAVEOUT_BUF_NUM;i++)
{
waveOutUnprepareHeader(pctx->hdev,pctx->wh+i,sizeof(WAVEHDR));
}
//Close device
result=waveOutClose(pctx->hdev);
for(i=0;i<WAVEOUT_BUF_NUM;i++)
{
free(pctx->wh[i].lpData);
}
CloseHandle(pctx->event);
WaitForSingleObject(pctx->event,INFINITE);
pctx->hdev=NULL;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -