录音流程:
waveInOpen -> waveInPrepareHeader -> waveInAddBuffer -> waveInStart -> waveInStop -> waveInReset ->waveInUnprepareHeader -> waveInClose
本次采用CALLBACK_EVENT方式,每次采集20ms数据,并且用WaitForSingleObject等待事件,每20ms写一次录音数据;一共录制20秒。
#include <stdio.h>
#include <Windows.h>
#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;
}
可以看出来,每次采集间隔并不是固定的20ms,非常不均匀。但是20秒的时间内,总数上,是相差不大。