Hi,
Bugzilla admins, please set the 1.4 milestone on all bugs mentioned here.
I'm not yet looking at dsound issues since I first want a correct foundation upon which to build to upper layers.
o #28039 IAudioClock_GetPosition must ignore underruns (MacOS) Here I've no idea how to solve this. My initial query remained unanswered: http://lists.apple.com/archives/coreaudio-api//2011/Sep/msg00024.html Ken? Andrew's yesterday patch (using GetCurrentPadding) is an interim work-around. GetPosition (speaker) is unrelated to padding which is solely about buffering.
o #28093 GetCurrentPadding must slowly decrease (MacOS) may cause an app to play audio using a single buffer, causing underruns and audio drop outs.
o #28056 Problems with sound under FreeBSD which became "blocking calls with OSS" recently addressed by Andrew.
o snd_pcm_drop causes incorrect GetPosition after mmdevapi Stop which I believe to be the cause of: #27901 winmm tests timing out waiting for hevent after waveOutRestart May get solved by Andrew's work in: #28517 Pikachu Volleyball stops playing sound effects
Every snd_pcm_drop and reset must be inspected with care w.r.t. its effect on GetPosition. Wine must ensure that after playing ends, GetPosition == sum of written samples for both mmdevapi and winmm.
o #27937 winmm kept busy playing silence after play finishes IIRC because winmm writes silence. Once mmdevapi handles underruns correctly, my patch "winmm: Never write silence, mmdevapi must handle underruns." will become applicable: http://www.winehq.org/pipermail/wine-patches/2011-September/107108.html
Playing silence causes: #28027 μ-law rendering with pauses and repetitions (MacOS) as well as presumably: #28413 Sound play in games and programs causes brief "pauses" at the time dsound used winmm prior to 1.3.29.
o #28047 IAudioClock_GetPosition must not depend on buffering (ALSA/Pulse) ALSA must derive GetPosition from snd_pcm_delay, not snd_pcm_avail_update
There are other issues not associated with a bug entry. I'm off for vacation, but here's a snippet from my TODO list: - OSS GetPosition from DSP_GETODELAY - ALSA+OSS: ReleaseBuffer: check method ordering and max size - GetStreamLatency = Xms + SHAREDMODE:period Stream latency is a static property of the audio graph's components. - wineoss GetStreamLatency must be constant, and SNDCTL_DSP_GETODELAY is only usable once running - Check WHDR_BEGIN/ENDLOOP code and write tests - WINMM_GetPosition is simply written_frames, not even minus padding (as the old alsa driver did), later use mmdevapi:GetPosition. - winmm PushData without IAC_Reset or last_clock_pos=0 in case of underrun - Investigate OSS4 underrun behaviour - Align wineOSS on newest ALSA code improvements - Submit CoreAudio memory leak fix to #28023; Write error handling patch - Check ALSA laptop suspend w.r.t. GetPosition - Add run-time consistency checks in renderer and abort audio stream (GetData) upon trouble instead of hanging.
and finally:
- Test compatibility with native DSound and file bug if unusable. There are several reports in bugzilla mentioning that this work-around ceased to work since 1.3.25. Loss of interoperability is not acceptable.
Regards, Jörg Höhle
On Oct 7, 2011, at 9:24 AM, Joerg-Cyril.Hoehle@t-systems.com wrote:
o #28039 IAudioClock_GetPosition must ignore underruns (MacOS) Here I've no idea how to solve this. My initial query remained unanswered: http://lists.apple.com/archives/coreaudio-api//2011/Sep/msg00024.html Ken? Andrew's yesterday patch (using GetCurrentPadding) is an interim work-around. GetPosition (speaker) is unrelated to padding which is solely about buffering.
It is expected that the queue's time keeps incrementing even when no buffers are enqueued. For example, see https://developer.apple.com/library/ios/#qa/qa1718/_index.html.
Here's one possible solution:
Enqueue the buffers with AudioQueueEnqueueBufferWithParameters() to get back the actual start time (in the queue's time frame) at which each buffer is scheduled to start. Then, compare AudioQueueGetCurrentTime() with the scheduled start time of the enqueued buffer(s) to see how far into which buffer the queue has played.
The code will have to track the position (in the desired sense) separately from the queue time. There will be a scalar value containing the sum of the lengths of all buffers known to have been completely played. There will also be a list of time ranges for those buffers which have been queued but are not known to have been completely played yet. For each buffer, the time range consists of its scheduled start time and its length.
At certain points -- ca_out_buffer_cb() and GetPosition() -- AudioQueueGetCurrentTime() will be called. The buffer list will be scanned. All the buffers whose end time (i.e. start time + length) is less than the queue time will be removed from the list, with their lengths added into the sum. That's all that's necessary for ca_out_buffer_cb() and is only done in that function to make sure the buffer list doesn't keep growing if GetPosition() is rarely or never called. For GetPosition(), the queue time will be compared to the first buffer that remains in the list, if any. If there are no buffers or the queue time is before the start time of the first buffer, then GetPosition() returns the sum. Otherwise, it will return the sum plus the queue time minus the buffer start time.
AudioClient_Reset() will clear the buffer list (and the sum?).
There's another approach that came to mind, but I don't think it's feasible: only run the queue when there are actually buffers to play. Don't start the queue until a buffer has been enqueued and stop it when there are no more ready. Basically, during the callback when the queue is requesting another buffer, if there's nothing to enqueue, call AudioQueueStop(..., FALSE). You may also need to use AudioQueueAddPropertyListener() to observe kAudioQueueProperty_IsRunning to learn when it has actually stopped, since the queue's time will reset to 0 at that point. During each period of the queue running, its time will reflect actual queued samples being played.
Timeline discontinuities occur when the sample rate changes, the output device is switched, the DSP has to be reset, or that sort of thing, I believe. They don't have anything to do with underruns of the kind you're considering.
Regards, Ken
On Fri, Oct 7, 2011 at 09:24, Joerg-Cyril.Hoehle@t-systems.com wrote:
Hi,
Bugzilla admins, please set the 1.4 milestone on all bugs mentioned here.
I'm not yet looking at dsound issues since I first want a correct foundation upon which to build to upper layers.
o #28039 IAudioClock_GetPosition must ignore underruns (MacOS) Here I've no idea how to solve this. My initial query remained unanswered: http://lists.apple.com/archives/coreaudio-api//2011/Sep/msg00024.html Ken? Andrew's yesterday patch (using GetCurrentPadding) is an interim work-around. GetPosition (speaker) is unrelated to padding which is solely about buffering.
o #28093 GetCurrentPadding must slowly decrease (MacOS) may cause an app to play audio using a single buffer, causing underruns and audio drop outs.
o #28056 Problems with sound under FreeBSD which became "blocking calls with OSS" recently addressed by Andrew.
o snd_pcm_drop causes incorrect GetPosition after mmdevapi Stop which I believe to be the cause of: #27901 winmm tests timing out waiting for hevent after waveOutRestart May get solved by Andrew's work in: #28517 Pikachu Volleyball stops playing sound effects
Every snd_pcm_drop and reset must be inspected with care w.r.t. its effect on GetPosition. Wine must ensure that after playing ends, GetPosition == sum of written samples for both mmdevapi and winmm.
o #27937 winmm kept busy playing silence after play finishes IIRC because winmm writes silence. Once mmdevapi handles underruns correctly, my patch "winmm: Never write silence, mmdevapi must handle underruns." will become applicable: http://www.winehq.org/pipermail/wine-patches/2011-September/107108.html
Playing silence causes: #28027 μ-law rendering with pauses and repetitions (MacOS) as well as presumably: #28413 Sound play in games and programs causes brief "pauses" at the time dsound used winmm prior to 1.3.29.
o #28047 IAudioClock_GetPosition must not depend on buffering (ALSA/Pulse) ALSA must derive GetPosition from snd_pcm_delay, not snd_pcm_avail_update
There are other issues not associated with a bug entry. I'm off for vacation, but here's a snippet from my TODO list:
- OSS GetPosition from DSP_GETODELAY
- ALSA+OSS: ReleaseBuffer: check method ordering and max size
- GetStreamLatency = Xms + SHAREDMODE:period
Stream latency is a static property of the audio graph's components.
- wineoss GetStreamLatency must be constant, and SNDCTL_DSP_GETODELAY
is only usable once running
- Check WHDR_BEGIN/ENDLOOP code and write tests
- WINMM_GetPosition is simply written_frames, not even minus padding
(as the old alsa driver did), later use mmdevapi:GetPosition.
- winmm PushData without IAC_Reset or last_clock_pos=0 in case of underrun
- Investigate OSS4 underrun behaviour
- Align wineOSS on newest ALSA code improvements
- Submit CoreAudio memory leak fix to #28023; Write error handling patch
- Check ALSA laptop suspend w.r.t. GetPosition
- Add run-time consistency checks in renderer and
abort audio stream (GetData) upon trouble instead of hanging.
and finally:
- Test compatibility with native DSound and file bug if unusable.
There are several reports in bugzilla mentioning that this work-around ceased to work since 1.3.25. Loss of interoperability is not acceptable.
Regards, Jörg Höhle
Done. In the future, please post full urls, makes my job easier :).
I've also given you bug editing/confirming privileges in bugzilla.
Cheers, Austin