Hi,

Maarten Lankhorst wrote:
>For capture I plan to just add 2 queues, one for readable packets, and one
>for packets that can be filled for reading.
Winecoreaudio uses exactly this.


>... for the pulse driver, I'm using the auto timing
>update feature and the callback for when rendering is not running.
>When the buffer is not underflowed, I'm using the write callback to
>signal more data is available.
I'm not familiar with PA's API, so I'm not following you.  I'm not even
sure we talk about the same thing.

>I believe the event should be triggered when there is actual data
>available, at least that's how I understood the event is supposed
>to work.

I distinguish 2 events:
 a) ALSA/PA backend ready for more data
 b) mmdevapi SetEventHandle to the app

Note that b) only exists when using EVENTCALLBACK.

We have tests about b) that show that mmdevapi delivers events
to the app even when stopped (Wine fails those with todo_wine). I
don't know at what rate.

Regarding a), nothing prevents you from using the back-end's
favourite notification mechanism to wake up - or use a timer.

I agree with you that ideally, somehow, b) and a) should be in sync,
otherwise we'll have clock skew and the XAudio scenario will exhibit
occasional underruns.

But there are big HOWEVER:
- ALSA/PA may not grant us the period we'd like (10ms). 21.333ms is common with 
ALSA/dmix.
  I don't know how important the 10ms are.
  You're familiar with DSound, so perhaps you have an opinion why DSound
  has been using 10ms intervals in Wine regardless of the back-end's period.
  I believe that Wine ought to use the same rate as native or some app will 
exhibit a bug.

- We do not need 10ms events when not using EVENTCALLBACK, so why not
  write all available data (e.g. 333ms from winmm:PlaySound) and sleep
  that much?  Laptop owners will thank us.

- How to continue signaling type a events after IAudioClient_Stop?
  By continuing to write silence to the back-end?!?

- Last but not least, I don't know whether ALSA's signaling and mmdevapi's
  SetEvent needs can be made compatible even when the periods would agree.
  mmdevapi's SetEvent means "don't worry, you have one period time to write 
data"
  or even "you may write data, but I already have buffered some".
  ALSA/PA's signal means(?) "hurry up, you're on the verge of underrun". Please 
correct me.

- The test_worst_case aka. XAudio scenario has tough requirements:
  - Signal events not often enough and you'll enter an underrun.
  - Signal events too early and it'll write no data. The event was wasted and
   the next one may come too late to avoid an underrun.

In summary, if the back-end guarantees 10ms wake-ups, you should be able to
nicely sync a) and b) (probably by writing silence when stopped...)
If not, then some mechanism must be there to decouple the two.

So far we've followed the "decouple" route in winealsa/oss. I believe the key to
the solution in mmdevapi will come from both being able to vary the sleeping
intervals to adapt to clock skew *and* not be bound to be exactly in sync with
the back-end, thanks to a latency-inducing buffer large enough to compensate
for the variability.
IOW, the design goal is to reach during normal playback a state where:
 Event received => GetCurrentPadding has (or pretends to have) decreased by
 at least 1 period (which implies there's room for writing).

Regards,
 Jörg

Reply via email to