--- /dev/null
+--- esound-0.2.22.orig/configure.in
++++ esound-0.2.22/configure.in
+@@ -50,6 +50,7 @@
+ AC_CHECK_LIB(rt,nanosleep,,[AC_CHECK_LIB(posix4,nanosleep)])])
+ AC_CHECK_FUNCS(usleep)
+ AC_CHECK_FUNC(inet_aton,,[AC_CHECK_LIB(resolv,inet_aton)])
++AC_CHECK_FUNCS(strtok_r)
+
+ case $ac_cv_func_nanosleep/$ac_cv_lib_rt_nanosleep/$ac_cv_lib_posix4_nanosleep in
+ no/no/no) ;;
+--- esound-0.2.22.orig/esddsp.in
++++ esound-0.2.22/esddsp.in
+@@ -92,8 +92,10 @@
+ exec_prefix=@exec_prefix@
+ libdir=@libdir@
+
+-export LD_PRELOAD_PATH=${libdir}
+-export LD_PRELOAD='libesddsp.so libesd.so'
++# Don't try to connect to esd if it isn't running
++#if [ ! "x`pidof esd`" = "x" ]; then
++ export LD_PRELOAD="${libdir}/libesddsp.so.0:${libdir}/libesd.so.0"
++#fi
+
+ # invoke the program with the args given
+ exec "$@"
+--- esound-0.2.22.orig/esddsp.c
++++ esound-0.2.22/esddsp.c
+@@ -185,6 +185,11 @@
+
+ if (!strcmp (pathname, "/dev/dsp"))
+ {
++/* We shouldn't need this with Unix domain sockets, plus there
++ * is a better test in esdlib.c - for more info see:
++ * http://www.debian.org/Bugs/db/53/53602.html
++ * commented out by bma@debian.org 1999-12-29 */
++/*
+ if (!getenv ("ESPEAKER"))
+ {
+ int ret;
+@@ -193,6 +198,7 @@
+ if ((ret = (*func) (pathname, flags, mode)) >= 0)
+ return ret;
+ }
++*/
+
+ DPRINTF ("hijacking /dev/dsp open, and taking it to esd...\n");
+ settings = done = 0;
+--- esound-0.2.22.orig/esdlib.c
++++ esound-0.2.22/esdlib.c
+@@ -637,7 +637,7 @@
+ /* ebm - I think this is an Inherently Bad Idea, but will leave it
+ alone until I can get a good look at it */
+ if(! (host && *host)) {
+- int childpid, mypid;
++ pid_t childpid, mypid;
+ struct sigaction sa, sa_orig;
+ struct sigaction sa_alarm, sa_orig_alarm;
+
+@@ -666,9 +666,10 @@
+ char *cmd;
+
+ setsid();
+- cmd = malloc(sizeof("esd ") + esd_spawn_options?strlen(esd_spawn_options):0);
++ chdir("/tmp");
+
+- sprintf(cmd, "esd %s -spawnpid %d", esd_spawn_options?esd_spawn_options:"", mypid);
++ cmd = malloc(sizeof("esd -spawnpid ") + esd_spawn_options?strlen(esd_spawn_options):0 + 10);
++ sprintf(cmd, "esd %s -spawnpid %u", esd_spawn_options?esd_spawn_options:"", mypid);
+
+ execl("/bin/sh", "/bin/sh", "-c", cmd, NULL);
+ perror("execl");
+--- esound-0.2.22.orig/esd_config.c
++++ esound-0.2.22/esd_config.c
+@@ -5,6 +5,14 @@
+ #include <string.h>
+
+ #define LINEBUF_SIZE 1024
++
++#ifdef HAVE_STRTOK_R
++#define DO_STRTOK(S,DELIM) strtok_r(S,DELIM,&strtok_state)
++char strtok_state[LINEBUF_SIZE];
++#else
++#define DO_STRTOK(S,DELIM) strtok(S,DELIM)
++#endif
++
+ int esd_no_spawn=1; /* If we can't find even the system config file,
+ things are screwed up - don't try to make things
+ worse. */
+@@ -90,9 +98,9 @@
+ break;
+ }
+
+- key = strtok(aline, "=");
++ key = DO_STRTOK(aline, "=");
+ if(!key) continue;
+- value = strtok(NULL, "=");
++ value = DO_STRTOK(NULL, "=");
+ if(!value) value = "";
+
+ if(!strcasecmp(key, "auto_spawn"))
+--- esound-0.2.22.orig/audio.c
++++ esound-0.2.22/audio.c
+@@ -7,6 +7,7 @@
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
+ #include <math.h>
++#include <errno.h>
+
+ /*******************************************************************/
+ /* globals */
+@@ -76,7 +77,22 @@
+ /* dump a buffer to the sound device */
+ int esd_audio_write( void *buffer, int buf_size )
+ {
+- return write( esd_audio_fd, buffer, buf_size );
++ ssize_t nwrite=0, pos=0;
++ int counter = 0;
++
++ while (counter < 100 && (nwrite = write( esd_audio_fd, buffer+pos, buf_size-pos )) != buf_size-pos ) {
++ if ( nwrite > 0 ) {
++ pos += nwrite;
++ } else if ( nwrite == -1 ) {
++ if ( errno == EAGAIN ) {
++ usleep(100);
++ counter++;
++ } else {
++ return -1;
++ }
++ }
++ }
++ return pos;
+ }
+ #endif
+
+--- esound-0.2.22.orig/audio_alsa.c
++++ esound-0.2.22/audio_alsa.c
+@@ -22,7 +22,7 @@
+ static snd_pcm_format_t alsa_format;
+ static snd_pcm_channel_info_t alsa_pinfo;
+ static int alsa_direction = SND_PCM_OPEN_PLAYBACK;
+-static int alsa_mode = SND_PCM_MODE_BLOCK;
++static int alsa_mode = SND_PCM_MODE_STREAM;
+ static int alsa_channel = SND_PCM_CHANNEL_PLAYBACK;
+ #endif
+
+@@ -65,13 +65,6 @@
+ int nbr_cards, ret;
+ char buf[256];
+ struct snd_ctl_hw_info hw_info;
+- static int frag_size = 4*1024;
+-
+-#ifdef ALSA_5_API
+- static int frag_count = 0;
+-#else
+- static int frag_count = 2;
+-#endif
+
+ #ifdef ALSA_5_API
+ snd_pcm_channel_params_t params;
+@@ -84,6 +77,10 @@
+
+ snd_ctl_t *ctl_handle;
+
++ if ( esd_audio_device ) {
++ card = atoi( esd_audio_device );
++ }
++
+ if( driver_trace ) {
+ fprintf( stderr, "Using ALSA %s\n", SND_LIB_VERSION_STR );
+ }
+@@ -127,7 +124,7 @@
+ fprintf( stderr, "esd: Found %d card(s)\n", nbr_cards );
+ }
+
+- for ( card=0; ( card < nbr_cards ) && (alsa_sound_handle == NULL); card++ ) {
++ for ( ; ( card < nbr_cards ) && (alsa_sound_handle == NULL); card++ ) {
+ if( driver_trace ) {
+ fprintf( stderr, "esd: trying alsa card %d\n", card );
+ }
+@@ -199,9 +196,8 @@
+ }
+
+ memset(¶ms, 0, sizeof(params));
+- params.buf.block.frag_size = frag_size;
+- params.buf.block.frags_max = frag_count;
+- params.buf.block.frags_min = 1;
++ params.buf.stream.queue_size = ESD_BUF_SIZE;
++ params.buf.stream.fill = SND_PCM_FILL_NONE;
+ params.channel = alsa_channel;
+ params.mode = alsa_mode;
+ params.start_mode = SND_PCM_START_FULL;
+@@ -343,43 +339,44 @@
+ #define ARCH_esd_audio_write
+ int esd_audio_write( void *buffer, int buf_size )
+ {
+- int i=0;
++ ssize_t nwrite=0, pos=0;
++ int counter = 0;
+
+ #ifdef ALSA_5_API
+ snd_pcm_channel_status_t status;
+ int ret;
+ #endif
+
+- i = snd_pcm_write( alsa_sound_handle, buffer, buf_size);
+- if( i<0 ) {
+-#if 0
+- fprintf( stderr, "error: %s: in snd_pcm_write\n", snd_strerror(i) );
+-#endif
+- }
+-
++ while (counter < 100 && (nwrite = snd_pcm_write( alsa_sound_handle, buffer+pos, buf_size-pos )) != buf_size-pos ) {
++ if ( nwrite > 0 ) {
++ pos += nwrite;
++ } else if ( nwrite < 0 ) {
++ if ( errno == EAGAIN ) {
++ usleep(100);
++ counter++;
++ } else {
+ #ifdef ALSA_5_API
+- status.channel = SND_PCM_CHANNEL_PLAYBACK;
+- ret = snd_pcm_channel_status( alsa_sound_handle, &status );
+- if( ret ) {
+- if( driver_trace ) fprintf( stderr, "error: %s: in snd_pcm_channel_status\n", snd_strerror(ret) );
+- return(-1);
+- }
+- if( status.underrun ) {
+- snd_pcm_channel_flush( alsa_sound_handle, alsa_channel );
+- snd_pcm_playback_prepare( alsa_sound_handle );
+- snd_pcm_write( alsa_sound_handle, buffer, buf_size );
+- if (snd_pcm_channel_status( alsa_sound_handle, &status ) < 0 && driver_trace) {
+- fprintf(stderr, "ALSA: could not get channel status. giving up\n");
+- return -1;
+- }
+- if (status.underrun) {
+- if( driver_trace ) fprintf(stderr, "ALSA: write error. giving up\n");
+- return -1;
+- }
+- }
++ status.channel = alsa_channel;
++ ret = snd_pcm_channel_status( alsa_sound_handle, &status );
++ if( ret ) {
++ if( driver_trace ) fprintf( stderr, "error: %s: in snd_pcm_channel_status\n", snd_strerror(ret) );
++ return(-1);
++ }
++ if( status.status == SND_PCM_STATUS_UNDERRUN ) {
++ counter++;
++ snd_pcm_channel_flush( alsa_sound_handle, alsa_channel );
++ snd_pcm_playback_prepare( alsa_sound_handle );
++ usleep(100);
++ } else {
++ return -1;
++ }
++#else
++ return -1;
+ #endif /* ALSA_5_API */
+-
+- return (i);
++ }
++ }
++ }
++ return pos;
+ }
+
+ #define ARCH_esd_audio_flush
+--- esound-0.2.22.orig/esd.c
++++ esound-0.2.22/esd.c
+@@ -191,7 +191,7 @@
+ return -1;
+ /* set the connect information */
+ socket_unix.sun_family = AF_UNIX;
+- strncpy(socket_unix.sun_path, ESD_UNIX_SOCKET_NAME, sizeof(socket_unix.sun_path));
++ strncpy(socket_unix.sun_path, ESD_UNIX_SOCKET_NAME, sizeof(socket_unix.sun_path)-1);
+ if ( connect( socket_out,
+ (struct sockaddr *) &socket_unix, SUN_LEN(&socket_unix) ) < 0 )
+ return -1;
+@@ -754,11 +754,8 @@
+ while ( 1 )
+ {
+ /* block while waiting for more clients and new data */
+- wait_for_clients_and_data( listen_socket );
+-
+- /* accept new connections */
+- get_new_clients( listen_socket );
+-
++ if ( wait_for_clients_and_data( listen_socket ) ||
++ esd_playing_samples || esd_recorder_list ) {
+
+ if ((esd_clients_list == NULL) && (!first) && (esd_terminate)) {
+ /* fprintf(stderr, "No clients!\n");*/
+@@ -777,7 +774,9 @@
+ /* awaken if on autostandby and doing anything */
+ if ( esd_on_autostandby && length && !esd_forced_standby ) {
+ ESDBG_TRACE( printf( "stuff to play, waking up.\n" ); );
+- esd_server_resume();
++ if ( !esd_server_resume()) {
++ usleep(100);
++ }
+ }
+
+ /* we handle this even when length == 0 because a filter could have
+@@ -846,6 +845,7 @@
+ restrain.tv_usec *= 1000L; /* convert to microseconds */
+ select( 0, 0, 0, 0, &restrain );
+ #endif
++ }
+ }
+ } /* while ( 1 ) */
+
+--- esound-0.2.22.orig/clients.c
++++ esound-0.2.22/clients.c
+@@ -17,6 +17,7 @@
+
+ /*******************************************************************/
+ /* globals */
++extern int esd_use_tcpip;
+
+ /* the list of the currently connected clients */
+ esd_client_t *esd_clients_list;
+@@ -129,17 +130,20 @@
+ do {
+ fd = accept( listen, (struct sockaddr*) &incoming, &size_in );
+ if ( fd > 0 ) {
+- port = ntohs( incoming.sin_port );
+- addr = ntohl( incoming.sin_addr.s_addr );
+-
+ ESDBG_TRACE(
++ if (esd_use_tcpip) {
++ port = ntohs( incoming.sin_port );
++ addr = ntohl( incoming.sin_addr.s_addr );
++
+ printf( "(%02d) new client from: %03u.%03u.%03u.%03u:%05d\n",
+ fd, (unsigned int) addr >> 24,
+ (unsigned int) (addr >> 16) % 256,
+ (unsigned int) (addr >> 8) % 256,
+- (unsigned int) addr % 256, port ); );
++ (unsigned int) addr % 256, port );
++ } );
+
+ #ifdef USE_LIBWRAP
++ if (esd_use_tcpip)
+ {
+ struct request_info req;
+ struct servent *serv;
+@@ -270,7 +274,7 @@
+ "paused=%d, samples=%d, auto=%d, standby=%d, record=%d, ready=%d\n",
+ is_paused_here, esd_playing_samples,
+ esd_autostandby_secs, esd_on_standby,
+- (esd_recorder != 0), ready ); );
++ (esd_recorder_list != 0), ready ); );
+
+ /* TODO: return ready, and do this in esd.c */
+ if ( ready <= 0 ) {
+@@ -304,6 +308,10 @@
+
+ is_paused_here = 0;
+
++ }
++
++ if ( FD_ISSET(listen, &rd_fds ) ) {
++ get_new_clients( listen );
+ }
+
+ return ready;
+--- esound-0.2.22.orig/mix.c
++++ esound-0.2.22/mix.c
+@@ -592,7 +592,7 @@
+ rd_dat = wr_dat * player->rate / esd_audio_rate;
+ rd_dat /= 2; /* adjust for mono */
+
+- sample = source_data_uc[ rd_dat++ ];
++ sample = source_data_uc[ rd_dat ];
+ sample -= 127; sample *= 256;
+
+ mixed_buffer[ wr_dat++ ] += sample;
+@@ -624,7 +624,7 @@
+ {
+ rd_dat = wr_dat * player->rate / esd_audio_rate;
+
+- sample = source_data_uc[ rd_dat++ ];
++ sample = source_data_uc[ rd_dat ];
+ sample -= 127; sample *= 256;
+
+ mixed_buffer[ wr_dat++ ] += sample;
+@@ -650,7 +650,7 @@
+ rd_dat = wr_dat * player->rate / esd_audio_rate;
+ rd_dat /= 2; /* adjust for mono */
+
+- sample = source_data_ss[ rd_dat++ ];
++ sample = source_data_ss[ rd_dat ];
+
+ mixed_buffer[ wr_dat++ ] += sample;
+ mixed_buffer[ wr_dat++ ] += sample;
+@@ -680,7 +680,7 @@
+ while ( wr_dat < length/sizeof(signed short) )
+ {
+ rd_dat = wr_dat * player->rate / esd_audio_rate;
+- sample = source_data_ss[ rd_dat++ ];
++ sample = source_data_ss[ rd_dat ];
+ mixed_buffer[ wr_dat++ ] += sample;
+ }
+ }
+@@ -706,7 +706,7 @@
+ rd_dat = wr_dat * player->rate / esd_audio_rate;
+ rd_dat /= 2; /* adjust for mono */
+
+- sample = source_data_uc[ rd_dat++ ];
++ sample = source_data_uc[ rd_dat ];
+ sample -= 127; sample *= 256;
+
+ sample = sample * player->left_vol_scale / ESD_VOLUME_BASE;
+@@ -751,7 +751,7 @@
+ sample = sample * player->left_vol_scale / ESD_VOLUME_BASE;
+ mixed_buffer[ wr_dat++ ] += sample;
+
+- sample = source_data_uc[ rd_dat++ ];
++ sample = source_data_uc[ rd_dat ];
+ sample -= 127; sample *= 256;
+ sample = sample * player->right_vol_scale / ESD_VOLUME_BASE;
+ mixed_buffer[ wr_dat++ ] += sample;
+@@ -777,7 +777,7 @@
+ rd_dat = wr_dat * player->rate / esd_audio_rate;
+ rd_dat /= 2; /* adjust for mono */
+
+- sample = source_data_ss[ rd_dat++ ];
++ sample = source_data_ss[ rd_dat ];
+
+ mixed_buffer[ wr_dat++ ]
+ += sample * player->left_vol_scale / ESD_VOLUME_BASE;
+@@ -820,7 +820,7 @@
+ sample = sample * player->left_vol_scale / ESD_VOLUME_BASE;
+ mixed_buffer[ wr_dat++ ] += sample;
+
+- sample = source_data_ss[ rd_dat++ ];
++ sample = source_data_ss[ rd_dat ];
+ sample = sample * player->right_vol_scale / ESD_VOLUME_BASE;
+ mixed_buffer[ wr_dat++ ] += sample;
+ }
+@@ -875,14 +875,14 @@
+ /* takes all input players, and mixes them to the mixed_buffer */
+ int mix_players( void *output, int length )
+ {
+- int actual = 0, max = 0;
++ int actual = 0, min = 0, max = 0, translated = 0, iBps, used;
+ esd_player_t *player = NULL;
+ esd_player_t *erase = NULL;
+
+ ESDBG_MIXER( printf( "++++++++++++++++++++++++++++++++++++++++++\n" ); );
+
+ /* zero the sum buffer */
+- memset( mixed_buffer, 0, esd_buf_size_samples * sizeof(int) );
++ memset( mixed_buffer, 0, ESD_BUF_SIZE * sizeof(signed int) );
+
+ /* as long as there's a player out there */
+ player = esd_players_list;
+@@ -890,21 +890,45 @@
+ {
+ /* read the client sound data */
+ actual = read_player( player );
+-
+- /* read_player(): >0 = data, ==0 = no data, <0 = erase it */
+- if ( actual > 0 ) {
+- /* printf( "received: %d bytes from %d\n",
+- actual, player->source_id ); */
+- /* actual = mix_to_stereo_32s( player, length ); */
+- actual = player->mix_func( player, length );
+- if ( actual > max ) max = actual;
+-
+- } else if ( actual == 0 ) {
+- ESDBG_TRACE( printf( "(%02d) no data available from player [%p]\n",
++
++ if ( actual == 0 ) {
++ ESDBG_TRACE( printf( "(%02d) no new data available from player [%p]\n",
+ player->source_id, player ); );
+- } else {
++ if ( player->actual_length == 0 ) {
++ player = player->next;
++ continue;
++ }
++ }
++
++ if ( actual < 0 ) {
+ /* actual < 0 means erase the player */
+ erase = player;
++ } else {
++ /* actual >= 0 means data might be there to mix */
++ iBps = sizeof(signed short) * 2;
++
++ if ( (player->format & ESD_MASK_BITS) == ESD_BITS8 )
++ iBps /= sizeof(signed short);
++ if ( (player->format & ESD_MASK_CHAN) == ESD_MONO )
++ iBps /= 2;
++
++ /* how much data is really there? */
++ translated = ((player->actual_length / iBps) * esd_audio_rate + player->rate - 1) / player->rate;
++ translated *= sizeof(signed short) * 2;
++
++ if ( translated > length ) {
++ ESDBG_TRACE( printf( "(%02d) player translated length doesn't fit [%p]\n",
++ player->source_id, player ); );
++ translated = length;
++ }
++
++ if ( min == 0 ) {
++ min = translated;
++ } else {
++ if ( min > translated ) {
++ min = translated;
++ }
++ }
+ }
+
+ /* check out the next item in the list */
+@@ -917,13 +941,54 @@
+ }
+ }
+
++ if ( min > 0 ) {
++ player = esd_players_list;
++ while( player != NULL )
++ {
++ if ( player->actual_length > 0 ) {
++ /* read_player(): >0 = data, ==0 = no data, <0 = erase it */
++ iBps = sizeof(signed short) * 2;
++
++ if ( (player->format & ESD_MASK_BITS) == ESD_BITS8 )
++ iBps /= sizeof(signed short);
++ if ( (player->format & ESD_MASK_CHAN) == ESD_MONO )
++ iBps /= 2;
++
++ actual = player->mix_func( player, min );
++
++ /* but how much data did we use? */
++ used = (actual / (sizeof(signed short) * 2)) * player->rate / esd_audio_rate;
++
++ if ( (player->format & ESD_MASK_BITS) != ESD_BITS8 )
++ used *= sizeof(signed short);
++ if ( (player->format & ESD_MASK_CHAN) != ESD_MONO )
++ used *= 2;
++
++ if ( player->actual_length - used > 0 ) {
++ memmove( player->data_buffer, player->data_buffer + used, player->actual_length - used );
++ player->actual_length -= used;
++ } else {
++ /* kill it, it's probably all used anyways */
++ player->actual_length = 0;
++ }
++
++ if ( actual > max ) {
++ max = actual;
++ }
++ }
++
++ /* check out the next item in the list */
++ player = player->next;
++ }
++
+ /* ESDBG_COMMS( printf( "maximum stream length = %d bytes\n", max ); ); */
+
+- if ( (esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 )
+- clip_mix_to_output_16s( output, max );
+- else {
+- clip_mix_to_output_8u( output, max );
+- max /= 2; /* half as many samples as you'd think */
++ if ( (esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 )
++ clip_mix_to_output_16s( output, max );
++ else {
++ clip_mix_to_output_8u( output, max );
++ max /= 2; /* half as many samples as you'd think */
++ }
+ }
+
+ return max;
+--- esound-0.2.22.orig/players.c
++++ esound-0.2.22/players.c
+@@ -287,27 +287,28 @@
+ FD_SET( player->source_id, &rd_fds );
+
+ /* if the data is ready, read a block */
+- can_read = select( player->source_id + 1,
+- &rd_fds, NULL, NULL, &timeout ) ;
++ can_read = (( player->actual_length < player->buffer_length ) &&
++ select( player->source_id + 1, &rd_fds, NULL, NULL, &timeout ));
++
+ if ( can_read > 0 )
+ {
+- ESD_READ_BIN( player->source_id, player->data_buffer,
+- player->buffer_length, actual, "str rd" );
++ ESD_READ_BIN( player->source_id, player->data_buffer+player->actual_length,
++ player->buffer_length-player->actual_length, actual, "str rd" );
+
+ /* check for end of stream */
+ if ( actual == 0
+ || ( actual < 0 && errno != EAGAIN && errno != EINTR ) )
+ return -1;
+
+- /* more data, save how much we got */
+- player->actual_length = actual;
+-
+ /* endian swap multi-byte data if we need to */
+ client = (esd_client_t *) (player->parent);
+ if ( client->swap_byte_order
+ && ( (player->format & ESD_MASK_BITS) == ESD_BITS16 ) )
+ {
+- buffer = (unsigned short*) player->data_buffer;
++ /* this will break if a read doesn't get us 16bit aligned
++ * data...
++ */
++ buffer = (unsigned short*) player->data_buffer+player->actual_length;
+ for ( pos = buffer
+ ; pos < buffer + actual / sizeof(short)
+ ; pos ++ )
+@@ -317,6 +318,9 @@
+ }
+ }
+
++ /* more data, save how much we got */
++ player->actual_length += actual;
++
+ } else if ( can_read < 0 ) {
+ sprintf( message, "error reading client (%d)\n",
+ player->source_id );
+@@ -330,6 +334,7 @@
+
+ /* printf( "player [%p], pos = %d, format = 0x%08x\n",
+ player, player->last_pos, player->format ); */
++ player->actual_length = 0;
+
+ /* only keep going if we didn't want to stop looping */
+ if ( ( player->last_pos ) == 0 &&
+@@ -351,6 +356,7 @@
+ player->last_pos += actual;
+ if ( ( player->format & ESD_MASK_FUNC ) != ESD_LOOP ) {
+ /* we're done for this iteration */
++ player->actual_length = actual;
+ break;
+ }
+ } else {
+@@ -387,6 +393,7 @@
+ /* something horrible has happened to the sample */
+ return -1;
+ }
++ player->actual_length = actual;
+
+ /* sample data is swapped as it's cached, no swap needed here */
+ break;
+@@ -541,8 +548,8 @@
+ if ( (player->format & ESD_MASK_CHAN) == ESD_MONO )
+ player->buffer_length /= 2;
+
+- /* force to an even multiple of 4 */
+- player->buffer_length += ( 4 - (player->buffer_length % 4) ) % 4;
++ /* force to an even multiple of 4 bytes (lower) */
++ player->buffer_length -= (player->buffer_length % 4);
+
+ player->data_buffer
+ = (void *) malloc( player->buffer_length );
+@@ -553,6 +560,7 @@
+ return NULL;
+ }
+
++ player->actual_length = 0;
+ /* everything's ok, set the easy stuff */
+ player->left_vol_scale = player->right_vol_scale = ESD_VOLUME_BASE;
+ player->mix_func = get_mix_func( player );
+@@ -614,7 +622,7 @@
+ player->buffer_length /= 2;
+
+ /* force to an even multiple of 4 */
+- player->buffer_length += ( 4 - (player->buffer_length % 4) ) % 4;
++ player->buffer_length -= ( player->buffer_length % 4 );
+
+ player->data_buffer
+ = (void *) malloc( player->buffer_length );
+@@ -628,6 +636,7 @@
+ /* update housekeeping values */
+ esd_playing_samples++;
+ player->last_pos = 0;
++ player->actual_length = 0;
+ sample->ref_count++;
+ player->mix_func = get_mix_func( player );
+ player->translate_func = NULL; /* no translating, just mixing */
+--- esound-0.2.22.orig/proto.c
++++ esound-0.2.22/proto.c
+@@ -336,14 +336,13 @@
+ /* let the device know we want to record */
+ ESDBG_TRACE( printf( "closing audio for a sec...\n" ); );
+ esd_audio_close();
+- sleep(1);
+ esd_audio_format |= ESD_RECORD;
+ ESDBG_TRACE( printf( "reopening audio to record...\n" ); );
+ if (esd_audio_open() < 0) {
+ /* Failed to record */
+ free_player( recorder );
+ esd_audio_format &= ~ESD_RECORD;
+- sleep(1);
++ usleep(100);
+ /* If we fail here, we have a oops */
+ esd_audio_open();
+ return 0;
+--- esound-0.2.22.orig/esdcat.c
++++ esound-0.2.22/esdcat.c
+@@ -60,7 +60,7 @@
+ #endif
+
+ format = bits | channels | mode | func;
+- printf( "opening socket, format = 0x%08x at %d Hz\n",
++ fprintf( stderr, "opening socket, format = 0x%08x at %d Hz\n",
+ format, rate );
+
+ /* sock = esd_play_stream( format, rate ); */
+--- esound-0.2.22.orig/esd-server.h
++++ esound-0.2.22/esd-server.h
+@@ -15,6 +15,7 @@
+ #include <sys/ioctl.h>
+ #include <netinet/in.h>
+ #include <sys/socket.h>
++#include <sys/un.h>
+ #include <signal.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+--- esound-0.2.22.orig/esdmon.c
++++ esound-0.2.22/esdmon.c
+@@ -52,7 +52,7 @@
+ }
+
+ format = bits | channels | mode | func;
+- printf( "opening socket, format = 0x%08x at %d Hz\n",
++ fprintf( stderr, "opening socket, format = 0x%08x at %d Hz\n",
+ format, rate );
+
+ sock = esd_monitor_stream( format, rate, host, argv[0] );
+--- esound-0.2.22.orig/esdrec.c
++++ esound-0.2.22/esdrec.c
+@@ -54,7 +54,7 @@
+ }
+
+ format = bits | channels | mode | func;
+- printf( "opening socket, format = 0x%08x at %d Hz\n",
++ fprintf( stderr, "opening socket, format = 0x%08x at %d Hz\n",
+ format, rate );
+
+ /* sock = esd_record_stream( format, rate ); */
+--- esound-0.2.22.orig/esdsample.c
++++ esound-0.2.22/esdsample.c
+@@ -95,7 +95,7 @@
+ if ( sock <= 0 )
+ return 1;
+ format = bits | channels | mode | func;
+- printf( "opening socket, format = 0x%08x at %d Hz\n",
++ fprintf( stderr, "opening socket, format = 0x%08x at %d Hz\n",
+ format, rate );
+
+ stat( name, &source_stats );
+--- esound-0.2.22.orig/esdloop.c
++++ esound-0.2.22/esdloop.c
+@@ -67,7 +67,7 @@
+ }
+
+ format = bits | channels | mode | func;
+- printf( "opening socket, format = 0x%08x at %d Hz\n",
++ fprintf( stderr, "opening socket, format = 0x%08x at %d Hz\n",
+ format, rate );
+
+ sock = esd_open_sound( host );
+--- esound-0.2.22.orig/esd.m4
++++ esound-0.2.22/esd.m4
+@@ -38,6 +38,8 @@
+ if test "$ESD_CONFIG" = "no" ; then
+ no_esd=yes
+ else
++ AC_LANG_SAVE
++ AC_LANG_C
+ ESD_CFLAGS=`$ESD_CONFIG $esdconf_args --cflags`
+ ESD_LIBS=`$ESD_CONFIG $esdconf_args --libs`
+
+@@ -114,6 +116,7 @@
+ ],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
++ AC_LANG_RESTORE
+ fi
+ fi
+ if test "x$no_esd" = x ; then
+@@ -133,6 +136,8 @@
+ echo "*** Could not run ESD test program, checking why..."
+ CFLAGS="$CFLAGS $ESD_CFLAGS"
+ LIBS="$LIBS $ESD_LIBS"
++ AC_LANG_SAVE
++ AC_LANG_C
+ AC_TRY_LINK([
+ #include <stdio.h>
+ #include <esd.h>
+@@ -152,6 +157,7 @@
+ echo "*** may want to edit the esd-config script: $ESD_CONFIG" ])
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
++ AC_LANG_RESTORE
+ fi
+ fi
+ ESD_CFLAGS=""
+