--- linux_a.c.orig2	Fri Aug 27 18:55:49 1999
+++ linux_a.c	Fri Aug 27 18:57:18 1999
@@ -61,10 +61,6 @@
 #include "playmidi.h"
 #include "miditrace.h"
 
-/* It is possible count_info.bytes > written bytes. bug? */
-#define BYTES_PROCESSED_BUGFIX 1
-static int ignore_processed_probrem = 0;
-
 #ifndef AFMT_S16_NE
 #ifdef LITTLE_ENDIAN
 #define AFMT_S16_NE AFMT_S16_LE
@@ -78,6 +74,7 @@
 static int output_data(char *buf, int32 nbytes);
 static int acntl(int request, void *arg);
 static int output_counter, counter_offset;
+static int total_bytes; /* Maximum buffer size in bytes */
 
 /* export the playback mode */
 
@@ -107,6 +104,9 @@
 {
     int fd, tmp, i, warnings = 0;
     int include_enc, exclude_enc;
+#ifdef SNDCTL_DSP_GETOSPACE
+    audio_buf_info info;
+#endif /* SNDCTL_DSP_GETOSPACE */
 
     /* Open the audio device */
     fd = open(dpm.name, O_WRONLY);
@@ -229,9 +229,15 @@
     }
 #endif
 
+#ifdef SNDCTL_DSP_GETOSPACE
+    if(ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) != -1)
+	total_bytes = info.fragstotal * info.fragsize;
+    else
+#endif /* SNDCTL_DSP_GETOSPACE */
+	total_bytes = -1; /* Unknown */
+
     dpm.fd = fd;
     output_counter = counter_offset = 0;
-    ignore_processed_probrem = 0;
 
     return warnings;
 }
@@ -240,20 +246,6 @@
 {
     int n;
 
-#if defined(BYTES_PROCESSED_BUGFIX) && defined(SNDCTL_DSP_GETOPTR)
-    if(!ignore_processed_probrem)
-    {
-	count_info cinfo;
-	ioctl(dpm.fd, SNDCTL_DSP_GETOPTR, &cinfo);
-	if(output_counter < cinfo.bytes)
-	{
-	    counter_offset += output_counter;
-	    ioctl(dpm.fd, SNDCTL_DSP_SYNC);
-	    output_counter = 0;
-	}
-    }
-#endif
-
     while(nbytes > 0)
     {
 	if((n = write(dpm.fd, buf, nbytes)) == -1)
@@ -293,86 +285,58 @@
 
 static int acntl(int request, void *arg)
 {
-    audio_buf_info info;
-    count_info cinfo;
-    int total, bytes;
+    int i;
 
     switch(request)
     {
       case PM_REQ_DISCARD:
 	counter_offset = output_counter = 0;
-	ignore_processed_probrem = 0;
 	return ioctl(dpm.fd, SNDCTL_DSP_RESET);
 
       case PM_REQ_FLUSH:
 	counter_offset = output_counter = 0;
-	ignore_processed_probrem = 0;
 	return ioctl(dpm.fd, SNDCTL_DSP_SYNC);
 
-      case PM_REQ_RATE: {
-	  int rate;
-	  rate = *(int *)arg;
-	  if(ioctl(dpm.fd, SNDCTL_DSP_SPEED, &rate) < 0)
-	      return -1;
-	  play_mode->rate = rate;
-	  return 0;
-	}
+      case PM_REQ_RATE:
+	i = *(int *)arg; /* sample rate in and out */
+	if(ioctl(dpm.fd, SNDCTL_DSP_SPEED, &i) < 0)
+	    return -1;
+	play_mode->rate = i;
+	return 0;
 
-#ifdef SNDCTL_DSP_GETOPTR
       case PM_REQ_GETQSIZ:
-	if(ioctl(dpm.fd, SNDCTL_DSP_GETOSPACE, &info) == -1)
-	{
-	    ignore_processed_probrem = 1;
+	if(total_bytes <= 0)
 	    return -1;
-	}
-	total = info.fragstotal * info.fragsize;
-	*((int *)arg) = total;
+	*((int *)arg) = total_bytes;
 	return 0;
 
-
-      case PM_REQ_GETFILLABLE:
-	if(ioctl(dpm.fd, SNDCTL_DSP_GETOSPACE, &info) == -1)
-	{
-	    ignore_processed_probrem = 1;
+#ifdef SNDCTL_DSP_GETODELAY
+      case PM_REQ_GETFILLED:
+	if(total_bytes <= 0 || ioctl(dpm.fd, SNDCTL_DSP_GETODELAY, &i) == -1)
 	    return -1;
-	}
-	total = info.fragstotal * info.fragsize;
-	bytes = info.bytes;
-	if(bytes > total)
-	    bytes = total;
-	if(!(dpm.encoding & PE_MONO)) bytes >>= 1;
-	if(dpm.encoding & PE_16BIT) bytes >>= 1;
-	*((int *)arg) = bytes;
+	if(!(dpm.encoding & PE_MONO)) i >>= 1;
+	if(dpm.encoding & PE_16BIT) i >>= 1;
+	*((int *)arg) = i;
 	return 0;
 
-      case PM_REQ_GETFILLED:
-	if(ioctl(dpm.fd, SNDCTL_DSP_GETOSPACE, &info) == -1)
-	{
-	    ignore_processed_probrem = 1;
+      case PM_REQ_GETFILLABLE:
+	if(total_bytes <= 0 || ioctl(dpm.fd, SNDCTL_DSP_GETODELAY, &i) == -1)
 	    return -1;
-	}
-	total = info.fragstotal * info.fragsize;
-	bytes = info.bytes;
-	if(bytes > total)
-	    bytes = total;
-	bytes = total - bytes;
-	if(!(dpm.encoding & PE_MONO)) bytes >>= 1;
-	if(dpm.encoding & PE_16BIT) bytes >>= 1;
-	*((int *)arg) = bytes;
+        i = total_bytes - i;
+	if(!(dpm.encoding & PE_MONO)) i >>= 1;
+	if(dpm.encoding & PE_16BIT) i >>= 1;
+	*((int *)arg) = i;
 	return 0;
 
       case PM_REQ_GETSAMPLES:
-	if(ioctl(dpm.fd, SNDCTL_DSP_GETOPTR, &cinfo) == -1)
-	{
-	    ignore_processed_probrem = 1;
+	if(total_bytes <= 0 || ioctl(dpm.fd, SNDCTL_DSP_GETODELAY, &i) == -1)
 	    return -1;
-	}
-	bytes = cinfo.bytes + counter_offset;
-	if(!(dpm.encoding & PE_MONO)) bytes >>= 1;
-	if(dpm.encoding & PE_16BIT) bytes >>= 1;
-	*((int *)arg) = bytes;
+	i = output_counter - i;
+	if(!(dpm.encoding & PE_MONO)) i >>= 1;
+	if(dpm.encoding & PE_16BIT) i >>= 1;
+	*((int *)arg) = i;
 	return 0;
-#endif /* SNDCTL_DSP_GETOPTR */
+#endif /* SNDCTL_DSP_GETODELAY */
     }
     return -1;
 }

