Discussion:
On second wave playback WAVEHDR dwFlags never get to WHDR_DONE
(too old to reply)
Angus Comber
2005-06-15 20:33:13 UTC
Permalink
Hello

Strange problem. My code runs just fine on Windows XP. But I also need to
get working on Windows 2000. My program plays a wav file then records a
message - but it does it repeatedly five times - so recording five voice
files.

On Windows 2000 it plays the first file, records to a file then on second
playback I check for a WHDR_DONE before preparing and waveOutWrite. But
never get a WHDR_DONE. Get instead 18 which is WHDR_ENDLOOP and
WHDR_INQUEUE.

It is strange that my code fine works with exactly the same voice board on
my development machine. But get this problem on a Windows 2000 machine. I
have even installed my C++ dev environment on the 2000 machine so same sort
of files loaded.

Any ideas on what I should be looking at?

Angus Comber
Dave
2005-06-15 22:45:55 UTC
Permalink
ah yes, someone else has found one of the subtle differences between
winmm.dll (i think thats where it hides) in xp and 2k... and if you try on
win98 you will find more. xp is much more forgiving and lets you do nice
things with swapping around buffers that just don't work the same way in 2k
and fail completely in 98. in xp i had a playback working fine... took the
same code to 2k and it wouldn't play or would crash the ocx process. fixed
that and in 98 it still wouldn't work, had to fix the same area again. the
one that got me was in xp you could set the lpdata member of the header to a
NULL and init the header, then plug in a pointer to the actual data out of a
buffer later on, and just keep changing the pointer when you refilled each
block. in w2k you have to point lpdata to a real location when you prepare
the header... but then it lets you reassign lpdata later on to point into a
different buffer. in 98 its even pickier, you can't change lpdata after you
prepare, you have to copy the data into the buffer or unprepare and
re-prepare the header with the new buffer.
Post by Angus Comber
Hello
Strange problem. My code runs just fine on Windows XP. But I also need to
get working on Windows 2000. My program plays a wav file then records a
message - but it does it repeatedly five times - so recording five voice
files.
On Windows 2000 it plays the first file, records to a file then on second
playback I check for a WHDR_DONE before preparing and waveOutWrite. But
never get a WHDR_DONE. Get instead 18 which is WHDR_ENDLOOP and
WHDR_INQUEUE.
It is strange that my code fine works with exactly the same voice board on
my development machine. But get this problem on a Windows 2000 machine.
I
have even installed my C++ dev environment on the 2000 machine so same sort
of files loaded.
Any ideas on what I should be looking at?
Angus Comber
Angus Comber
2005-06-16 09:01:11 UTC
Permalink
I expected 2000 to be the same ... and it wasn't! I developed the
application on Windows XP and delivered on Windows 2000. (well not yet
delivered). About a week ago I thought the job was finished... oh well,
that's programming!

Yes it is working OK on 2000 now. I will have to test it on 98 just to see
what happens.

Interesting about the prepare/unprepare bit about buffers. Your tip no
doubt will save me many an hour.

Angus
Post by Dave
ah yes, someone else has found one of the subtle differences between
winmm.dll (i think thats where it hides) in xp and 2k... and if you try on
win98 you will find more. xp is much more forgiving and lets you do nice
things with swapping around buffers that just don't work the same way in 2k
and fail completely in 98. in xp i had a playback working fine... took the
same code to 2k and it wouldn't play or would crash the ocx process.
fixed
Post by Dave
that and in 98 it still wouldn't work, had to fix the same area again.
the
Post by Dave
one that got me was in xp you could set the lpdata member of the header to a
NULL and init the header, then plug in a pointer to the actual data out of a
buffer later on, and just keep changing the pointer when you refilled each
block. in w2k you have to point lpdata to a real location when you prepare
the header... but then it lets you reassign lpdata later on to point into a
different buffer. in 98 its even pickier, you can't change lpdata after you
prepare, you have to copy the data into the buffer or unprepare and
re-prepare the header with the new buffer.
Post by Angus Comber
Hello
Strange problem. My code runs just fine on Windows XP. But I also need to
get working on Windows 2000. My program plays a wav file then records a
message - but it does it repeatedly five times - so recording five voice
files.
On Windows 2000 it plays the first file, records to a file then on second
playback I check for a WHDR_DONE before preparing and waveOutWrite. But
never get a WHDR_DONE. Get instead 18 which is WHDR_ENDLOOP and
WHDR_INQUEUE.
It is strange that my code fine works with exactly the same voice board on
my development machine. But get this problem on a Windows 2000 machine.
I
have even installed my C++ dev environment on the 2000 machine so same sort
of files loaded.
Any ideas on what I should be looking at?
Angus Comber
Dave
2005-06-16 11:13:39 UTC
Permalink
you can reuse the buffers, just create them before preparing the headers the
first time and then copy data into them each time instead of just changing
the pointers... if you have something critical on timing maybe you could do
a speed comparison between copying a full buffer vs unprepare/prepare with
new pointer.
Post by Angus Comber
I expected 2000 to be the same ... and it wasn't! I developed the
application on Windows XP and delivered on Windows 2000. (well not yet
delivered). About a week ago I thought the job was finished... oh well,
that's programming!
Yes it is working OK on 2000 now. I will have to test it on 98 just to see
what happens.
Interesting about the prepare/unprepare bit about buffers. Your tip no
doubt will save me many an hour.
Angus
Post by Dave
ah yes, someone else has found one of the subtle differences between
winmm.dll (i think thats where it hides) in xp and 2k... and if you try on
win98 you will find more. xp is much more forgiving and lets you do nice
things with swapping around buffers that just don't work the same way in
2k
Post by Dave
and fail completely in 98. in xp i had a playback working fine... took
the
Post by Dave
same code to 2k and it wouldn't play or would crash the ocx process.
fixed
Post by Dave
that and in 98 it still wouldn't work, had to fix the same area again.
the
Post by Dave
one that got me was in xp you could set the lpdata member of the header
to
a
Post by Dave
NULL and init the header, then plug in a pointer to the actual data out
of
a
Post by Dave
buffer later on, and just keep changing the pointer when you refilled each
block. in w2k you have to point lpdata to a real location when you
prepare
Post by Dave
the header... but then it lets you reassign lpdata later on to point into
a
Post by Dave
different buffer. in 98 its even pickier, you can't change lpdata after
you
Post by Dave
prepare, you have to copy the data into the buffer or unprepare and
re-prepare the header with the new buffer.
Post by Angus Comber
Hello
Strange problem. My code runs just fine on Windows XP. But I also
need
to
get working on Windows 2000. My program plays a wav file then records a
message - but it does it repeatedly five times - so recording five voice
files.
On Windows 2000 it plays the first file, records to a file then on
second
Post by Dave
Post by Angus Comber
playback I check for a WHDR_DONE before preparing and waveOutWrite.
But
never get a WHDR_DONE. Get instead 18 which is WHDR_ENDLOOP and
WHDR_INQUEUE.
It is strange that my code fine works with exactly the same voice board
on
Post by Dave
Post by Angus Comber
my development machine. But get this problem on a Windows 2000 machine.
I
have even installed my C++ dev environment on the 2000 machine so same sort
of files loaded.
Any ideas on what I should be looking at?
Angus Comber
Tobia Quantrill
2005-06-16 11:50:57 UTC
Permalink
Post by Dave
you can reuse the buffers, just create them before preparing the headers the
first time and then copy data into them each time instead of just changing
the pointers... if you have something critical on timing maybe you could do
a speed comparison between copying a full buffer vs unprepare/prepare with
new pointer.
It's much better to prepare header once, and reuse the buffers during
playback. At the end, unprepare them. Preparing procedure is not doing
enything smart... I think it could be avoided if you do everything correctly
and put WHDR_PREPARED flag manualy, but I haven't tried that.
--
It is practically impossible to teach good programming to students that have
had a prior exposure to BASIC: as potential programmers they are mentally
mutilated beyond hope of regeneration. (Edsger Dijkstra 1930-2002)
Chris P. [MVP]
2005-06-16 12:30:15 UTC
Permalink
Post by Angus Comber
Hello
Strange problem. My code runs just fine on Windows XP. But I also need to
get working on Windows 2000. My program plays a wav file then records a
message - but it does it repeatedly five times - so recording five voice
files.
On Windows 2000 it plays the first file, records to a file then on second
playback I check for a WHDR_DONE before preparing and waveOutWrite. But
never get a WHDR_DONE. Get instead 18 which is WHDR_ENDLOOP and
WHDR_INQUEUE.
It is strange that my code fine works with exactly the same voice board on
my development machine. But get this problem on a Windows 2000 machine. I
have even installed my C++ dev environment on the 2000 machine so same sort
of files loaded.
Voice boards are particularly picky. They are not WDM audio drivers and do
not go through the same driver chain as a regular audio device. Because of
this you are at the mercy of the driver writers.

Loading...