http://bugs.winehq.org/show_bug.cgi?id=33105
Bug #: 33105 Summary: un/plugging earphone while playing kills sound on MacOS Product: Wine Version: 1.5.25 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 Classification: Unclassified
I had observed earlier that mplayer stopped playing audio when plugging earphones into my Mac Mini. Running the interactive (audible) mmdevapi render tests shows the likely culprit.
AudioQueueGetCurrentTime fails during approximately 500ms while the Mac is dynamically reconfiguring its audio pipeline following the plug operation.
243251.428:trace:coreaudio:get_current_aqbuffer_position 634 frames (relative) 243251.450:trace:coreaudio:AudioClient_GetCurrentPadding (0x12bae8)->(0x32fbf8) 243251.450:warn:coreaudio:get_current_aqbuffer_position Unable to get current time: 73746f70 ... 243251.936:warn:coreaudio:get_current_aqbuffer_position Unable to get current time: 73746f70 243251.942:trace:coreaudio:AudioClient_GetCurrentPadding (0x12bae8)->(0x32fbf8) 243251.942:trace:coreaudio:get_current_aqbuffer_position No buffers queued
QueueStopped = 0x73746f70, // ASCII 'stop'
Apple's Audio Queue Services documentation does not mention that result code, however some OSS projects do. mono's Mac driver: https://github.com/mono/maccore/blob/master/src/AudioToolbox/AudioQueue.cs AudioStreamer.m: http://code.metager.de/source/xref/ubuntu/one/ios-music/utilities/AudioStrea... Upon encountering that error, the latter app simply repeats the last known position (like our winealsa/oss drivers do).
The Wine bug is possibly in mmdevdrv.c:get_current_aqbuffer_position. It always struck me that there's some "return 0" not preceded by "if(mode==BUFPOS_ABSOLUTE) /* add This->written_frames */" As a consequence, GetPosition returns 0, which possibly breaks winmm, DSound and anyone else using that API.
I have a patch series that revisits that function...
The render tests show that audible audio resumes normal operations past that half second, so aborting the CA queue or returning an error to the application (e.g. AUDCLNT_E_DEVICE_INVALIDATED) is to be avoided IMHO. (Of course, adding support of DEVICE_INVALIDATED to Wine's winmm and DSound is another task).