Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
Windos
win32.3rdparty
win32.directx.audio
win32.directx.ddk
win32.directx.graphics
win32.directx.input
win32.directx.managed
win32.directx.misc
win32.directx.networking
win32.directx.sdk
win32.directx.video
win32.dirx.grap.shaders
win32.gdi
win32.international
win32.kernel
win32.messaging
win32.mmedia
win32.networks
win32.ole
win32.rtc
win32.tapi
win32.tapi.beta
win32.tools
win32.ui
win32.wince
win32.wmi
windows.mediacenter
winfx.aero
winfx.announcements
winfx.avalon
winfx.collaboration
winfx.fundamentals
winfx.general
winfx.indigo
winfx.sdk
winfx.winfs
  
 
date: Tue, 19 Feb 2008 19:07:13 -0800 (PST),    group: microsoft.public.win32.programmer.directx.audio        back       


Problem with audio on Vista   
Hi!

I hope this is the right group for this question - suggestions of
active groups where this question would be better posed are welcome.

I'm having trouble with audio playback. My environment is Vista 64,
Visual Studio 2005, Vista SDK. The approach I'm using is very simple:

0. Get ready for audio playback with waveOutOpen.
1. Load buffer A with raw audio samples.
2. Load buffer B with raw audio samples.
3. Prepare buffer A with waveOutPrepareHeader.
4. Prepare buffer B with waveOutPrepareHeader.
5. Start buffer A playing, using waveOutWrite.
6. Wait for MM_WOM_DONE.
7. Start buffer B playing, using waveOutWrite.
8. Wait for MM_WOM_DONE.
9. Go to 5.

This approach works fine on Windows 2000 and XP. But on Vista, it
produces audio corruption. For small buffers, (c. 4k) audio plays at
about half speed, with dead air between short (4k?) bursts of audio.
At 16k, the dead air seems to be mostly gone, but there's a notable
clicking when changing buffers. This decreases until it's not very
noticeable at 22k, and with 32k buffers, audio sounds perfect. Does
anyone have any clues? For my purposes, it's important to have small
buffers to keep playback position indicators very accurate. As far as
I can tell, the new buffer is being queued up quickly on completion of
the old one, and even if it wasn't, I'd expect that to cause a
constant delay between buffer playbacks, independent of buffer size.

If anyone would like to see more code (header setup, function calls
etc) please let me know!

Thanks,

Mike.
date: Tue, 19 Feb 2008 19:07:13 -0800 (PST)   author:   Mike

Problem with waveOut audio playback on Vista (C++) - buffer size-related skipping.   
Just noticed the subject line I originally set was useless...!
Hopefully this one's a little better.

Mike.
date: Tue, 19 Feb 2008 19:08:51 -0800 (PST)   author:   Mike

Re: Problem with audio on Vista   
On Tue, 19 Feb 2008 19:07:13 -0800 (PST), Mike wrote:

> I hope this is the right group for this question - suggestions of
> active groups where this question would be better posed are welcome.

Technically it's probably more appropriate for
microsoft.public.win32.programmer.mmedia but I'll just set the follow up
there.
 
> I'm having trouble with audio playback. My environment is Vista 64,
> Visual Studio 2005, Vista SDK. The approach I'm using is very simple:
> 
> 0. Get ready for audio playback with waveOutOpen.
> 1. Load buffer A with raw audio samples.
> 2. Load buffer B with raw audio samples.
> 3. Prepare buffer A with waveOutPrepareHeader.
> 4. Prepare buffer B with waveOutPrepareHeader.
> 5. Start buffer A playing, using waveOutWrite.
> 6. Wait for MM_WOM_DONE.
> 7. Start buffer B playing, using waveOutWrite.
> 8. Wait for MM_WOM_DONE.
> 9. Go to 5.
> 
...

Your running on Vista 64 but are you compiling a 32 or 64-bit executable?

Your technique above is flawed and in theory shouldn't work at all even on
XP or 2K.  You need to have a minimum of 2 buffers in queue at all times.
Buffer B must be queued *before* you received the MM_WOM_DONE message for
buffer A.  With only 1 buffer in queue MM_WOM_DONE indicates that the first
buffer playback is complete - which in your case also means that the output
has starved for data as there is no more buffers in queue.  I think the
only reason that it worked on 2K and XP is due to a flaw in their KMixer
implementation that returned the WOM_DONE message prematurely.  Regardless
you should still be able to get accurate stream information with
waveOutGetPosition(), I usually have between .25 and 1 second queued up and
can still sync with visual indicators using that.

-- 
http://www.chrisnet.net/code.htm
[MS MVP for DirectShow / MediaFoundation]
date: Wed, 20 Feb 2008 10:16:28 -0500   author:   Chris P.

Re: Problem with audio on Vista   
On Feb 21, 4:16 am, "Chris P."  wrote:
> Your running on Vista 64 but are you compiling a 32 or 64-bit executable?

It's a 32-bit executable.

> Your technique above is flawed and in theory shouldn't work at all even on
> XP or 2K.  You need to have a minimum of 2 buffers in queue at all times.
> Buffer B must be queued *before* you received the MM_WOM_DONE message for
> buffer A.  With only 1 buffer in queue MM_WOM_DONE indicates that the first
> buffer playback is complete - which in your case also means that the output
> has starved for data as there is no more buffers in queue.  I think the
> only reason that it worked on 2K and XP is due to a flaw in their KMixer
> implementation that returned the WOM_DONE message prematurely.  Regardless
> you should still be able to get accurate stream information with
> waveOutGetPosition(), I usually have between .25 and 1 second queued up and
> can still sync with visual indicators using that.

Thanks for that thought - the code isn't mine originally, I'm
modifying it (it's pretty ancient!). So, it's quite possible that I've
misread the code (and given an incorrect algorithm above), perhaps it
is trying to keep two buffers in the queue all the time. I'll recheck
and modify as required.

I did actually wonder about exactly this possibility, but assumed that
the _DONE message was sent out early enough to allow for queuing the
next buffer. One thing I wasn't sure about was whether waveOutWrite
can be called multiple times immediately consecutively, to place more
than one buffer in the audio playback queue, without causing problems.
Thinking about it, I'm sure it must be possible, to avoid the exact
problem you describe above. This may also explain the problems I had
when porting the code to Windows CE...!

Thanks very much for the info - will post a note here when I get a
chance to have a go at the code!

Mike.
date: Wed, 20 Feb 2008 17:23:36 -0800 (PST)   author:   Mike

Re: Problem with audio on Vista   
On Feb 21, 2:23 pm, Mike  wrote:
> > Your technique above is flawed and in theory shouldn't work at all even on
> > XP or 2K.  You need to have a minimum of 2 buffers in queue at all times.
> > Buffer B must be queued *before* you received the MM_WOM_DONE message for
> Thanks for that thought - the code isn't mine originally, I'm
> modifying it (it's pretty ancient!). So, it's quite possible that I've
> misread the code (and given an incorrect algorithm above), perhaps it
> is trying to keep two buffers in the queue all the time. I'll recheck
> and modify as required.

Well, I checked - turns out I didn't read the code carefully enough,
it does in fact queue both buffers at the outset. The fixed algorithm
is this:

0. Get ready for audio playback with waveOutOpen.
1. Load buffer A with raw audio samples.
2. Prepare buffer A with waveOutPrepareHeader.
3. Start buffer A playing, using waveOutWrite.
4. Load buffer B with raw audio samples.
5. Prepare buffer B with waveOutPrepareHeader.
6. Start buffer B playing, using waveOutWrite.
7. Wait for MM_WOM_DONE.
8. Reload buffer A with raw audio samples.
9. Queue buffer A, using waveOutWrite.
10. Wait for MM_WOM_DONE.
11. Reload buffer B with raw audio samples.
12. Queue buffer B, using waveOutWrite.
13. Go to 7.

Does anyone have any further clues? The same executable seems to run
very well on XP and older; it's a bit baffling.

Mike.
date: Wed, 20 Feb 2008 23:20:56 -0800 (PST)   author:   Mike

Re: Problem with audio on Vista   
On Feb 21, 7:20�am, Mike  wrote:
<snip>
> The fixed algorithm is this:
>
> 0. Get ready for audio playback with waveOutOpen.
> 1. Load buffer A with raw audio samples.
> 2. Prepare buffer A with waveOutPrepareHeader.
> 3. Start buffer A playing, using waveOutWrite.
> 4. Load buffer B with raw audio samples.
> 5. Prepare buffer B with waveOutPrepareHeader.
> 6. Start buffer B playing, using waveOutWrite.
> 7. Wait for MM_WOM_DONE.
> 8. Reload buffer A with raw audio samples.
> 9. Queue buffer A, using waveOutWrite.
> 10. Wait for MM_WOM_DONE.
> 11. Reload buffer B with raw audio samples.
> 12. Queue buffer B, using waveOutWrite.
> 13. Go to 7.
>
> Does anyone have any further clues? The same executable seems to run
> very well on XP and older; it's a bit baffling.
>

The algorithm I use is slightly different in text, but may be same in
implementation.

0. Get ready for audio playback with waveOutOpen.
1. Allocate memory for all headers
2. Allocate memory for all buffers
3  waveOutPrepareHeader() for all headers;
// the above is usually done with arrays of buffers & headers
4  Load all buffers from input source
5  waveOutWrite all buffers (incrementing QueueCount variable)
when MM_WOM_DONE. is received
6 Decrement QueueCount
  if not end of audio source
{7. Reload the returned header buffer with audio.
8 waveOutWrite the refilled buffer
9. increment QueueCount
}
if queueCount = 0, tidy up all memory & waveOutClose

I find the QueueCount is necessary to cater for waveOutReset,
otherwise one frees the memory when the first buffer after an empty
input source is returned, and MM_WOM_DONE has nowhere to come back to.

Note that you don't need to re-Unprepare & Prepare headers when a
buffer is returned, unless you want to change the size of the buffer.

Using arrays for the multiple buffers & headers is more convenient. I
usually use three buffers, because on occasion quite a lot of code
occurs between buffers. (although as an ancient coder I am totally
flabbergasted by the amount of stuff I can do apparently
instantaneously).

Alan Lloyd
date: Thu, 21 Feb 2008 01:50:11 -0800 (PST)   author:   unknown

Re: Problem with audio on Vista   
On Wed, 20 Feb 2008 23:20:56 -0800 (PST), Mike wrote:

> Well, I checked - turns out I didn't read the code carefully enough,
> it does in fact queue both buffers at the outset. The fixed algorithm
> is this:
> 
> 0. Get ready for audio playback with waveOutOpen.
> 1. Load buffer A with raw audio samples.
> 2. Prepare buffer A with waveOutPrepareHeader.
> 3. Start buffer A playing, using waveOutWrite.
> 4. Load buffer B with raw audio samples.
> 5. Prepare buffer B with waveOutPrepareHeader.
> 6. Start buffer B playing, using waveOutWrite.
> 7. Wait for MM_WOM_DONE.
> 8. Reload buffer A with raw audio samples.
> 9. Queue buffer A, using waveOutWrite.
> 10. Wait for MM_WOM_DONE.
> 11. Reload buffer B with raw audio samples.
> 12. Queue buffer B, using waveOutWrite.
> 13. Go to 7.
> 
> Does anyone have any further clues? The same executable seems to run
> very well on XP and older; it's a bit baffling.

I use a similar technique to Alan except that I use events rather than the
Windows message.  I always found there was too much delay in the Window
message which meant that you had to buffer twice as much data to get smooth
playback.  

waveOut on Vista is wrapped and no longer goes directly to the windows
audio mixer like it used to, it is instead redirected through the WASAPI
audio interface.  You might need to either increase the number of buffers
or the size to compensate.  I remember that on a Windows CE project I did
years back I had to use large amounts of buffering.

-- 
http://www.chrisnet.net/code.htm
[MS MVP for DirectShow / MediaFoundation]
date: Thu, 21 Feb 2008 10:27:29 -0500   author:   Chris P.

Re: Problem with audio on Vista   
Thanks for the comments everyone - I could try using a larger number
of small buffers, that might help. As the app stands now, the larger
the buffers are, the worse the resolution of the playback position
indicator is. I could use two larger buffers and fake the playback
position with timers, but it'd be better to use a pile of short
buffers, and approximate the delay between adding a buffer to the
queue and the time the buffer begins playback.

For what it's worth, my buffers on CE are very small, I think 4k
again, and that seems to work fine (tested on 3.0 and 5.0).

Mike.
date: Sat, 23 Feb 2008 01:59:40 -0800 (PST)   author:   Mike

Re: Problem with audio on Vista   
On Sat, 23 Feb 2008 01:59:40 -0800 (PST), Mike wrote:

> Thanks for the comments everyone - I could try using a larger number
> of small buffers, that might help. As the app stands now, the larger
> the buffers are, the worse the resolution of the playback position
> indicator is. I could use two larger buffers and fake the playback
> position with timers, but it'd be better to use a pile of short
> buffers, and approximate the delay between adding a buffer to the
> queue and the time the buffer begins playback.

You can make the playback position indicator just as accurate with 10
seconds of buffering as you can with 1/4 second.  You use the stream offset
to calculate the number of audio samples played out compared to what you
have given it, subtract the difference to apply to your position indicator.

-- 
http://www.chrisnet.net/code.htm
[MS MVP for DirectShow / MediaFoundation]
date: Mon, 25 Feb 2008 10:30:12 -0500   author:   Chris P.

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us