简体   繁体   English

为什么录制的音频数据只使用一半的缓冲区(WaveIn)?

[英]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.

相关问题 使用 waveIn 和 waveOut 在 windows 中进行录音和实时播放 - audio recording and real-time playing in windows using waveIn and waveOut 为什么 sprintf 只转换了我的 uint64_t 数据的一半? - Why is the sprintf converting only half of my uint64_t data? Mbed CAN网络仅获得一半的数据 - Mbed CAN network only gets half the data Android OpenSL音频缓冲区欠载,具有本机采样率/缓冲区大小(仅限部分设备) - Android OpenSL Audio Buffer underrun with native sample rate/buffer size (only some devices) 为什么 SDL2 提供的缓冲区,对于音频样本,不够大? - Why the buffer provided by SDL2, for audio samples, is not big enough? Core Audio Ring Buffer Data 出现空白 - Core Audio Ring Buffer Data comes out blank DirectX11仅在填充的索引和顶点缓冲区中绘制一半的顶点 - DirectX11 only draws half of the vertices in a populated index and vertex buffer 缓冲区很长,但仅使用最后1GB字节的数据。 - Have a very long buffer but only use the last 1GB bytes of data. 为什么我的Magic Square算法只能找到一半可能的解决方案? - Why is my Magic Square algorithm only finding half of the possible solutions? 限制音频缓冲区的大小 - Limiting the size of an audio buffer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM