Hey Joerg,

Op 27-01-12 16:35, joerg-cyril.hoe...@t-systems.com schreef:
Maarten,

thank you for participating!

Provide a hidden API in mmdevapi?
No need, you know how mmdevapi behaves, you can write it in such a
way without adding latency by using GetCurrentPadding or the clock.
I don't know what you mean.  What I mean is follows:

mmdevapi has no notion of rewinding.
Rewinding is what PulseAudio recommends to master latency:
http://0pointer.de/blog/projects/guide-to-sound-apis.html
"Use snd_pcm_rewind() if you need to react to user input quickly.
  Do not assume that snd_pcm_rewind() is available and works and to which 
degree."

Let's say DSound uses a 200ms primary buffer.  It can (and I believe
Wine's DSound did that) mix all of the playing secondary buffers and
feed 200ms of samples to ALSA.
Effect: 200ms audio playing with nothing else to do.

Now let' suppose after 50ms, Play is invoked on an explosion buffer.
DSound can query the hw pos and remix the remaining 150ms (or 140 to
play safe) to include that noise.  With ALSA, it can do so
- either by using snd_pcm_rewind or
- via direct access to the ALSA buffer (mmap).

The key point is that DSound's model (the HW buffer) is compatible
with both feeding arbitrary large amounts of data in advance *and*
quickly adding sounds with as little latency as possible.


Enters mmdevapi.  No rewinding.  A Release'd frame will be played,
unless you Stop and Reset.

If you Release 200ms of data now, additional samples can only be heard
afterwards.  The solution so far: write next to nothing in advance --
10ms! -- and rely on super fast interrupt&  wake-up to reliably submit
another 10ms just in time.

Assessment: failure.
Wobbling sound and underruns reported in bugzilla.
No wonder MS sells w7 with new machines only.  The old ones
can't stand the 10ms interrupt rate.
I'm fairly confident older machines handle that properly too. Just requires properly written drivers.
Windows vista was a lot more bloated than 7.
I wouldn't count on rewinding for alsa either, I'm not even sure if dmix finally supports it or not, buffer slightly more data instead. I think this is what IAudioClient::GetStreamLatency is meant for.

Alternatives:

A. Every DSound secondary buffer gets its mmdevapi stream.
    DSound::Play immediately calls IAC::Start.

Some says this is not useable because every mmdevapi stream maps 1:1 to
snd_pcm_open and it's rumoured that cards would not support the
amount of simultaneous connections corresponding to the number of
secondary buffers that DSound apps typically use (rumour has it over
20).  Again, DSound is not my domain of expertise.
Doesn't work on streams where you can alter the frequency..
That's why I've been arguing in bug #29531 that mmdevapi implements
its own mixer.  ALSA would only see one connection.
How to implement that mixer?  Now we circled once and are back at the
above point about rewind/mmap.

B. Special DSound hooks that bypass mmdevapi's streaming design,
    allowing to both write 200ms of data in advance and overwrite part
    of it as needed -- hidden API or COM interfaces.

C. Other?

Well, that was the old DSound.  XAudio2 ("the rage bug #28723")
apparently goes the "every 10ms" route, hence Wine needs to support
that in any case.

I've repeatedly argued that the fact that an app may may use 10ms (and
risk gfx and sfx glitches and write 3GHz quadcore as min. requirement
on the back of the DVD cover) should not cause apps using 200ms
buffers to suffer glitches.  How to meet both ends?
Or just fix things properly and use rtkit for time critical threads,
the real problem would be context switches with wineserver. The
extra task switches and reliance on the scheduler to get
things right could cause more problems..

~Maarten


Reply via email to