diff -ruN mpg123-0.59r.orig/audio.c mpg123-0.59r/audio.c
--- mpg123-0.59r.orig/audio.c	Wed Apr  7 00:53:05 1999
+++ mpg123-0.59r/audio.c	Wed May 10 16:13:12 2000
@@ -19,7 +19,8 @@
   ai->handle = NULL;
   ai->alsa_format.format = -1;
   ai->alsa_format.rate = -1;
-  ai->alsa_format.channels = -1;
+  ai->alsa_format.voices = -1;
+  ai->buf = NULL;
 #endif
   ai->device = NULL;
   ai->channels = -1;
diff -ruN mpg123-0.59r.orig/audio.h mpg123-0.59r/audio.h
--- mpg123-0.59r.orig/audio.h	Wed Jun 16 05:22:03 1999
+++ mpg123-0.59r/audio.h	Wed May 10 16:13:12 2000
@@ -53,8 +53,9 @@
   long gain;
   int output;
 #ifdef ALSA
-  void *handle;
+  snd_pcm_t *handle;
   snd_pcm_format_t alsa_format;
+  unsigned char *buf;
 #endif
   char *device;
   int channels;
Binary files mpg123-0.59r.orig/audio.o and mpg123-0.59r/audio.o differ
diff -ruN mpg123-0.59r.orig/audio_alsa.c mpg123-0.59r/audio_alsa.c
--- mpg123-0.59r.orig/audio_alsa.c	Fri May 28 19:25:50 1999
+++ mpg123-0.59r/audio_alsa.c	Fri May 12 20:38:12 2000
@@ -4,6 +4,7 @@
  *  Code by Anders Semb Hermansen <ahermans@vf.telia.no>
  *  Cleanups by Jaroslav Kysela <perex@jcu.cz>
  *              Ville Syrjala <syrjala@sci.fi>
+ *  ALSA 0.[56] support by katsuhiro Ueno <katsu@blue.sky.or.jp>
  *
  *  You can use -a <soundcard #>:<device #>...
  *  For example: mpg123 -a 1:0 aaa.mpg
@@ -72,33 +73,107 @@
 		return -1;
 	}
 
+	if (ai->buf)
+		free(ai->buf);
+	ai->buf = NULL;
+
 	return 0;
 }
 
 static void audio_set_playback_params(struct audio_info_struct *ai)
 {
 	int err;
-	snd_pcm_playback_info_t pi;
-	snd_pcm_playback_params_t pp;
-
-	if((err=snd_pcm_playback_info(ai->handle, &pi)) < 0 )
+	snd_pcm_channel_info_t ci;
+	snd_pcm_channel_params_t cp;
+	snd_pcm_channel_setup_t setup;
+
+	if(ai->alsa_format.rate == -1
+	   || ai->alsa_format.format == -1
+	   || ai->alsa_format.voices == -1)
+		return;
+
+	memset(&ci, 0, sizeof(ci));
+	ci.channel = SND_PCM_CHANNEL_PLAYBACK;
+	if((err=snd_pcm_channel_info(ai->handle, &ci)) < 0 )
 	{
-		fprintf(stderr, "playback info failed: %s\n", snd_strerror(err));
+		fprintf(stderr, "snd_pcm_channel_info failed: %s\n", snd_strerror(err));
 		return;	/* not fatal error */
 	}
 
-	bzero(&pp, sizeof(pp));
-	pp.fragment_size = pi.buffer_size/4;
-	if (pp.fragment_size > pi.max_fragment_size) pp.fragment_size = pi.max_fragment_size;
-	if (pp.fragment_size < pi.min_fragment_size) pp.fragment_size = pi.min_fragment_size;
-	pp.fragments_max = -1;
-	pp.fragments_room = 1;
+	snd_pcm_channel_flush(ai->handle, SND_PCM_CHANNEL_PLAYBACK);
+
+	if(ai->alsa_format.rate < ci.min_rate
+	   || ci.max_rate < ai->alsa_format.rate) {
+		fprintf(stderr, "unsupported rate %dHz\n", ai->alsa_format.rate);
+		return;
+	}
+	if(ai->alsa_format.voices < ci.min_voices
+	   || ci.max_voices < ai->alsa_format.voices) {
+		fprintf(stderr, "unsupported voice %d\n", ai->alsa_format.voices);
+		return;
+	}
+	if(!(ci.formats & (1 << ai->alsa_format.format))) {
+		fprintf(stderr, "unsupported format\n");
+		return;
+	}
+
+	memset(&cp, 0, sizeof(cp));
+	cp.mode = SND_PCM_MODE_BLOCK;
+	cp.channel = SND_PCM_CHANNEL_PLAYBACK;
+	cp.start_mode = SND_PCM_START_FULL;
+#if SND_LIB_MINOR >= 6
+	cp.xrun_mode = SND_PCM_XRUN_FLUSH;
+#else
+	cp.stop_mode = SND_PCM_STOP_STOP;
+#endif
+	cp.format.interleave = 1;
+	cp.format.format     = ai->alsa_format.format;
+	cp.format.rate       = ai->alsa_format.rate;
+	cp.format.voices     = ai->alsa_format.voices;
+
+#if SND_LIB_MINOR >= 6
+	cp.frag_size   = audiobufsize;
+	cp.buffer_size = ci.buffer_size;
+	cp.buf.block.frags_xrun_max = 0;
+	cp.buf.block.frags_min = 1;
+#else
+	cp.buf.block.frag_size = audiobufsize;
+	cp.buf.block.frags_max = -1;
+	cp.buf.block.frags_min = 1;
+#endif
+
+	if((err=snd_pcm_channel_params(ai->handle, &cp)) < 0 )
+	{
+		fprintf(stderr, "snd_pcm_channel_params failed: %s\n", snd_strerror(err));
+		return; /* not fatal error */
+	}
+
+	if((err=snd_pcm_channel_prepare(ai->handle, SND_PCM_CHANNEL_PLAYBACK)) < 0 )
+	{
+		fprintf(stderr, "snd_pcm_channel_prepare failed: %s\n", snd_strerror(err));
+		return; /* not fatal error */
+	}
 
-	if((err=snd_pcm_playback_params(ai->handle, &pp)) < 0 )
+	memset(&setup, 0, sizeof(setup));
+	setup.channel = SND_PCM_CHANNEL_PLAYBACK;
+	if((err=snd_pcm_channel_setup(ai->handle, &setup)) < 0 )
 	{
-		fprintf(stderr, "playback params failed: %s\n", snd_strerror(err));
+		fprintf(stderr, "snd_pcm_channel_setup failed: %s\n", snd_strerror(err));
 		return; /* not fatal error */
 	}
+	if (setup.format.format != ai->alsa_format.format
+	    || setup.format.rate != ai->alsa_format.rate
+	    || setup.format.voices != ai->alsa_format.voices
+#if SND_LIB_MINOR >= 6
+	    || setup.frag_size != audiobufsize
+#else
+	    || setup.buf.block.frag_size != audiobufsize
+#endif
+	    )
+	{
+		fprintf(stderr, "format not supported.\n");
+		return;
+	}
 }
 
 int audio_reset_parameters(struct audio_info_struct *ai)
@@ -107,6 +182,7 @@
 	audio_set_channels(ai);
 	audio_set_rate(ai);
 
+	audio_set_playback_params(ai);
 	return 0;
 }
 
@@ -117,42 +193,24 @@
 
 int audio_set_rate(struct audio_info_struct *ai)
 {
-	int ret;
-
 	if(!ai || ai->rate < 0)
 		return -1;
 
 	ai->alsa_format.rate=ai->rate;
-
-	if((ret=snd_pcm_playback_format(ai->handle, &ai->alsa_format)) < 0 )
-		return -1;
-
-	audio_set_playback_params(ai);
-
 	return 0;
 }
 
 int audio_set_channels(struct audio_info_struct *ai)
 {
-	int ret;
-
-	if(ai->alsa_format.channels < 0)
+	if(ai->channels < 0)
 		return 0;
 
-	ai->alsa_format.channels = ai->channels;
-
-	if((ret=snd_pcm_playback_format(ai->handle, &ai->alsa_format)) < 0 )
-		return -1;
-
-	audio_set_playback_params(ai);
-
+	ai->alsa_format.voices = ai->channels;
 	return 0;
 }
 
 int audio_set_format(struct audio_info_struct *ai)
 {
-	int ret;
-
 	if(ai->format == -1)
 		return 0;
 
@@ -179,11 +237,6 @@
 			break;
 	}
 
-	if((ret=snd_pcm_playback_format(ai->handle, &ai->alsa_format)) < 0 )
-		return -1;
-
-	audio_set_playback_params(ai);
-
 	return 0;
 }
 
@@ -191,7 +244,7 @@
 {
 	int i, err;
 	int fmt = -1;
-	snd_pcm_playback_info_t pi;
+	snd_pcm_channel_info_t ci;
 
 	static int fmts[] = {
 		AUDIO_FORMAT_SIGNED_16, AUDIO_FORMAT_UNSIGNED_16,
@@ -204,14 +257,16 @@
 		SND_PCM_FMT_MU_LAW, SND_PCM_FMT_A_LAW
 	};
 
-	if((err=snd_pcm_playback_info(ai->handle, &pi)) < 0 )
+	memset(&ci, 0, sizeof(ci));
+	ci.channel = SND_PCM_CHANNEL_PLAYBACK;
+	if((err=snd_pcm_channel_info(ai->handle, &ci)) < 0 )
 	{
-		fprintf(stderr, "playback info failed: %s\n", snd_strerror(err));
+		fprintf(stderr, "snd_pcm_channel_info failed: %s\n", snd_strerror(err));
 		return -1;
 	}
 
 	for (i = 0; i < 6; i++) {
-		if (pi.formats & afmts[i]) {
+		if (ci.formats & afmts[i]) {
 			if (fmt == -1)
 				fmt = 0;
 			fmt |= fmts[i];
@@ -223,16 +278,57 @@
 
 int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
 {
-	ssize_t ret;
+	int n;
+	snd_pcm_channel_status_t cs;
+
+	if (len < audiobufsize) {
+		if (!ai->buf) {
+			ai->buf = malloc(audiobufsize);
+			if (!ai->buf)
+				return -1;
+		}
+		memcpy(ai->buf, buf, len);
+#if SND_LIB_MINOR >= 6
+		snd_pcm_format_set_silence(ai->alsa_format.format,
+					   ai->buf + len, audiobufsize - len);
+#else
+		memset(ai->buf + len, 0, audiobufsize - len);
+#endif
+		buf = ai->buf;
+	}
 
-	ret=snd_pcm_write(ai->handle, buf, len);
+	n = snd_pcm_write(ai->handle, buf, audiobufsize);
 
-	return ret;
+	if (n != audiobufsize) {
+		memset(&cs, 0, sizeof(cs));
+		cs.channel = SND_PCM_CHANNEL_PLAYBACK;
+		snd_pcm_channel_status(ai->handle, &cs);
+#if SND_LIB_MINOR >= 6
+		if (cs.status != SND_PCM_STATUS_XRUN)
+#else
+		if (cs.status != SND_PCM_STATUS_UNDERRUN)
+#endif
+			return -1;
+		snd_pcm_channel_flush(ai->handle, SND_PCM_CHANNEL_PLAYBACK);
+		snd_pcm_channel_prepare(ai->handle, SND_PCM_CHANNEL_PLAYBACK);
+		n = snd_pcm_write(ai->handle, buf, audiobufsize);
+		if (n != audiobufsize) {
+			fprintf(stderr, "snd_pcm_write: %s", snd_strerror(n));
+			return -1;
+		}
+	}
+
+	return len;
 }
 
 int audio_close(struct audio_info_struct *ai)
 {
 	int ret;
+
+	if (ai->buf)
+		free(ai->buf);
+
+	snd_pcm_channel_flush(ai->handle, SND_PCM_CHANNEL_PLAYBACK);
 	ret = snd_pcm_close(ai->handle);
 	return ret;
 }
diff -ruN mpg123-0.59r.orig/mpg123.h mpg123-0.59r/mpg123.h
--- mpg123-0.59r.orig/mpg123.h	Fri May 28 23:51:58 1999
+++ mpg123-0.59r/mpg123.h	Fri May 12 20:34:52 2000
@@ -53,11 +53,11 @@
 #endif
 
 #ifdef REAL_IS_FLOAT
-#  define real float
+typedef float real;
 #elif defined(REAL_IS_LONG_DOUBLE)
-#  define real long double
+typedef long double real;
 #else
-#  define real double
+typedef double real;
 #endif
 
 #ifdef __GNUC__
