c++ - audio recording and real-time playing in windows using waveIn and waveOut -
i want record microphone audio input and, small time delay, play recorded sound immediately. done continuously using queue of buffers.
i got code running point continuously plays microphone audio input, there short still noticeable repeated pauses throughout whole audio output using waveout. causing these annoying pauses? , how remove them?
another question is, i'm not using thing mutex, i'm relying on fact wavein , waveout have same sampling rate , same amount of data, waveout follows wavein , wavein not write buffer being played. problem?
here's code, should compile , run. made code run, , it's far being written. comment on improving code highly welcome.
#include "stdafx.h" #include <windows.h> #pragma comment(lib, "winmm.lib") #include <iostream> #include <fstream> #include <sstream> using namespace std; handle hevent_bufferready; handle hevent_finishedplaying; #define samplerate 44100 #define nsec 1 int _ibuf; int _iplaying; unsigned long result; hwavein hwavein; hwaveout hwaveout; waveformatex pformat; enum { num_buf = 3 }; wavehdr _header [num_buf]; dword winapi recordingwaitingthread(lpvoid ivalue) { while(1) { waitforsingleobject(hevent_bufferready,infinite); result = waveinunprepareheader (hwavein, &_header[_ibuf], sizeof (wavehdr)); _iplaying = _ibuf; result = waveoutprepareheader(hwaveout, &_header[_ibuf], sizeof(wavehdr)); result = waveoutwrite(hwaveout, &_header[_ibuf], sizeof(wavehdr)); // play audio ++_ibuf; if (_ibuf == num_buf) _ibuf = 0; result = waveinprepareheader(hwavein, & _header[_ibuf], sizeof(wavehdr)); result = waveinaddbuffer (hwavein, & _header[_ibuf], sizeof (wavehdr)); } return 0; } dword winapi playingwaitingthread(lpvoid ivalue) { while(1){ waitforsingleobject(hevent_finishedplaying,infinite); waveoutunprepareheader(hwaveout, &_header[_iplaying], sizeof(wavehdr)); } } static void callback waveoutproc(hwaveout hwaveout, uint umsg, dword dwinstance, dword dwparam1,dword dwparam2 ) { if(umsg != wom_done) return; setevent(hevent_finishedplaying); } void callback mywaveinproc(hwavein hwi, uint umsg, dword dwinstance, dword dwparam1, dword dwparam2) { if(umsg != wim_data) return; setevent(hevent_bufferready); } int main(int argc, _tchar* argv[]) { hevent_bufferready=createevent(null,false, false, null); hevent_finishedplaying = createevent(null,false, false, null); pformat.wformattag = wave_format_pcm; // simple, uncompressed format pformat.nchannels = 1; // 1=mono, 2=stereo pformat.nsamplespersec = samplerate; pformat.wbitspersample = 16; // 16 high quality, 8 telephone-grade pformat.nblockalign = pformat.nchannels*pformat.wbitspersample/8; pformat.navgbytespersec = (pformat.nsamplespersec)*(pformat.nchannels)*(pformat.wbitspersample)/8; pformat.cbsize=0; short int *_pbuf; size_t bpbuff =4000;//= (pformat.nsamplespersec) * (pformat.nchannels) * (pformat.wbitspersample)/8; _pbuf = new short int [bpbuff * num_buf]; result = waveinopen(&hwavein, wave_mapper,&pformat, (dword)mywaveinproc, 0l, callback_function); result = waveoutopen(&hwaveout, wave_mapper, &pformat, (dword_ptr)waveoutproc, 0, callback_function); // initialize headers in queue ( int = 0; < num_buf; i++ ) { _header[i].lpdata = (lpstr)&_pbuf [i * bpbuff]; _header[i].dwbufferlength = bpbuff*sizeof(*_pbuf); _header[i].dwflags = 0l; _header[i].dwloops = 0l; } dword mythreadid; dword mythreadidplay; handle hthread; handle hthreadplay; hthread = createthread(null, 0, recordingwaitingthread,null,0,&mythreadid); hthreadplay = createthread(null, 0, playingwaitingthread,null,0,&mythreadidplay); _ibuf = 0; waveinprepareheader(hwavein, & _header[_ibuf], sizeof(wavehdr)); waveinaddbuffer (hwavein, & _header[_ibuf], sizeof (wavehdr)); waveinstart(hwavein); getchar(); waveinclose(hwavein); waveoutclose(hwaveout); closehandle(hthread); closehandle(hthreadplay); closehandle(hevent_bufferready); closehandle(hevent_finishedplaying); return 0; }
Comments
Post a Comment