Handmade Hero » Forums » Code » Lowering Audio Latency on Day 9
Blu342
12 posts
#17052 Lowering Audio Latency on Day 9
8 months, 3 weeks ago Edited by Blu342 on Dec. 26, 2018, 10:47 a.m.

https://youtu.be/8y9nPk1c45c?t=5833

in the above we are lowering the audio latency. we do this by writing LatencySampleCount = (SamplesPerSecond) / 15 Samples ahead of the PlayCursor.

casey, said we shouldn't use SamplesPerSecond / 60, because of potential audio dropouts. i'm not really sure what he means by audio dropouts. also he said that so long as the user is running at above 15FPS their audio will not dropout with (SamplesPerSecond) / 15; I don't really get why this is the case.

seems to me like it isn't really about running at 15 FPS throughout the entire second but more about whether a single frame takes longer than one fifteenth of a second to complete.

for example

let x represent filled in parts of the buffer
P the play cursor
T the target position SamplesPerSecond/15 samples ahead
R the running sample count

|PxxxxR----T-------------------------|

now we can stall for one frame safely (assuming we are running at 15 FPS); however, if we stall for 2 then we have a dropout?
hence, if we miss the frame due to getting swapped out by the OS, etc, but then start running at a pace of 30FPS, it is still possible to have a dropout, despite having run 30 Frames that Second. correct?
mmozeiko
Mārtiņš Možeiko
1971 posts / 1 project
#17053 Lowering Audio Latency on Day 9
8 months, 3 weeks ago Edited by Mārtiņš Možeiko on Dec. 26, 2018, 11:10 a.m.

Yes, you understand correctly. LatencySampleCount is number of samples audio can play without updating it with new information. If game or OS stalls the process for more than this time, there won't be any new audio to play - thus the audio dropout.

One of solutions games do is to create new high-priority thread for submitting audio information to OS. It can do it with small chunks to reduce latency. Then you need to take care submitting/mixing new information into this thread input which you can prepare far ahead current time (music for few seconds) and then just overwrite as new information comes in from game (sound effects). Then even if OS stalls main game thread, then audio will still play for a while giving game a chance to recover.

Windows Vista+ has special API that actually tells OS "this is high-priority audio thread". You do that with "AvSetMmThreadCharacteristicsA("Pro Audio" , &index)" on the thread.
Blu342
12 posts
#17055 Lowering Audio Latency on Day 9
8 months, 3 weeks ago Edited by Blu342 on Dec. 26, 2018, 11:46 a.m.

perfect. thanks so much. just one question though, why didn't casey want to divide by 60 instead of 15 then? he started off by dividing by 60 then changed to 15, saying it was a "bit aggressive" and might cause dropouts. was it just in case people with slow pcs were unable to run the game at 60, then he didn't want them to have dropouts, and was therefore willing to have higher latency?
mmozeiko
Mārtiņš Možeiko
1971 posts / 1 project
#17056 Lowering Audio Latency on Day 9
8 months, 3 weeks ago

Yes. If game runs less than 60fps then this will obviously be an issue. But even if it runs at 60fps the DirectSound API has latency itself, because it needs extra time to submit buffers to WASAPI, thus you need larger buffer than exactly just one frame.
Blu342
12 posts
#17057 Lowering Audio Latency on Day 9
8 months, 3 weeks ago Edited by Blu342 on Dec. 26, 2018, 1:05 p.m.

by latency do you mean like if the write cursor and the play cursor are too far apart, then we may be writing into the region between them, which is not valid. i remember reading on another post on the forums that the time between them is around 33ms, so I guess that would make sense. since if we are writing to it in a increment based on running at 60 FPS, we may write into this invalid region.