[SDL] SDL sound under Mac OS X and Linux
Darrell Walisser
walisser at mac.com
Sat Nov 23 06:24:01 PST 2002
On Saturday, November 23, 2002, at 06:03 AM, Fredrick Meunier wrote:
> Hi Darell,
>
> Darrell Walisser wrote:
>> On Thursday, November 21, 2002, at 04:06 PM, Fredrick Meunier wrote:
>>> 1) I write unsigned 8 bit samples to my sound card (padded to 16bit
>>> if that's all that is available). Using OSS to output the samples
>>> sounds fine, but using SDL under Linux or OS X sounds clipped when I
>>> am outputting maximum volume (maximum value=128 +- 124). Is this a
>>> known problem with SDL sound output, should I be reducing the max
>>> amplitude of my samples?
>> I've also noticed this in the past. I'm not sure what the cause is.
>> It might be a bug in mixing of 8 bit samples, or conversion of 8 bit
>> to 16 bit samples. Does initializing SDL with 16 bit samples and
>> converting your samples to 16 bit yourself fix the problem?
>
> No, converting the samples to 16 bit myself still leaves the (loudest)
> samples sounding distorted (Linux and Mac OS X), and sounding perfect
> on Linux using OSS.
>
>> This is pure speculation, but I think it's possible that after SDL
>> hands off the samples they are processed again by the sound daemon
>> (or entity that controls the system sound volume) and at that point
>> there might be some distortion. In this case, using a sound format
>> that mirrors the hardware/OS setting might solve the problem.
>
> I'll try a few different combinations and see if it helps.
>
>>> 2) I generate 1/50th of a second of audio at a time and write it to
>>> a ring buffer, the SDL callback then reads the data writes it to the
>>> sound card. Under Linux this works well, CPU usage is low and there
>>> are practically no sound glitches. The same code on Mac OS X mostly
>>> works, but if there is any movement in other windows the sound from
>>> my app glitches. If I minimise my app or go fullscreen the glitches
>>> dissapear. Is anyone else seeing this and are there any suggestions
>>> about fixing the problem?
>
>> I've heard of this before. It might be because when you drag the
>> application window (I presume dragging other application windows
>> doesn't have this problem), the main thread is blocked temporarily (I
>> don't really know why it would be, though). If you are using
>> SDL_LockAudio() and copying to the ring buffer in the main thread,
>> you might have breakups if your audio buffers are too small. See if
>> using a larger audio buffer decreases this effect.
>
> Dragging any window or having the dock pop up will cause glitching.
> I think the main thread is not so much blocked from running as starved
> of CPU as the demands of the window system or other programs
> increases. I guess there are two fixes:
> 1) Make my program less CPU-hungry
> 2) Make the emulator run with real-time priority? Is there a real-time
> scheduling priority available on Mac OS X?
>
> I get much higher CPU load than I would get on Linux (Linux 6% CPU,
> Mac OS X 25-50% CPU as reported by top).
>
> I think that the remaining glitching is mostly caused by my graphics
> routines not being as fast as they could be.
>
> I create my video mode attempting to match the users display like this:
>
> vidinfo = SDL_GetVideoInfo();
> gc = SDL_SetVideoMode( width, height, vidinfo->vfmt->BitsPerPixel,
> SDL_HWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE );
>
> I have an offscreen surface that I create with:
>
> image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, height,
> gc->format->BitsPerPixel, gc->format->Rmask, gc->format->Gmask,
> gc->format->Bmask, gc->format->Amask );
>
> That I draw to on a pixel basis every frame. I blit the relevant
> changed areas from this image to the screen with:
>
> SDL_BlitSurface( image, &updated_rects[num_rects], gc,
> &updated_rects[num_rects] );
>
> (as I am emulating the sweep of the video beam over the screen of the
> emulated hardware there are changes in the image that should not show
> up on screen until the next frame). I keep track of the areas dirtied
> and then do a single call to SDL_UpdateRects every frame. This seems
> plenty fast on Linux, but is there a better way to do it on Mac OS X?
There is a better way. Don't use SDL_HWSURFACE, and don't create an
additional software buffer of the same size as the screen. Mac OS X
doesn't support a hardware screen surface in windowed mode, and windows
in Mac OS X are already double-buffered (note: this doesn't mean you
should use SDL_Flip(), that's why SDL_DOUBLEBUF isn't set on the
surface).
In fullscreen mode Mac OS X uses a hardware, single-buffered surface.
But you would be better off to use a software surface, as it will
likely be faster.
More information about the SDL
mailing list