[英]Why the recorded audio data only use half of the buffer (WaveIn)?
I'm trying to record audio data from the microphone and save in files.我正在尝试从麦克风录制音频数据并保存在文件中。 The problem is that the wavein device only uses half the buffer specified in the wave header.
问题是wavein 设备只使用wave 头中指定的缓冲区的一半。 In particular, only first 2000 points in the file from the audio, the rest of the file reads like the following
特别是,音频文件中只有前 2000 个点,文件的其余部分如下所示
-12851
-12851
-12851
-12851
.....
Not clear what goes wrong.不清楚出了什么问题。 What I find is that if I change the following line of code from
我发现如果我更改以下代码行
_header[i].dwBufferLength = bpbuff;
to到
_header[i].dwBufferLength = 2*bpbuff;
then all 4000 values are indeed the audio input.那么所有 4000 个值确实是音频输入。 But obviously this is not the right way to get the problem fixed.
但显然这不是解决问题的正确方法。 Any thoughts?
有什么想法吗?
Here's the full code:这是完整的代码:
#include "stdafx.h"
#include <Windows.h>
#pragma comment(lib, "winmm.lib")
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
HANDLE hEvent_BufferReady;
#define Samplerate 2000
#define nSec 3
BOOL BufferReady;
enum { NUM_BUF = 8 };
int _iBuf;
int prevBuf;
void CALLBACK myWaveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
WAVEHDR *pHdr=NULL;
switch(uMsg)
{
case WIM_CLOSE:
cout << "waveInProc()... WIM_CLOSE" << endl;
break;
case WIM_DATA:
{
cout << "waveInProc()... WIM_DATA : " <<endl;
SetEvent(hEvent_BufferReady);
}
break;
case WIM_OPEN:
cout << "waveInProc()... WIM_OPEN" << endl;
break;
default:
break;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
hEvent_BufferReady=CreateEvent(NULL,FALSE, FALSE, NULL);
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM; // simple, uncompressed format
pFormat.nChannels = 1; // 1=mono, 2=stereo
pFormat.nSamplesPerSec = Samplerate; // 44100
pFormat.wBitsPerSample = 16; // 16 for high quality, 8 for telephone-grade
pFormat.nBlockAlign = pFormat.nChannels*pFormat.wBitsPerSample/8;
pFormat.nAvgBytesPerSec = (pFormat.nSamplesPerSec)*(pFormat.nChannels)*(pFormat.wBitsPerSample)/8;
pFormat.cbSize=0;
HWAVEIN hWaveIn;
unsigned long result;
WAVEHDR _header [NUM_BUF];
short int *_pBuf;
size_t bpbuff = (pFormat.nSamplesPerSec) * (pFormat.nChannels) * (pFormat.wBitsPerSample)/8;
result = waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat, (DWORD)myWaveInProc, 0L, CALLBACK_FUNCTION);
_pBuf = new short int [bpbuff * NUM_BUF];
// initialize all headers in the queue
for ( int i = 0; i < NUM_BUF; i++ )
{
_header[i].lpData = (LPSTR)&_pBuf [i * bpbuff];
_header[i].dwBufferLength = bpbuff;
_header[i].dwFlags = 0L;
_header[i].dwLoops = 0L;
waveInPrepareHeader(hWaveIn, & _header[i], sizeof(WAVEHDR));
waveInAddBuffer (hWaveIn, & _header[i], sizeof (WAVEHDR));
}
_iBuf = 0;
int _prevBuf = NUM_BUF - 1;
unsigned char* tempchar;
waveInStart(hWaveIn);
for(int iter=0;iter<5;iter++)
{
do {
} while (!(_header[_iBuf].dwFlags & WHDR_DONE));
waveInUnprepareHeader (hWaveIn, &_header[_iBuf], sizeof (WAVEHDR));
std::ostringstream fn;
fn << "file" << iter << ".txt";
ofstream myfile;
myfile.open (fn.str());
for(int i=0;i<bpbuff;i++)
{
myfile<<_pBuf[_iBuf*bpbuff + i]<<"\n";
}
myfile.close();
int prevBuf = _iBuf - 1;
if (prevBuf < 0)
prevBuf = NUM_BUF - 1;
_header [prevBuf].lpData = (LPSTR)&_pBuf [prevBuf * bpbuff];
_header [prevBuf].dwBufferLength = bpbuff;
_header [prevBuf].dwFlags = 0L;
_header [prevBuf].dwLoops = 0L;
waveInPrepareHeader(hWaveIn, & _header[_iBuf], sizeof(WAVEHDR));
waveInAddBuffer (hWaveIn, & _header[_iBuf], sizeof (WAVEHDR));
++_iBuf;
if (_iBuf == NUM_BUF) _iBuf = 0;
}
waveInClose(hWaveIn);
cout<<"hello"<<endl;
getchar();
CloseHandle(hEvent_BufferReady);
return 0;
}
WAVEHDR::dwBufferLength
: WAVEHDR::dwBufferLength
:
dwBufferLength
- Length, in bytes, of the buffer.dwBufferLength
- 缓冲区的长度,以字节为单位。
Your code:您的代码:
_pBuf = new short int [bpbuff * NUM_BUF];
// initialize all headers in the queue
for ( int i = 0; i < NUM_BUF; i++ )
{
_header[i].lpData = (LPSTR)&_pBuf [i * bpbuff];
_header[i].dwBufferLength = bpbuff;
Your buffer is bpbuff * sizeof (short int)
bytes long.您的缓冲区是
bpbuff * sizeof (short int)
字节长。 However you route it to the API to get it filled with bpbuff
bytes of data only.但是,您将其路由到 API 以使其仅填充
bpbuff
字节的数据。 Hence, the buffer is only filled partially and the rest of it holds uninitialized data (which you see as -12851, see 0xCDCDCDCD
).因此,缓冲区仅部分填充,其余部分保存未初始化的数据(您将其视为 -12851,请参阅
0xCDCDCDCD
)。
You need to make it:你需要做到:
_header[i].dwBufferLength = bpbuff * sizeof *_pBuf;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.