http://bugs.winehq.org/show_bug.cgi?id=30191
Bug #: 30191 Summary: Stuttering mmdevapi audio (Mac OS X) Product: Wine Version: 1.4 Platform: x86 OS/Version: Mac OS X Status: NEW Severity: normal Priority: P2 Component: mmdevapi AssignedTo: wine-bugs@winehq.org ReportedBy: hoehle@users.sourceforge.net CC: aeikum@codeweavers.com Classification: Unclassified
The interactive mmdevapi render tests stutters quasi continuously on my Mac OS X "early 2009" nVidia Mac mini.
Actually, stuttering can be interpreted as an indicator of low-latency, which is good :-) Consider winecoreaudio's 20ms period. If audio would only start at e.g. t=9ms, then at period time t=20, underrun would be very far when writing the next frames.
The reasons for stuttering are known from winealsa, yet the details are different: lead-in and regularity.
Lead-in: Note that mmdevapi/render.c:test_worst_case does not behave like XAudio2 with winecoreaudio and wineoss, due to their use of a 20ms period. Alexey's analysis in bug #28723, comment #19 is that XAudio then writes a lead-in of 3/4*4 = 3 periods, unlike the 1 period written in the 10ms period case. test_worst_case uses 0 or 1 period. So XAudio2 apps may not stutter, whereas the mmdevapi test does. That does not imply that our winecoreaudio code is great, rather than that we're forbidden to reduce the period to the 10ms that native uses everywhere.
Unlike ALSA, I see no notion of underrun in CoreAudio. So I don't see when writing a lead-in would be appropriate, except at start. I think we need something else.
Regularity/stability: XAudio2 and test_worst_case write at most one period worth of frames per event. Writing nothing is a guarantee of underrun (unless the event rate is artificially high to counter this). Indeed, adding a trace("MISS") to test_worse_case every time GetCurrentPadding is too high to add more samples correlates with some, but not all underruns.
Again, my ntdll CreateTimerQueue stabilisator patch from bug #30071 helps a little, as otherwise callbacks are mostly 21ms apart rather than 20ms. That clock skew also accounts for a few underruns.
However the major point is: XAudio2 needs event signalling to match decrease of padding, such that it adds the next period of data. My ALSA work-in progress code does exactly that, but CoreAudio needs it even more due to the absence of the lead-in safety-belt.