Win32 Wave API录音

    技术2023-11-23  96

    录音流程:

    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秒的时间内,总数上,是相差不大。

    Processed: 0.008, SQL: 9