[uae] Sound issues (was Re: Re: Source code snapshot 20060505)

  • From: Richard Drummond <evilrich@xxxxxxxxxxxxxx>
  • To: uae@xxxxxxxxxxxxx
  • Date: Wed, 10 May 2006 02:26:50 -0400

Hi All

On Tuesday 09 May 2006 02:12, Richard Drummond wrote:
> I should proably take some time out and experiment with this stuff, and see
> what effects changing HZ and the preemption policy have.

Okay. I've been experimenting...

The upshot is, that E-UAE's SDL sound driver doesn't work terribly well on 
Linux unless your kernel has preemption enabled. The OSS and Alsa drivers 
work a hell of a lot better even without preemption.

I'm afraid, as far as I can see, that this is due to the architectures of 
Linux, E-UAE and SDL (Yes, they're all partly to blame.)

SDL creates a separate sound thread with which you register a callback to pass 
audio data to it. The problem is that in E-UAE the audio data is created in 
the main thread. The audio thread thus cannot run whenever it needs to - it 
must synchronize with the main thread which is producing the audio data it 
needs. (BTW, the OSS and Alsa drivers don't have this problem: the main 
thread passes audio data to the respective sound systems directly. Also note, 
that this doesn't necessarily affect all SDL platforms - just systems with 
similar scheduling behaviour/thread model. No such problem occurs on AmigaOS4 
for example.)

Without the preemption, the likelyhood is that the SDL audio thread isn't 
going to be able pass the audio data on to the underlying sound system in 
time. The worse case is when your running E-UAE with cpu_speed=max and 
there's no sleeping being done (for example, Exec has been ditched, so no 
STOP opcodes are being executed). With a preemptable kernel, the problem is 
less noticeable; without, you get stuttering audio output.

There seems little that can be done about that. For example, it would be nice 
if you could somehow raise the priority of the audio thread above the main 
E-UAE thread so that it could preempt it. But SDL has no thread priority 
model (partly because the Unix thread priority model sucks - or it is the 
security model that sucks because you generally don't have the permission to 
raise the priority of a thread).

BTW, I did try experimenting with an 'asynchronous' SDL audio driver. The main 
thread and the audio callback communicated via a lockless ring buffer. The 
problem then is that there's no guarantee that the right amount of audio data 
has been produced by the time the SDL audio thread wants to pass a fixed 
number of bytes along to the sound system. So you end either repeating bytes 
or skipping them. Anyway, it worked a lot better than the existing
 'synchronous' SDL driver when cpu_speed=max (but still nowhere like as well 
as the OSS or ALSA drivers) and worse when cpu_speed=min. So, it probably 
ain't worth the effort.

As a result of my investigations:

1) I recommend that if you are building E-UAE for yourself on Linux, that you 
use the ALSA or OSS sound drivers. I'll be doing just that in my official 
builds. If you need to use the SDL driver for some reason, make sure you read 
point 2).

2) I recommend that if your kernel doesn't have premption built in, then build 
your own kernel with it. While your at it, if it's a recent 2.6 kernel, set 
the timeslice to 1000HZ or 250HZ (which is the default, I believe), but 
definitely not 100HZ.


I'm not sure how this affects other Unix systems. For OS X, this has certainly 
increased the priority of doing a native sound driver for E-UAE.


I should probably try to but together some documentation on performance 
optimization for E-UAE. Anybody want to help out?

Cheers,
Rich

Other related posts: