Day 20: ExpectedBytesUntilFlip computed but unused

Should row 1055 to 1057 not be like this:

1
2
3
4
 
DWORD ExpectedBytesUntilFlip = (DWORD)((SecondsLeftUntilFlip/TargetSecondsPerFrame)*(real32)ExpectedSoundBytesPerFrame);

DWORD ExpectedFrameBoundaryByte = PlayCursor + ExpectedBytesUntilFlip;

Row 1057 now is
1
DWORD ExpectedFrameBoundaryByte = PlayCursor + ExpectedSoundBytesPerFrame;

and ExpectedBytesUntilFlip is not used at all?

Or is it just me?
No, this is actually correct - I tested this on my local build and this fixes the problem Casey had with the expected flip boundary being outside the jitter range of the flip play cursor!
Yes someone pointed this out in a prior thread but of course I can't fix it until Monday :( Killing me to not know if it works! But thank you for posting that it does...

- Casey
Well, they both work on my machine, but can't wait for the explanation!

What I find weird though is that my laptop (dell latitude e6530) has exactly the same audio latency DELTA:5760 (0.030000s)

Maybe it's a windows thing?

[EDIT]
Just tried it on my workpc with different audiocard but still the same latency
DELTA:5760 (0.030000s)

Edited by Roderic Bos on
This bug would have been caught by the compiler if the "unused variables" warning wasn't disabled. Just sayin'.

[quote=Rooc]
What I find weird though is that my laptop (dell latitude e6530) has exactly the same audio latency DELTA:5760 (0.030000s)


Same here. After some research, it seems like KMixer is the culprit.
Nice find!
Yeah ok tested it but with ExpectedBytesUntilFlip instead of the current ExpectedSoundBytesPerFrame you get audioskip so that would not work.
Nimbal
This bug would have been caught by the compiler if the "unused variables" warning wasn't disabled. Just sayin'.


It's kind of a shame if (I can't remember) the same warning deals with unused parameters and unused variables declared globally/in functions. Because unused parameters might be something we don't want the compiler to warn about but other unused variables might be.
Rooc
Yeah ok tested it but with ExpectedBytesUntilFlip instead of the current ExpectedSoundBytesPerFrame you get audioskip so that would not work.


I was getting skips with or without the change until I increased my safety bytes from whatever/3 to whatever/2, after which point the skips went away in both cases. It might be machine dependent.
ChronalDragon

I was getting skips with or without the change until I increased my safety bytes from whatever/3 to whatever/2, after which point the skips went away in both cases. It might be machine dependent.


Yeah same here after bikker safetybytes, the yellow and white cursor lines overlap more when using ExpectedBytesUntilSkip though, which was the problem being addressed I think.

BTW the more you pause the more it'll skip...
Nimbal

After some research, it seems like KMixer is the culprit.


The page goes on about how there's no latency if you use DirectSound right, but if I remember what I saw in *my* msdn dive, what with DirectSound no longer being quite so Direct, there'll always be that latency if you use it post-XP (because it can't be hardware accelerated).

Edited by theinternetftw on Reason: elucidation
My understanding is that DirectSound can still use hardware mixing / acceleration if the driver and sound card support it. KMixer always takes over the first available wave output (and so on systems with only one wave output you have to go through KMixer), and if the sound card / driver support more than one wave output pin then DirectSound can take advantage of those (bypassing the KMixer latency).

Though back in the early days the hardware mixing was generally problematic, I don't know if these days it has improved any (and I don't have a sound card here at work that I can test on).
On Vista+ DirectSound never uses hardware acceleration for its functionality (multiple buffers, 3d effects, etc). It always uses WASAPI to mix everything together and pass it further to real hardware. Same thing with XAudio2 and WinMM on Vista+ - they also use WASAPI to output audio. On WindowsXP XAudio2 uses DirectSound to output its audio.

Edited by Mārtiņš Možeiko on
EDIT: Looks like this must've been addressed in today's video (Day 24). Please disregard!

So, was the consensus that the code is correct as originally written (i.e. using ExpectedSoundBytesPerFrame instead of ExpectedBytesPerFlip to compute ExpectedFrameBoundaryByte)? I just ran into this problem independently in my own port, and using ExpectedBytesPerFlip definitely seemed to be the more correct approach. Here's my (possibly misguided) reasoning:

ExpectedSoundBytesPerFrame is effectively a constant: it's the number of bytes of audio we expect to generate for an entire frame, at a given frame rate. ExpectedBytesUntilFlip, on the other hand, is an estimate of how many more bytes of audio we need to generate before the end of the frame. Thus, when computing the ExpectedFrameBoundaryByte, wouldn't it make sense to use PlayCursor+ExpectedBytesUntilFlip instead of PlayCursor+ExpectedSoundBytesPerFrame?

Consider the case where GameUpdateAndRender() takes a fairly long time to finish. For example, on my platform (rendering at 1080p, because why not?), GameUpdateAndRender() takes about 20ms in Debug builds. When I hit the audio code for the first time, PlayCursor is at about ~20ms through the current frame of audio (give or take, as usual). ExpectedSoundBytesPerSecond is a full 33ms frame's worth of audio, as always; adding that to PlayCursor gives me an expected frame boundary in the middle of the next frame, well after the actual frame flip. ExpectedBytesUntilFlip, on the other hand, is about 13 ms of audio; adding that to PlayCursor puts me very close to the actual flip location.

In release builds (or on faster platforms), I expected that it wouldn't make as much of a difference which you choose. As GameUpdateAndRender() runs faster; ExpectedBytesUntilFlip will converge to ExpectedSoundBytesPerFrame, and you'll get the same results either way.

Please let me know if/where I've gone astray here; audio programming isn't exactly my superpower :)

Edited by Cort on Reason: Question already answered