--- ./xanim.c.orig	Sat Nov 29 02:14:06 1997
+++ ./xanim.c	Sun Feb 15 22:16:21 1998
@@ -46,7 +46,8 @@
  *           loads and more cpu intensive frames.
  * 10Apr95 - Fixed bug where movies without sound would turn off sound
  *	     is movies listed later on the command line.
- * 28Nov97 - jw: dumpfile option -ZF... added.
+ * 28Nov97 - jw: video dumpfile option -ZF... added.
+ * 14Feb98 - jw: audio dumpfile option -AF... added.
  *
  *******************************/
 
@@ -132,6 +133,7 @@
 
 
 xaULONG xa_forkit;
+xaULONG xa_had_forkit;
 xaULONG xa_vaudio_present;
 xaULONG xa_vaudio_enable;
 xaULONG xa_vaudio_status;
@@ -626,6 +628,7 @@
  fprintf(stdout,"      Ap#   Play Audio from output port #(Sparc only).\n");
 /* fprintf(stdout,"      As#   Scale Audio playback speed by #.\n"); */
  fprintf(stdout,"      Av#   Set Audio volume to #. range 0 to 100.\n");
+ fprintf(stdout,"      AFfname write soundtrack to file fname (sun au format).\n");
  fprintf(stdout,"\n  C[copts]  Color SubMenu\n");
  fprintf(stdout,"      C1    Create cmap from 1st TrueColor frame. Map\n");
  fprintf(stdout,"            the rest to this first cmap.(Could be SLOW)\n");
@@ -715,7 +718,7 @@
  fprintf(stdout,"       Ze   Have XAnim exit after playing cmd line.\n");
  fprintf(stdout,"       Zp#  Pause at specified frame number.\n");
  fprintf(stdout,"       Zpe  Pause at end of animation.\n");
- fprintf(stdout,"       ZFfname write each frame to file fname.\n");
+ fprintf(stdout,"       ZFfname write each frame to file fname (PPM format).\n");
  fprintf(stdout,"\n");
  fprintf(stdout,"Window commands.\n");
  fprintf(stdout,"\n");
@@ -789,6 +792,7 @@
   if ( strcmp( argv[0], "xad\0") == 0) XA_IPC_Set_Debug(xaTRUE);
 
   xa_forkit = XA_Give_Birth();  /* FireUp the Audio Child */
+  xa_had_forkit = xa_forkit;
 
 	/*** Wait for first XA_IPC_OK Acknowlege */
   if (xa_forkit == xaTRUE)	xa_forkit = XA_Video_Receive_Ack(5000);
@@ -1028,7 +1032,7 @@
 /* 
     fprintf(stdout,"XAnim Rev %2.2f.%d by Mark Podlipec (c) 1991-1997\n",DA_REV,DA_MINOR_REV);
 */
-    fprintf(stdout,"XAnim Rev %2.2f.%d.%da by Mark Podlipec (c) 1991-1997\n",DA_REV,DA_MINOR_REV,DA_BETA_REV);
+    fprintf(stdout,"XAnim Rev %2.2f.%d.%dj2 by Mark Podlipec (c) 1991-1998\n",DA_REV,DA_MINOR_REV,DA_BETA_REV);
 
 /* quick command line check.
  */
@@ -1151,6 +1155,13 @@
 		j = len;
 	      }
 	      break;
+	      case 'F':
+	        {
+	          j++; 
+	          XA_AUDIO_DUMP(in+j, len-j);
+		  j = len;
+		}
+		break;
 	      case 'r':   /* POD TEST */
 		j++; vaudiof->playrate = XA_Read_Int(in,&j);
 		if (vaudiof->playrate==0) vaudiof->playrate = 8000;
@@ -1967,6 +1978,8 @@
   xa_now_cycling = xaFALSE;
 
   xa_anim_ready = xaTRUE; /* allow expose event to start animation */
+  if (xa_had_forkit && !xa_forkit)
+    fprintf(stderr, "Warning: Audio IPC too slow, disabled.\n");
 }
 
 /*
--- ./xa_au.c.orig	Sun Jan 26 17:22:03 1997
+++ ./xa_au.c	Sun Feb 15 22:02:31 1998
@@ -11,7 +11,7 @@
  *
  * There is no warranty or other guarantee of fitness of this software.
  * It is provided solely "as is". The author(s) disclaim(s) all
- * responsibility and liability with respect to this software's usage
+ * responsibility and liabilty with respect to this software's usage
  * or its effect upon hardware or computer systems.
  *
  */
@@ -64,7 +64,7 @@
 
   if ( (fin=fopen(fname,XA_OPEN_MODE)) == 0)
   {
-    fprintf(stderr,"can't open AVI File %s for reading\n",fname);
+    fprintf(stderr,"can't open AU File %s for reading\n",fname);
     return(xaFALSE);
   }
 
@@ -156,5 +156,3 @@
   anim_hdr->max_faud_size = au_max_faud_size;
   return(xaTRUE);
 } /* end of read file */
-
-
--- ./xa_acodec.c.orig	Sun Jan 26 17:22:02 1997
+++ ./xa_acodec.c	Sun Feb 15 20:55:44 1998
@@ -53,6 +53,7 @@
 
 xaULONG XA_IPC_Sound();
 xaULONG XA_Add_Sound();
+extern void AU_Dump_Audio();
 extern xaULONG xa_vaudio_hard_buff;
 extern xaULONG xa_audio_hard_type;
 
--- ./xa_ipc.c.orig	Sun Jan 26 17:22:04 1997
+++ ./xa_ipc.c	Sun Feb 15 21:36:11 1998
@@ -118,6 +118,9 @@
 extern xaLONG xa_time_audio;
 extern xaULONG xa_timelo_audio;
 
+char *dumpfileaudio = NULL;
+FILE *dumpfileaudio_fp = NULL;
+
 static xaULONG xa_ipc_cmd_id = 1;
 
 int xa_audio_fd[2];    /* audio child reads this, video writes this */
@@ -661,6 +664,11 @@
       case XA_IPC_AUD_KILL:
 	AUD_DEBUG fprintf(stderr,"AUD IPC: AUD_KILL\n");
 	XA_Audio_Kill();
+	if (dumpfileaudio_fp) 
+	  {
+	    fclose(dumpfileaudio_fp);
+	    dumpfileaudio_fp = NULL;
+	  }
         XA_Audio_Send_ACK(XA_IPC_ACK_OK,ipc_cmd.id,xa_audio_status);
 	break;
 
@@ -732,6 +740,16 @@
       case XA_IPC_FILE:
 	AUD_DEBUG fprintf(stderr,"AUD IPC: received FILE %d\n",ipc_cmd.value);
 	xa_aud_hdr_cur = Get_Aud_Hdr(xa_aud_hdr_cur,ipc_cmd.value);
+	XA_Audio_Send_ACK(XA_IPC_ACK_OK,ipc_cmd.id,0);
+	break;
+      case XA_IPC_DUMP:
+	AUD_DEBUG fprintf(stderr,"AUD DUMPFILE: %d\n",ipc_cmd.value);
+        if (ipc_cmd.len) 
+	  { 
+	    dumpfileaudio = XA_Audio_Receive_Video_Buf(ipc_cmd.len, 500);
+	    AUD_DEBUG fprintf(stderr,"AUD DUMP: %s \n", dumpfileaudio);
+	    ipc_cmd.len = 0;  /* we've used it */
+	  }
 	XA_Audio_Send_ACK(XA_IPC_ACK_OK,ipc_cmd.id,0);
 	break;
 
--- ./xa_audio.c.orig	Sun Jan 26 17:22:03 1997
+++ ./xa_audio.c	Sun Feb 15 22:02:55 1998
@@ -4976,6 +4976,56 @@
   xa_audio_flushed = 1;
 }
 
+extern FILE *dumpfileaudio_fp;
+extern char *dumpfileaudio;
+
+static UTIL_Put_MSB_Long(fp, l)
+FILE *fp;
+unsigned long l;
+{
+  putc((l >> 24) & 0xff, fp);
+  putc((l >> 16) & 0xff, fp);
+  putc((l >>  8) & 0xff, fp);
+  putc((l >>  0) & 0xff, fp);
+}
+
+static void AU_Dump_File(buf, len, ai)
+unsigned char *buf;
+int len;
+audio_info_t *ai;
+{
+  if (dumpfileaudio && !dumpfileaudio_fp)
+    if (!(dumpfileaudio_fp = fopen(dumpfileaudio, "w")))
+      {
+	perror(dumpfileaudio);
+	fprintf(stderr, "Warning: +AF option (dumping of audio data to file) ignored.\n");
+	dumpfileaudio = NULL;
+      }
+    else
+      {
+	/* write .au header */
+	fprintf(dumpfileaudio_fp, ".snd");
+	UTIL_Put_MSB_Long(dumpfileaudio_fp, 6*4);	/* size of .au header */
+	UTIL_Put_MSB_Long(dumpfileaudio_fp, 0xffffffff); /* unknown data size */
+	UTIL_Put_MSB_Long(dumpfileaudio_fp, ai->play.encoding);
+	UTIL_Put_MSB_Long(dumpfileaudio_fp, ai->play.sample_rate);
+	UTIL_Put_MSB_Long(dumpfileaudio_fp, ai->play.channels);
+        DEBUG_LEVEL1 fprintf(stdout, "dumpfile header format %d.\n", ai->play.encoding);
+      }
+  
+  if (dumpfileaudio_fp)
+    {
+      DEBUG_LEVEL1 fprintf(stdout, "dumpfile writing %d bytes.\n", len);
+      if (!fwrite(buf, len, 1, dumpfileaudio_fp))
+        {
+          perror("dumpfileaudio fwrite");
+	  fclose(dumpfileaudio_fp);
+	  dumpfileaudio_fp = NULL;
+	  dumpfileaudio = NULL;
+	}
+    }
+}
+
 
 /********** New_Merged_Audio_Output **********************
  * Set Volume if needed and then write audio data to audio device.
@@ -5057,6 +5107,9 @@
 
 
 /*---------------- Now for the Write Segments -------------------------------*/
+
+      if (dumpfileaudio)
+	AU_Dump_File(xa_audio_ring->buf, xa_audio_ring->len, &audio_info);
 
 #ifdef XA_SPARC_AUDIO
       write(devAudio,xa_audio_ring->buf,xa_audio_ring->len); 
--- ./xa_ipc.h.orig	Sun Jan 26 17:22:05 1997
+++ ./xa_ipc.h	Sun Feb 15 21:05:15 1998
@@ -54,6 +54,7 @@
 #define XA_IPC_RST_TIME		0x00109
 #define XA_IPC_VID_TIME		0x0010a
 #define XA_IPC_MERGEFILE	0x0010b
+#define XA_IPC_DUMP		0x0010c
 /*                               */
 #define XA_IPC_AUD_SETUP	0x00200
 #define XA_IPC_AUD_INIT		0x00201
--- ./xa_ipc_cmds.h.orig	Sun Jan 26 17:22:05 1997
+++ ./xa_ipc_cmds.h	Sun Feb 15 21:04:50 1998
@@ -92,6 +92,8 @@
   XA_Video_Send2_Audio(XA_IPC_UNFILE,0,0,num,1000,0); }
 #define XA_AUDIO_MERGEFILE(num)	{ if (xa_forkit == xaTRUE) xa_forkit = \
   XA_Video_Send2_Audio(XA_IPC_MERGEFILE,0,0,num,1000,0); }
+#define XA_AUDIO_DUMP(name, len) { if (xa_forkit == xaTRUE) xa_forkit = \
+  XA_Video_Send2_Audio(XA_IPC_DUMP,name,len,0,1000,0); }
 
 #else
 
@@ -124,6 +126,7 @@
 #define XA_AUDIO_RST_TIME(x)
 #define XA_AUDIO_UNFILE(num)
 #define XA_AUDIO_MERGEFILE(num)
+#define XA_AUDIO_DUMP(name, len)
 
 #endif
 

