Ok, I can I catch the data? I mean, if I create an event and wait for its
response with "WaitForSingleObject" I no longer have the parameters I used
to with the regular CALLBACK.
Let me explain with the following code:
**code
HANDLE hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
HWAVEIN hwi;
waveInOpen(&hwi,0,(LPWAVEFORMATEX)&pwf,(DWORD)hEvent,0,CALLBACK_EVENT );
waveInPrepareHeader(...);
waveInAddBuffer(...);
waveInStart(hwi);
ResetEvent(hEvent); // Should I?
while(1)
{
WaitForSingleObject(event, INFINITE);
...process buffer...how can?...
waveInAddBuffer(...);
}
**code
From where should I get the lpData end other flags ??
thanks
You allocated all the WAVEINHDR structs and the lpData. Don't lose
track of them. After all, you're supposed to delete them later, when
you're finished.
The dwUser field in WAVEINHDR can be used by you. For example, put a
0 in there for buffer 0, a 1 in there for buffer 1, etc.
When WaitForSingleObject returns you are going to have to assume which
buffer finished. Of course, if you have a nextbuffernumber counter
that starts at zero you can use that. Make it an index into wherever
your array of WAVEINHDR is.
> You allocated all the WAVEINHDR structs and the lpData. Don't lose
> track of them. After all, you're supposed to delete them later, when
> you're finished.
> The dwUser field in WAVEINHDR can be used by you. For example, put a
> 0 in there for buffer 0, a 1 in there for buffer 1, etc.
> When WaitForSingleObject returns you are going to have to assume which
> buffer finished. Of course, if you have a nextbuffernumber counter
> that starts at zero you can use that. Make it an index into wherever
> your array of WAVEINHDR is.
Ok. Suppose I am just using ONE single buffer. Hopefully it'll help me
understand better!
The recording function is called with CreateThread() and the following is
its code:
DWORD WINAPI start_recorder(const LPVOID lpParam)
{
// Define WAVEFORMATEX
WAVEFORMATEX wf;
(...)
// I pass to the waveInOpen() function the "hevent" HANDLE to an event a
created with,
// CreateEvent(NULL, TRUE, TRUE, NULL); in the main(); Its HANDLE (hevent)
is global.
waveInOpen(&hwi,0,(LPWAVEFORMATEX)&wf,(DWORD)hevent,0,CALLBACK_EVENT);
// Define WAVEHDR Structure:
WAVEHDR *buff = new (WAVEHDR);
buff->lpData = (LPSTR) malloc(system_buf_len);
buff->dwBufferLength = system_buf_len;
buff->dwBytesRecorded = 0;
//Prepare, add and Start
waveInPrepareHeader(hwi, buff, sizeof(WAVEHDR));
waveInAddBuffer(hwi, buff, sizeof(WAVEHDR));
waveInStart(hwi);
//ResetEvent()
ResetEvent(hevent);
//Loop...
while(1)
{
WaitForSingleObject(hevent, INFINITE);
if (buff->dwFlags)
{
printf("%d", buff->dwBytesRecorded); printf("\n");
}
waveInAddBuffer(hwi,buff, sizeof(WAVEHDR));
if(stop_thread_flag)
break;
}
}
waveInClose(hwi);
return 0;
} // end function
is this correct approach?? NB. in buff->dwBytesRecorded I am getting
differents values each time...I thought I'd get 32768 always...
Anyway, you can have a view at the whole code here:
http://theartofweb.net/cpp/recorder.txt
thanks
I see only a couple of small problems. You don't show any
initialization of buff->dwFlags but your code tests it for some
reason. And you have set the event to manual reset, so it needs a
ResetEvent call right after WaitForSingleObject returns. (Or use
CreateEvent(NULL, 0, 0, NULL) so you don't need to ever reset it.)
> I see only a couple of small problems. You don't show any
> initialization of buff->dwFlags but your code tests it for some
> reason. And you have set the event to manual reset, so it needs a
> ResetEvent call right after WaitForSingleObject returns. (Or use
> CreateEvent(NULL, 0, 0, NULL) so you don't need to ever reset it.)
I'm sorry that's because I was writing fast to the group!
Actually, I did initializate buff->dwFlags to "0".
Anyway, now that I am using CreateEvent(NULL,0,0,NULL) it is working!
// Loop...
while(1)
{
WaitForSingleObject(hevent, INFINITE);
save_buffer(buff);
waveInAddBuffer(hwi, buff, sizeof(WAVEHDR));
if(stop_thread_flag)
break;
}
waveInClose(hwi);
return 0;
}
VOID save_buffer(WAVEHDR *pWaveHdr)
{
printf("%d", pWaveHdr->dwBytesRecorded); printf("\n");
}
Yet, this is using just one single buffer :-(
> I'm sorry that's because I was writing fast to the group!
One more thing...I don't seem to be getting the WHDR_DONE...ever! instead
the first time I get 18 then only 3...what's the matter?
thanks (window vista)
You are getting WHDR_DONE but you're not testing for it correctly.
WHDR_DONE is the 0x01 bit, which is part of 0x03.
if (buff->dwFlags & WHDR_DONE)
{ ...header is done
}
> You are getting WHDR_DONE but you're not testing for it correctly.
> WHDR_DONE is the 0x01 bit, which is part of 0x03.
> if (buff->dwFlags & WHDR_DONE)
> { ...header is done
> }
Perfect! anyway, I wonder what's the use of WHDR_DONE now that thru the
CALLBACK_EVENT I get the signal when the buffer is filled by the sistem!
Just for the record now this is the code:
{
...
while(1)
{
WaitForSingleObject(hevent, INFINITE);
if(buff->dwFlags & WHDR_DONE)
{
save_buffer(buff);
waveInAddBuffer(hwi, buff, sizeof(WAVEHDR));
}
if(stop_thread_flag)
break;
}
waveInUnprepareHeader(hwi, buff, sizeof(WAVEHDR));
waveInClose(hwi);
return 0;
};
thenks
> You allocated all the WAVEINHDR structs and the lpData. Don't lose
> track of them. After all, you're supposed to delete them later, when
> you're finished.
> The dwUser field in WAVEINHDR can be used by you. For example, put a
> 0 in there for buffer 0, a 1 in there for buffer 1, etc.
> When WaitForSingleObject returns you are going to have to assume which
> buffer finished. Of course, if you have a nextbuffernumber counter
> that starts at zero you can use that. Make it an index into wherever
> your array of WAVEINHDR is.
Do you think I could check out every buffer right after the
WaitForSingleObject? something like the following:
// Loop...
while(1)
{
WaitForSingleObject(hevent, INFINITE);
for (int k = 0; k<num_buffers; k++)
{
if(buff[k].dwFlags & WHDR_DONE)
{
save_buffer(&buff[k]);
waveInAddBuffer(hwi, &buff[k], sizeof(WAVEHDR));
}
}
if(stop_thread_flag)
break;
}
for (int u = 0; u<num_buffers; u++)
{
waveInUnprepareHeader(hwi, &buff[u], sizeof(WAVEHDR));
}
waveInClose(hwi);
return 0;
Do you think this is the right approach? I tested the code and it seems to
be working great though.
thanks
It seems fine to do it that way. I think you could get by just fine
without the checks though, because the buffers will be filled in the
same order you output them. So a counter variable would be needed,
like
save_buffer(&buff[k]);
waveInAddBuffer(hwi, &buff[k], sizeof(WAVEHDR));
k++;
> It seems fine to do it that way. I think you could get by just fine
> without the checks though, because the buffers will be filled in the
> same order you output them. So a counter variable would be needed,
> like
Oh my, I never thought of it like that!
do you think the following would be good?
int k = 0;
while(1)
{
if(stop_thread_flag)
break;
// CALLBACK EVENT
WaitForSingleObject(hevent, INFINITE);
if(buff[k].dwFlags & WHDR_DONE)
{
save_buffer(&buff[k]);
waveInAddBuffer(hwi, &buff[k], sizeof(WAVEHDR));
}
if(k == num_buffers -1)
k = 0;
else
k++;
}
for (int u = 0; u<num_buffers; u++)
{
waveInUnprepareHeader(hwi, &buff[u], sizeof(WAVEHDR));
}
waveInClose(hwi);
return 0;
I tried the code and it seems I am experiencing some sort of delay so maybe
that's proove it is working!
thanks
> I tried the code and it seems I am experiencing some sort of delay so
> maybe that's proove it is working!
By the way the whole code is avaible here: http://theartofweb.net/cpp/