Commit 69789889 authored by Sam Lantinga's avatar Sam Lantinga

Fixed bug #572

Please merge this patch for the PA driver in SDL.

http://0pointer.de/public/sdl-pulse-rework.patch

This patch:
- fixes buffering (i.e. reduces number of "fragments" to 2, doesn't defer
filling up of the buffer until the entire buffer ran completely empty.)
- drops $PASERVER and $PADEVICE env var support, since this is a duplication of
$PULSE_SERVER and $PULSE_SINK which the PA libs honor anyway.

This fixes the sound issues in all games I tested.

--HG--
branch : SDL-1.2
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%403846
parent 6bae66b5
/* -*- Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*- */
/* /*
SDL - Simple DirectMedia Layer SDL - Simple DirectMedia Layer
Copyright (C) 1997-2009 Sam Lantinga Copyright (C) 1997-2009 Sam Lantinga
...@@ -18,7 +19,7 @@ ...@@ -18,7 +19,7 @@
Stéphan Kochen Stéphan Kochen
stephan@kochen.nl stephan@kochen.nl
Based on parts of the ALSA and ESounD output drivers. Based on parts of the ALSA and ESounD output drivers.
*/ */
#include "SDL_config.h" #include "SDL_config.h"
...@@ -78,14 +79,14 @@ static int (*SDL_NAME(pa_simple_write))( ...@@ -78,14 +79,14 @@ static int (*SDL_NAME(pa_simple_write))(
pa_simple *s, pa_simple *s,
const void *data, const void *data,
size_t length, size_t length,
int *error int *error
); );
static pa_channel_map* (*SDL_NAME(pa_channel_map_init_auto))( static pa_channel_map* (*SDL_NAME(pa_channel_map_init_auto))(
pa_channel_map *m, pa_channel_map *m,
unsigned channels, unsigned channels,
pa_channel_map_def_t def pa_channel_map_def_t def
); );
static struct { static struct {
const char *name; const char *name;
...@@ -158,16 +159,16 @@ static int Audio_Available(void) ...@@ -158,16 +159,16 @@ static int Audio_Available(void)
if ( LoadPulseLibrary() < 0 ) { if ( LoadPulseLibrary() < 0 ) {
return available; return available;
} }
/* Connect with a dummy format. */ /* Connect with a dummy format. */
paspec.format = PA_SAMPLE_U8; paspec.format = PA_SAMPLE_U8;
paspec.rate = 11025; paspec.rate = 11025;
paspec.channels = 1; paspec.channels = 1;
connection = SDL_NAME(pa_simple_new)( connection = SDL_NAME(pa_simple_new)(
SDL_getenv("PASERVER"), /* server */ NULL, /* server */
"Test stream", /* application name */ "Test stream", /* application name */
PA_STREAM_PLAYBACK, /* playback mode */ PA_STREAM_PLAYBACK, /* playback mode */
SDL_getenv("PADEVICE"), /* device on the server */ NULL, /* device on the server */
"Simple DirectMedia Layer", /* stream description */ "Simple DirectMedia Layer", /* stream description */
&paspec, /* sample format spec */ &paspec, /* sample format spec */
NULL, /* channel map */ NULL, /* channel map */
...@@ -178,7 +179,7 @@ static int Audio_Available(void) ...@@ -178,7 +179,7 @@ static int Audio_Available(void)
available = 1; available = 1;
SDL_NAME(pa_simple_free)(connection); SDL_NAME(pa_simple_free)(connection);
} }
UnloadPulseLibrary(); UnloadPulseLibrary();
return(available); return(available);
} }
...@@ -233,7 +234,7 @@ static void PULSE_WaitAudio(_THIS) ...@@ -233,7 +234,7 @@ static void PULSE_WaitAudio(_THIS)
{ {
/* Check to see if the thread-parent process is still alive */ /* Check to see if the thread-parent process is still alive */
{ static int cnt = 0; { static int cnt = 0;
/* Note that this only works with thread implementations /* Note that this only works with thread implementations
that use a different process id for each thread. that use a different process id for each thread.
*/ */
if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */ if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */
...@@ -302,7 +303,7 @@ static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -302,7 +303,7 @@ static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec)
pa_sample_spec paspec; pa_sample_spec paspec;
pa_buffer_attr paattr; pa_buffer_attr paattr;
pa_channel_map pacmap; pa_channel_map pacmap;
paspec.format = PA_SAMPLE_INVALID; paspec.format = PA_SAMPLE_INVALID;
for ( test_format = SDL_FirstAudioFormat(spec->format); test_format; ) { for ( test_format = SDL_FirstAudioFormat(spec->format); test_format; ) {
switch ( test_format ) { switch ( test_format ) {
...@@ -324,7 +325,7 @@ static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -324,7 +325,7 @@ static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec)
return(-1); return(-1);
} }
spec->format = test_format; spec->format = test_format;
paspec.channels = spec->channels; paspec.channels = spec->channels;
paspec.rate = spec->freq; paspec.rate = spec->freq;
...@@ -338,25 +339,24 @@ static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -338,25 +339,24 @@ static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec)
return(-1); return(-1);
} }
SDL_memset(mixbuf, spec->silence, spec->size); SDL_memset(mixbuf, spec->silence, spec->size);
/* Reduced prebuffering compared to the defaults. */ /* Reduced prebuffering compared to the defaults. */
paattr.tlength = mixlen; paattr.tlength = mixlen*2;
paattr.minreq = mixlen; paattr.minreq = mixlen;
paattr.fragsize = mixlen; paattr.prebuf = mixlen*2;
paattr.prebuf = mixlen; paattr.maxlength = mixlen*2;
paattr.maxlength = mixlen * 4;
/* The SDL ALSA output hints us that we use Windows' channel mapping */ /* The SDL ALSA output hints us that we use Windows' channel mapping */
/* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */ /* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
SDL_NAME(pa_channel_map_init_auto)( SDL_NAME(pa_channel_map_init_auto)(
&pacmap, spec->channels, PA_CHANNEL_MAP_WAVEEX); &pacmap, spec->channels, PA_CHANNEL_MAP_WAVEEX);
/* Connect to the PulseAudio server */ /* Connect to the PulseAudio server */
stream = SDL_NAME(pa_simple_new)( stream = SDL_NAME(pa_simple_new)(
SDL_getenv("PASERVER"), /* server */ NULL, /* server */
get_progname(), /* application name */ get_progname(), /* application name */
PA_STREAM_PLAYBACK, /* playback mode */ PA_STREAM_PLAYBACK, /* playback mode */
SDL_getenv("PADEVICE"), /* device on the server */ NULL, /* device on the server */
"Simple DirectMedia Layer", /* stream description */ "Simple DirectMedia Layer", /* stream description */
&paspec, /* sample format spec */ &paspec, /* sample format spec */
&pacmap, /* channel map */ &pacmap, /* channel map */
...@@ -371,7 +371,6 @@ static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -371,7 +371,6 @@ static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec)
/* Get the parent process id (we're the parent of the audio thread) */ /* Get the parent process id (we're the parent of the audio thread) */
parent = getpid(); parent = getpid();
return(0); return(0);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment