Win32 Wave API录音

录音流程:

waveInOpen -> waveInPrepareHeader -> waveInAddBuffer -> waveInStart -> waveInStop -> waveInReset ->waveInUnprepareHeader -> waveInClose

本次采用CALLBACK_EVENT方式,每次采集20ms数据,并且用WaitForSingleObject等待事件,每20ms写一次录音数据;一共录制20秒。

#include   
#include   
#pragma comment(lib, "winmm.lib")  

HWAVEIN hWaveIn;  //输入设备
WAVEFORMATEX waveform; //采集音频的格式,结构体
BYTE *pBuffer1;//采集音频时的数据缓存
WAVEHDR wHdr1; //采集音频时包含数据缓存的结构体
FILE *pf;
int main(int argc, char* argv[])
{
	HANDLE          wait_events;
	waveform.wFormatTag = WAVE_FORMAT_PCM;//声音格式为PCM
	waveform.nSamplesPerSec = 16000;//采样率,16000次/秒
	waveform.wBitsPerSample = 16;//采样比特,16bits/次
	waveform.nChannels = 1;//采样声道数,1声道
	waveform.nBlockAlign = 2;//一个块的大小
	waveform.nAvgBytesPerSec = waveform.nSamplesPerSec * waveform.nBlockAlign;//每秒的数据率,就是每秒能采集多少字节的数据
	waveform.cbSize = 0;//一般为0

	wait_events = CreateEvent(NULL, 0, 0, NULL);
	//使用waveInOpen函数开启音频采集
	int ret = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD_PTR)wait_events, 0L, CALLBACK_EVENT);
	
	//本例采用20ms打包时长,一次获取20ms音频数据
	DWORD bufsize = waveform.nAvgBytesPerSec * 20 / 1000;//每次开辟20ms的缓存存储录音数据
	
	fopen_s(&pf, "test.pcm", "wb");
	DWORD dwEvent;

	pBuffer1 = new BYTE[bufsize];
	wHdr1.lpData = (LPSTR)pBuffer1;
	wHdr1.dwBufferLength = bufsize;
	wHdr1.dwBytesRecorded = 0;
	wHdr1.dwUser = 0;
	wHdr1.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;;
	wHdr1.dwLoops = 1;
	
	ret = waveInStart(hWaveIn);//开始录音

	DWORD dwLastInterval = 0;

	DWORD dwTick1 = GetTickCount();

	int nMaxCount = 1000;//1000个打包时长,就是20秒数据
	int i = 0;
	while (i++ < nMaxCount)
	{
		dwEvent = WaitForSingleObject( wait_events, INFINITE);

		if (wHdr1.dwBytesRecorded > 0)
		{
			fwrite(pBuffer1, 1, wHdr1.dwBytesRecorded, pf);

			//获取当前时间
			DWORD dwInterval = 0;
			DWORD dwCurTick = GetTickCount();
			dwInterval = dwCurTick - dwLastInterval;
			printf("%d  dwInterval=%ld\r\n", i, dwInterval);
			dwLastInterval = dwCurTick;
		}
		else
		{
			printf("no recorded data");
		}

		ret = waveInPrepareHeader(hWaveIn, &wHdr1, sizeof(WAVEHDR));//准备一个波形数据块头用于录音
		ret = waveInAddBuffer(hWaveIn, &wHdr1, sizeof(WAVEHDR));//指定波形数据块为录音输入缓存
	}
	DWORD dwTick2 = GetTickCount();
	printf("used times = %ld\n", dwTick2 - dwTick1);

	waveInReset(hWaveIn);//停止录音
	delete pBuffer1;
	fclose(pf);

	waveInClose(hWaveIn);
	return 0;
}

Win32 Wave API录音_第1张图片

可以看出来,每次采集间隔并不是固定的20ms,非常不均匀。但是20秒的时间内,总数上,是相差不大。

你可能感兴趣的:(音视频开发学习)