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

📄 windev.cpp

📁 evc编写的wave文件波形播放
💻 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 + -