*** linux_a.c.orig	Mon May 20 17:09:46 1996
--- linux_a.c	Tue Jun 16 21:40:17 1998
***************
*** 71,82 ****
     then 8-bit unsigned if it fails. If you have a sound device that
     can't handle either, let me know. */
  
  static int open_output(void)
  {
    int fd, tmp, i, warnings=0;
    
    /* Open the audio device */
!   fd=open(dpm.name, O_RDWR | O_NDELAY);
    if (fd<0)
      {
        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
--- 71,85 ----
     then 8-bit unsigned if it fails. If you have a sound device that
     can't handle either, let me know. */
  
+ /* Flag for Luigi Rizzo new sound driver (as opposed to VoxWare) */
+ static luigi_driver = 0;
+ 
  static int open_output(void)
  {
    int fd, tmp, i, warnings=0;
    
    /* Open the audio device */
!   fd=open(dpm.name, O_RDWR);
    if (fd<0)
      {
        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
***************
*** 84,89 ****
--- 87,109 ----
        return -1;
      }
  
+   /* Figure out if we're running with the Luigi driver or
+      the original VoxWare driver, with code based on dburr/luigi
+      in ports/5607.  It'd be great if we could do this before
+      opening the audio device, but oh well... */
+ #if defined(AIOGFMT)	/* only defined in Luigi driver */
+   {
+     snd_chan_param s;
+     int i;
+     i = ioctl(fd, AIOGFMT, &s);
+     if (i != -1)
+       luigi_driver = 1;
+   }
+ #endif defined (AIOGFMT)
+ 
+   ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "Using %s sound driver",
+ 	    luigi_driver ? "luigi" : "VoxWare");
+ 
    /* They can't mean these */
    dpm.encoding &= ~(PE_ULAW|PE_BYTESWAP);
  
***************
*** 92,97 ****
--- 112,140 ----
       the other one. */
  
    i=tmp=(dpm.encoding & PE_16BIT) ? 16 : 8;
+   if (luigi_driver)
+     {
+       if (dpm.encoding & PE_16BIT) {
+ 	int fmt = AFMT_S16_LE ;
+ 
+ 	if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0 || fmt != AFMT_S16_LE) {
+ 	    fmt = AFMT_U8 ;
+ 	    if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0 || fmt != AFMT_U8) {
+ 		ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
+ 		      "%s doesn't support 16- or 8-bit sample width",
+ 		      dpm.name);
+ 		close(fd);
+ 		return -1;
+ 	    }
+ 	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
+ 		  "Sample width adjusted to %d bits", tmp);
+ 	    dpm.encoding ^= PE_16BIT;
+ 	    warnings = 1;
+ 	}
+       }
+     }
+   else
+     {
    if (ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &tmp)<0 || tmp!=i)
      {
        /* Try the other one */
***************
*** 109,114 ****
--- 152,158 ----
        dpm.encoding ^= PE_16BIT;
        warnings=1;
      }
+     }
    if (dpm.encoding & PE_16BIT)
      dpm.encoding |= PE_SIGNED;
    else
***************
*** 163,168 ****
--- 207,214 ----
    /* Set buffer fragments (in extra_param[0]) */
    
    tmp=AUDIO_BUFFER_BITS;
+   if (luigi_driver)
+     tmp += 2;
    if (!(dpm.encoding & PE_MONO)) tmp++;
    if (dpm.encoding & PE_16BIT) tmp++;
    tmp |= (dpm.extra_param[0]<<16);
***************
*** 189,216 ****
    return warnings;
  }
  
  static void output_data(int32 *buf, int32 count)
  {
    if (!(dpm.encoding & PE_MONO)) count*=2; /* Stereo samples */
    
!   if (dpm.encoding & PE_16BIT)
!     {
        /* Convert data to signed 16-bit PCM */
        s32tos16(buf, count);
!       
!       /* Write the data out. Linux likes to give an EINTR if you suspend
! 	 a program while waiting on a write, so we may need to retry. */
!       while ((-1==write(dpm.fd, buf, count * 2)) && errno==EINTR)
! 	;
!     }
!   else
!     {
        /* Convert to 8-bit unsigned and write out. */
        s32tou8(buf, count);
!       
!       while ((-1==write(dpm.fd, buf, count)) && errno==EINTR)
! 	;
      }
  }
  
  static void close_output(void)
--- 235,269 ----
    return warnings;
  }
  
+ /* output_data comes from Luigi's linux_a.c.  This version seems to allow
+    for partial writes to the sound device, where as the original version
+    doesn't. */
  static void output_data(int32 *buf, int32 count)
  {
+   char *p;
+   int res, l;
+   
    if (!(dpm.encoding & PE_MONO)) count*=2; /* Stereo samples */
    
!   if (dpm.encoding & PE_16BIT) {
        /* Convert data to signed 16-bit PCM */
        s32tos16(buf, count);
!       res = count*2;
!   } else {
        /* Convert to 8-bit unsigned and write out. */
        s32tou8(buf, count);
!       res = count;
!   }
!   for (p = (char *) buf; res > 0; res -= l) {
! again:
!     l = write(dpm.fd, p, res);
!     if (l < 0) {
! 	if (errno == EINTR)
! 		goto again;
! 	return;
      }
+     p += l;
+   }
  }
  
  static void close_output(void)
