dsound: use event based threads, v2

Joerg-Cyril.Hoehle at t-systems.com Joerg-Cyril.Hoehle at t-systems.com
Fri Dec 21 11:44:04 CST 2012


Maarten Lankhorst answered:
>> [...] I wonder why you 
>> insist on using GetStreamLatency as the basis of your timeout 
>> computations instead of GetDevicePeriod.
>Because I'm using it later on in the rework to tell how much to queue.
Ah.  But why not use the correct tool for the correct job?
GetPeriod for period, and StreamLatency for buffer and queue sizes?

>In my rework, I try to write at most 3 * GetStreamLatency, so even if for some
>reason no event is ever delivered, you would never get an underrun.

I'm sorry to disagree, but I've conducted numerous tests last night.
The results are very disappointing, but I'll only find time in January
to write more about it.

Basically, no trick in DSound or Winmm whatsoever can prevent an underrun.
The typical Linux machine can and will not schedule arbitrary threads that
are ready to run, and I observed arbitrary pauses of 12-120ms. :-(

How much was wake up delayed? For lovers of histograms: sort -n delays | uniq -c
period  20ms            10ms
     57 0          828  0
     41 1          202  1
   2767 2         2771  2
    541 3          185  3
    258 4         1956  4
      6 5           16  5
     22 6           13  6
      5 7            1  7
      1 8           10  8
      2 9            2  9
     11 10           3  10
                     4  11
      1 12           9  12
      1 13           1  13
                     2  14
                     1  16
      1 18 
      1 34
                     1  88
      1 119
   3716  samples  6005

- Even if mmdevapi SetEvent's your thread, there's no guarantee that
  it gets scheduled without or with little delay.
- Above data is for one thread.  As multiple threads are
  involved in producing audio, delays accumulate.
- Even if the DSound thread always gets to run and Release's data, there's no
  guarantee that the winealsa.drv thread does and sends data to ALSA.
- Worse, even if the winealsa thread gets to run, there's no guarantee *AT ALL*
  (and I've seen it happen) that it won't lose CPU for over 20ms even if calling
  nothing but snd_pcm_* (and TRACE) in the callback.
As a consequence, the current winealsa.drv can, by design (ALSA buffer holding
no more than 3 periods), not prevent underruns, no matter how much you kick it.

You advertised RT priorities.  With them, the picture would look different of course.
A faster machine helps too...

In January, I'll write more, e.g. about concrete changes in code.

BTW, yesterday I replaced the timer queues in winealsa with an own thread.
Timing is much better, but that doesn't prevent delays.  More changes
are needed to improve the situation.

	Jörg Höhle

More information about the wine-devel mailing list