Handmade Hero»Forums»Code
Roderic Bos
70 posts
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?
Andrew Chronister
194 posts / 1 project
Developer, administrator, and style wrangler
Day 20: ExpectedBytesUntilFlip computed but unused
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!
Casey Muratori
801 posts / 1 project
Casey Muratori is a programmer at Molly Rocket on the game 1935 and is the host of the educational programming series Handmade Hero.
Day 20: ExpectedBytesUntilFlip computed but unused
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
Roderic Bos
70 posts
Day 20: ExpectedBytesUntilFlip computed but unused
Edited by Roderic Bos on
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)
Benjamin Kloster
48 posts
Day 20: ExpectedBytesUntilFlip computed but unused
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.
Roderic Bos
70 posts
Day 20: ExpectedBytesUntilFlip computed but unused
Nice find!
Roderic Bos
70 posts
Day 20: ExpectedBytesUntilFlip computed but unused
Yeah ok tested it but with ExpectedBytesUntilFlip instead of the current ExpectedSoundBytesPerFrame you get audioskip so that would not work.
Johan Öfverstedt
45 posts
Day 20: ExpectedBytesUntilFlip computed but unused
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.
Andrew Chronister
194 posts / 1 project
Developer, administrator, and style wrangler
Day 20: ExpectedBytesUntilFlip computed but unused
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.
Roderic Bos
70 posts
Day 20: ExpectedBytesUntilFlip computed but unused
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...
38 posts
Day 20: ExpectedBytesUntilFlip computed but unused
Edited by theinternetftw on Reason: elucidation
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).
William
6 posts
Day 20: ExpectedBytesUntilFlip computed but unused
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).
Mārtiņš Možeiko
2405 posts / 2 projects
Day 20: ExpectedBytesUntilFlip computed but unused
Edited by Mārtiņš Možeiko 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.
Cort
5 posts
Day 20: ExpectedBytesUntilFlip computed but unused
Edited by Cort on Reason: Question already answered
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 :)