Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CreateEvent / WaveForm API

29 views
Skip to first unread message

Larry

unread,
Dec 25, 2009, 8:48:58 PM12/25/09
to
> If you use CALLBACK_EVENT then create an event with CreateEvent, pass
> the event handle in dwCallback, and wait for the recording to finish
> by calling WaitForSingleObject with the event handle.
> WaitForSingleObject will suspend your code until the buffer has been
> filled, then it will return.

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

ScottMcP [MVP]

unread,
Dec 25, 2009, 10:40:50 PM12/25/09
to

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.

Larry

unread,
Dec 26, 2009, 1:16:37 PM12/26/09
to
"ScottMcP [MVP]" <scot...@mvps.org> ha scritto nel messaggio
news:4c1e1254-2c4f-4fd5...@n13g2000vbe.googlegroups.com...


> 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

ScottMcP [MVP]

unread,
Dec 26, 2009, 1:58:27 PM12/26/09
to
On Dec 26, 1:16 pm, "Larry" <dontmewit...@got.it> wrote:
> "ScottMcP [MVP]" <scott...@mvps.org> ha scritto nel messaggionews:4c1e1254-2c4f-4fd5...@n13g2000vbe.googlegroups.com...

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.)

Larry

unread,
Dec 26, 2009, 2:44:03 PM12/26/09
to
"ScottMcP [MVP]" <scot...@mvps.org> ha scritto nel messaggio
news:b064d2c6-57ab-4fe1...@r12g2000vbm.googlegroups.com...

> 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 :-(


Larry

unread,
Dec 26, 2009, 2:52:00 PM12/26/09
to

"Larry" <dontme...@got.it> ha scritto nel messaggio
news:4b366783$0$1101$4faf...@reader4.news.tin.it...

> 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)

ScottMcP [MVP]

unread,
Dec 26, 2009, 4:47:47 PM12/26/09
to
On Dec 26, 2:52 pm, "Larry" <dontmewit...@got.it> wrote:
> "Larry" <dontmewit...@got.it> ha scritto nel messaggionews:4b366783$0$1101$4faf...@reader4.news.tin.it...

> 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
}

Larry

unread,
Dec 26, 2009, 5:53:15 PM12/26/09
to

"ScottMcP [MVP]" <scot...@mvps.org> ha scritto nel messaggio
news:94552def-7e53-4df9...@e20g2000vbb.googlegroups.com...

> 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

Larry

unread,
Dec 28, 2009, 6:14:21 PM12/28/09
to

"ScottMcP [MVP]" <scot...@mvps.org> ha scritto nel messaggio
news:4c1e1254-2c4f-4fd5...@n13g2000vbe.googlegroups.com...

> 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

ScottMcP [MVP]

unread,
Dec 28, 2009, 8:14:58 PM12/28/09
to
On Dec 28, 6:14 pm, "Larry" <dontmewit...@got.it> wrote:
> "ScottMcP [MVP]" <scott...@mvps.org> ha scritto nel messaggionews:4c1e1254-2c4f-4fd5...@n13g2000vbe.googlegroups.com...

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

Larry

unread,
Dec 28, 2009, 8:40:35 PM12/28/09
to
"ScottMcP [MVP]" <scot...@mvps.org> ha scritto nel messaggio
news:b62210f2-5aec-4c9a...@u20g2000vbq.googlegroups.com...

> 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

Larry

unread,
Dec 28, 2009, 8:51:01 PM12/28/09
to
"Larry" <dontme...@got.it> ha scritto nel messaggio
news:4b395e13$0$814$4faf...@reader5.news.tin.it...

> "ScottMcP [MVP]" <scot...@mvps.org> ha scritto nel messaggio

> 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/

0 new messages