On Tue, 16 Jun 2009, Arthur Taylor wrote: [...]
This is all simple enough except for how variable it is. Applications usually allocate a set size of wavehdrs and then use them circularly. Applications usually use when a wavehdr is returned for timing purposes rather than waveOutGetPosition. The number of wavehdrs and their sizes is entirely up to the application.
There are two common problems with audio drivers implementing this system. The first is drivers which return a wavehdr as soon as it is written to output (waveesd.dr for example) as it will cause timing issues for applications when large batches of wavehdrs are returned at once.
That's interesting. Fixing that in wineesd is pretty simple actually. All you have to do is replace dwWrittenTotal with dwPlayedTotal in wodPlayer_NotifyCompletions(). This actually improves the one 5s wavehdr test in our conformance test: without the patch it completes too early, while with dwPlayedTotal it completes in exactly 5s.
But fixing this also breaks our ten 0.5s wavehdrs test. Not that it works 100% either way. I need to double check but it feels like our test feeds 1 wavehdr, waits for it to complete (WaitForSingleObject(hevent)), and only then feeds the next wavehdr. Because wineesd has a pretty high latency this results in something like 0.5s of sound, then 0.5s of silence, then 0.5s of sound, etc (it seems like we're also missing a notification for the last wavehdr but that may be a separate issue). This test is supposed to reflect the behavior of streaming applications but I don't think it's really accurate.
However I get the same issue with DirectSound. I suspect it's for the same reason: I seem to recall that DirectSound sends as little in advance as possible to not have to redo too much mixing if the input streams change. But that breaks totally if it sends less than the sound driver's latency.
Is there a standard way to deal with these latency issues on Windows? Does anyone have ideas on how to best deal with them?