http://bugs.winehq.org/show_bug.cgi?id=29294
--- Comment #21 from Jörg Höhle hoehle@users.sourceforge.net 2012-03-01 16:50:15 CST ---
No sound from these tests as plughw:0,0 is being used.
Please investigate further. winmm:wave iterates across all winmm devices, so it should use all devices that mmdevapi could open, likely not solely plughw:0,0.
Then I'd like you to run the render+winmm+dsound tests N times, every time with a different audio device selected via winecfg. Verify in the log that mmdevapi's default device changes. This is the one that gets used to produce the sine wave in the render test. You now know how to use the log's AUDDRV_GetAudioEndpoint lines to verify what gets used (search for the last occurrence in the file). What differences can you observe or hear?
35.166:0009:trace:dsound:DirectSoundDevice_Create 35.166:0009:trace:dsound:DSOUND_ReopenDevice 35.166:0009:trace:alsa:AUDDRV_GetAudioEndpoint "default"
SH4 uses DSound.
alsa:dump_fmt nSamplesPerSec: 44100 alsa:AudioClient_Initialize ALSA period: 5512 frames alsa:AudioClient_Initialize ALSA buffer: 16537 frames alsa:AudioClient_Initialize MMDevice period: 441 frames alsa:AudioClient_Initialize MMDevice buffer: 5120 frames
Winealsa is in trouble because its buffer is smaller than ALSA's period! This is almost a guarantee for underruns.
I now see that was already present in the render log:
alsa:dump_fmt nSamplesPerSec: 48000 alsa:AudioClient_Initialize ALSA period: 6000 frames alsa:AudioClient_Initialize ALSA buffer: 18000 frames alsa:AudioClient_Initialize MMDevice period: 480 frames alsa:AudioClient_Initialize MMDevice buffer: 2400 frames
But there our lead-in prevented an underrun (as it was designed to do) in the test_worst_case XAudio2 scenario:
alsa:alsa_write_data lead-in 6192
with SH4 and DSound, the lead-in is much smaller due to DSound's own prefill: alsa:alsa_write_data lead-in 1009
These are the issues: - Huge ALSA period. Absence of stutter in the mmdevapi:render test proves that the situation is not as unbearable as it seems. Probably we can continue to pretend to operate with 10ms periods known from mmdevapi (and DSound), instead of switching to ALSA's 125ms period. Yet it's a bit hairy.
- CreateTimerQueueTimer, known from bug #28723, comment #130, kicks in at about 11ms only. That's not enough. Because of that, ALSA padding slowly decreases from 6288 (more than one ALSA period) to 3600 (a half period) while playing 1 second. If you would change the render test to play for 1 minute, it would hit an underrun. Can you increase the number of iterations (i<5999) in dlls/mmdevapi/tests/render.c:2102 and recompile to check that?
- DSound. It doesn't yet use GetCurrentPadding and GetPosition like I believe it should. Actually, I believe it should implement a behaviour not unlike XAudio2(!)... Again, how do the dlls/dsound/tests sound? The log shows that DSound lets padding decrease from ~6000 to ~4000. If it were doing its job well, padding would remain roughly constant.
- Delays from ALSA 41.535:0027:trace:alsa:alsa_write_data pad: 0 41.555:0027:trace:alsa:alsa_write_data lead-in 1009 Why did 20ms elapse upon start? Perhaps ALSA needs that much time to set up processing.
- Out of the blue underruns 41.667:0027:trace:alsa:alsa_write_data pad: 4439 41.674:0028:trace:alsa:AudioClock_GetPosition frames written: 8704, held: 0, avail: 11939, delay: 4598 state 3, pos: 4106 41.677:0027:trace:alsa:alsa_write_data pad: 4421 41.684:0028:trace:alsa:AudioClock_GetPosition frames written: 9216, held: 0, avail: 11956, delay: 4581 state 4, pos: 9216
ALSA has 100ms of data, yet it will signal an underrun. Surprisingly, the underruns are periodic and 130-140ms apart, which is close to the period size. Oddly, you said the render test played fine and they happen to have even fewer frames left in the ALSA buffer. Perhaps the different frame rate makes a difference? Please retry SH4 after setting DefaultSampleRate to 48000 for DSound in the registry. Check in the log that 48000 gets used then.
Perhaps underruns would not happen if ALSA always had a full period? The lead-in was designed to satisfy that property, but it still requires CreateTimerQueue or DSound to refill data fast enough.