2016-04-17 5 views
-1

Ich versuche, Audiodaten vom Mikrofon aufzunehmen und in Dateien zu speichern. Das Problem ist, dass das Wavein-Gerät nur die Hälfte des im Wave-Header angegebenen Puffers verwendet. Insbesondere nur erste 2000 Punkte in der Datei aus dem Audio liest der Rest der Datei wie folgtWarum verwenden die aufgenommenen Audiodaten nur die Hälfte des Puffers (WaveIn)?

-12851 
-12851 
-12851 
-12851 
..... 

nicht klar, was schief geht. Was ich finde, ist, dass, wenn ich die folgende Codezeile aus

_header[i].dwBufferLength = bpbuff; 

zu

_header[i].dwBufferLength = 2*bpbuff; 

dann alle 4000 Werte sind in der Tat der Audioeingang ändern. Aber offensichtlich ist das nicht der richtige Weg, um das Problem zu beheben. Irgendwelche Gedanken?

Hier ist der vollständige 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; 
} 
+0

, der wie ein Puffer klingt überrannt oder andere UB. Haben Sie versucht, Ihr Programm zu debuggen? Das Problem auf ein paar Zeilen Code reduzieren? –

+0

Okay, dann weißt du es am besten. –

Antwort

1

WAVEHDR::dwBufferLength:

dwBufferLength - Länge in Bytes des Puffers.

Ihr 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; 

Ihr Puffer ist bpbuff * sizeof (short int) Byte lang. Sie leiten es jedoch an die API weiter, damit es nur mit bpbuff Datenbytes gefüllt wird. Daher wird der Puffer nur teilweise gefüllt und der Rest enthält nicht initialisierte Daten (die Sie als -12851 sehen, siehe 0xCDCDCDCD).

Sie müssen es machen:

_header[i].dwBufferLength = bpbuff * sizeof *_pBuf; 
+0

Das behebt genau das Problem. Ich vermutete, dass dies mit dem Datentyp zu tun hat und experimentierte mit dem Datentyp ein wenig, hatte aber kein klares Verständnis darüber, was dwBuferLength wirklich sein muss. Danke! – Andy

Verwandte Themen