diff -C 2 -P speak_freely-6.1b/Makefile speak_freely-6.1b_amiga/Makefile
*** speak_freely-6.1b/Makefile	Thu Mar  6 11:17:17 1997
--- speak_freely-6.1b_amiga/Makefile	Wed Mar 12 23:40:54 1997
***************
*** 16,21 ****
  # If they aren't, you need to install them before building Speak
  # Freely.
! CC = cc -float -signed
! LFLAGS = -laudio -lcurses -lm
  
  # SunOS 4.1.x
--- 16,21 ----
  # If they aren't, you need to install them before building Speak
  # Freely.
! #CC = cc -float -signed
! #LFLAGS = -laudio -lcurses -lm
  
  # SunOS 4.1.x
***************
*** 73,76 ****
--- 73,81 ----
  #CCFLAGS = -DHEWLETT_PACKARD -DOLDCC
  #LFLAGS = -lAlib -lcurses -ltermcap -lm
+ 
+ # AmigaOS courtesy of Martin Blom
+ CC = gcc -O3 -m68020-40 #-resident32
+ CCFLAGS = 
+ LFLAGS = -lcurses -lm
  
  # Where Perl is located on your system.  This is used to make
diff -C 2 -P speak_freely-6.1b/README.amiga speak_freely-6.1b_amiga/README.amiga
*** speak_freely-6.1b/README.amiga	Wed Dec 31 22:00:00 1969
--- speak_freely-6.1b_amiga/README.amiga	Wed Mar 12 15:19:59 1997
***************
*** 0 ****
--- 1,19 ----
+ 
+ This is a quick port if John Walker's "Speak Freely" (Unix version). The
+ AUDIO: device that is part of the AHI package (see Aminet:dev/misc/ahi.lha
+ or <URL:http://www.lysator.liu.se/~lcs/ahi.html>) is used to play and
+ record sound. This means that it was a walk in the park to port the
+ program, and that it also supports sound cards.
+ 
+ The program has been compiled for full duplex sound hardware. I tried the
+ program in half duplex mode with a Toccata, but it didn't work too well. If
+ you are unlucky to have a half duplex sound card fear not! Just use your
+ sound card to record, and the native Amiga audio to play!
+ 
+ Selecting which unit of ahi.device to use is simple, just set the
+ environment variables SPEAKFREE_PLAY_UNIT and SPEAKFREE_RECORD_UNIT to the
+ desired unit. Example:
+ 
+ 1> setenv SPEAKFREE_RECORD_UNIT 1
+ 1> copy ENV:SPEAKFREE_RECORD_UNIT ENVARC:
+ 
Common subdirectories: speak_freely-6.1b/adpcm and speak_freely-6.1b_amiga/adpcm
Common subdirectories: speak_freely-6.1b/contrib and speak_freely-6.1b_amiga/contrib
Common subdirectories: speak_freely-6.1b/des and speak_freely-6.1b_amiga/des
Common subdirectories: speak_freely-6.1b/gsm and speak_freely-6.1b_amiga/gsm
Common subdirectories: speak_freely-6.1b/idea and speak_freely-6.1b_amiga/idea
Common subdirectories: speak_freely-6.1b/libdes and speak_freely-6.1b_amiga/libdes
Common subdirectories: speak_freely-6.1b/lpc and speak_freely-6.1b_amiga/lpc
Common subdirectories: speak_freely-6.1b/lpc10 and speak_freely-6.1b_amiga/lpc10
Common subdirectories: speak_freely-6.1b/md5 and speak_freely-6.1b_amiga/md5
diff -C 2 -P speak_freely-6.1b/mike.c speak_freely-6.1b_amiga/mike.c
*** speak_freely-6.1b/mike.c	Wed Mar  5 18:08:20 1997
--- speak_freely-6.1b_amiga/mike.c	Tue Mar 11 23:36:00 1997
***************
*** 1474,1477 ****
--- 1474,1486 ----
  }
  
+ int cleanup(void)
+ {
+     exiting();
+     gsm_destroy(gsmh);
+     lpc_end();
+     desdone();
+ }
+ 
+ 
  /*  Main program.  */
  
***************
*** 1607,1610 ****
--- 1616,1620 ----
  		    makeSessionKey(s, op + 1, TRUE);
  		    printf("%s\n", s);
+ 		    cleanup();
  		    return 0;
  
***************
*** 1663,1666 ****
--- 1673,1677 ----
  			    fprintf(stderr, "Unsupported encryption algorithm: %s.  Only DES-CBC is available.\n",
  				    algorithm);
+ 			    cleanup();
  			    return 2;
  			}
***************
*** 1730,1733 ****
--- 1741,1745 ----
  			if (fp == NULL) {
  			    perror("Cannot open key file");
+ 			    cleanup();
  			    return 2;
  			}
***************
*** 1735,1738 ****
--- 1747,1751 ----
  			if (curotp == NULL) {
  			    fprintf(stderr, "Cannot allocate key file buffer.\n");
+ 			    cleanup();
  			    return 2;
  			}
***************
*** 1761,1764 ****
--- 1774,1778 ----
  		case 'P':	      /* -Phost  --  Copy output to host  */
  		    if (!addest(op + 1)) {
+ 		        cleanup();
  			return 1;
  		    }
***************
*** 1805,1808 ****
--- 1819,1823 ----
  		case '?':	      /* -?  --  Print usage information */
  		    usage();
+ 		    cleanup();
  		    return 0;
  
***************
*** 1833,1836 ****
--- 1848,1852 ----
  			if (pipe == NULL) {
  			    fprintf(stderr, "Unable to open pipe to: %s\n", c);
+ 			    cleanup();
  			    return 2;
  			} else {
***************
*** 1885,1888 ****
--- 1901,1905 ----
  				fclose(kfile);
  				unlink(f);
+ 				cleanup();
  				return 2;
  			    }
***************
*** 1911,1914 ****
--- 1928,1932 ----
  	    if (rtp && vat) {
  		fprintf(stderr, "Cannot choose both -RTP and -VAT protocols simultaneously.\n");
+ 		cleanup();
  		return 2;
  	    }
***************
*** 1917,1920 ****
--- 1935,1939 ----
  		if (curideakey[0] || curpgpkey[0] || curotp != NULL) {
  		    fprintf(stderr, "IDEA, PGP, and Key File encryption cannot be used\n    with -RTP or -VAT protocols.\n");
+ 		    cleanup();
  		    return 2;
  		}
***************
*** 1922,1925 ****
--- 1941,1945 ----
  		if (vat && curkey[0]) {
  		    fprintf(stderr, "DES encryption not implemented for VAT protocol.\n");
+ 		    cleanup();
  		    return 2;
  		}
***************
*** 1927,1934 ****
--- 1947,1956 ----
  		if (compressing) {
  		    fprintf(stderr, "Simple (-C) compression cannot be used with\n   -RTP or -VAT protocols.\n");
+ 		    cleanup();
  		    return 2;
  		}
  		if (lpc10compress) {
  		    fprintf(stderr, "LPC-10 (-LPC10) compression cannot be used with\n	 -RTP or -VAT protocols.\n");
+ 		    cleanup();
  		    return 2;
  		}
***************
*** 1940,1943 ****
--- 1962,1966 ----
  	    if (dests == NULL) {
  		if (!addest(op)) {
+ 		    cleanup();
  		    return 1;
  		}
***************
*** 1945,1948 ****
--- 1968,1972 ----
  		int ok = sendfile(op);
  		if (ok != 0)
+ 		    cleanup();
  		    return ok;
  		sentfile++;
***************
*** 1950,1966 ****
  	}
      }
- 
      if (dests == NULL) {
  	usage();
      } else {
  	if (sentfile == 0) {
! 	    return sendfile(NULL);
  	}
      }
  
!     exiting();
!     gsm_destroy(gsmh);
!     lpc_end();
!     desdone();
      return 0;
  }
--- 1974,1989 ----
  	}
      }
      if (dests == NULL) {
  	usage();
      } else {
  	if (sentfile == 0) {
! 	    int rc = sendfile(NULL);
! 	    cleanup();
! 	    return rc;
  	}
      }
  
!     cleanup();
      return 0;
  }
+ 
diff -C 2 -P speak_freely-6.1b/soundbyte.c speak_freely-6.1b_amiga/soundbyte.c
*** speak_freely-6.1b/soundbyte.c	Wed Mar  5 18:04:49 1997
--- speak_freely-6.1b_amiga/soundbyte.c	Thu Mar 13 11:23:32 1997
***************
*** 531,532 ****
--- 531,751 ----
  }
  #endif
+ 
+ 
+ #ifdef amigaos
+ 
+ /*
+ 
+       AmigaOS audio driver, using the AUDIO: device.
+ 
+       The AUDIO: device is included in the AHI distribution
+ 
+       Implemented by Martin Blom.
+ */
+ 
+ 
+ #include <stdio.h>
+ #include <fcntl.h>
+ 
+ /*  Local variables  */
+ 
+ static int paudiof = -1;        /* For playing   */
+ static int raudiof = -1;        /* For recording */
+ static int mode    = -1;
+ static int volume  = 100;
+ 
+ static char WriteFile[256];     /* For the template */
+ static char ReadFile[256];      /* For the template */
+ 
+ static short pbuf[BUFL];        /* Buffer for playing */
+ static short rbuf[BUFL];        /* Buffer for recording */
+ 
+ 
+ /*  SOUNDINIT  --  Open the sound peripheral and initialise for
+                    access.  Return TRUE if successful, FALSE
+                    otherwise.  */
+ 
+ int soundinit(iomode)
+   int iomode;
+ {
+   char *variable;
+   int punit   = 0;
+   int runit   = 0;
+ 
+   /* Save mode for soundplayvol() */
+   mode = iomode;
+ 
+   if(iomode == -1) {
+     return FALSE;
+   }
+ 
+   /* Find out where to read and play audio */
+   
+   variable = getenv("SPEAKFREE_PLAY_UNIT");
+   if(variable) {
+     punit = strtol(variable, NULL, 10);
+   }
+ 
+   variable = getenv("SPEAKFREE_RECORD_UNIT");
+   if(variable) {
+     runit = strtol(variable, NULL, 10);
+   }
+ 
+   sprintf((char *) WriteFile,
+       "AUDIO:BITS/16/FREQUENCY/8000/CHANNELS/1/TYPE/SIGNED/"
+       "VOLUME/%d/BUFFER/8192/UNIT/%d", volume, punit);
+   sprintf((char *) ReadFile,
+       "AUDIO:BITS/16/FREQUENCY/8000/CHANNELS/1/TYPE/SIGNED/"
+       "BUFFER/2048/UNIT/%d", runit);
+ 
+   if (iomode != O_RDONLY) {
+     if ((paudiof = open(WriteFile, O_WRONLY)) < 0) {
+       fprintf(stderr, "Audio open: unable to open \"%s\"\n", WriteFile);
+       return FALSE;
+     }
+   }
+ 
+   if (iomode != O_WRONLY) {
+     if ((raudiof = open(ReadFile, O_RDONLY)) < 0) {
+       fprintf(stderr, "Audio open: unable to open \"%s\"\n", ReadFile);
+       return FALSE;
+     }
+   }
+ 
+   return TRUE;
+ }
+ 
+ 
+ /*  SOUNDTERM  --  Close the sound device.  */
+ 
+ void soundterm()
+ {
+   if (paudiof >= 0) {
+     if (close(paudiof) < 0) {
+       perror("closing audio device");
+     }
+     paudiof = -1;
+   }
+   if (raudiof >= 0) {
+     if (close(raudiof) < 0) {
+       perror("closing audio device");
+     }
+     raudiof = -1;
+   }
+   mode   = -1;
+ }
+ 
+ 
+ /*  SOUNDPLAY  --  Begin playing a sound.  */
+ 
+ void soundplay(len, buf)
+   int len;
+   unsigned char *buf;
+ {
+   int ios;
+   int i;
+ 
+   if(len > BUFL) {
+     len = BUFL;
+   }
+ 
+   /* Convert µlaw to 16 bit */
+   for (i = 0; i < len; i++) {
+     pbuf[i] = audio_u2s(buf[i]);
+   }
+ 
+   while (TRUE) {
+     ios = write(paudiof, pbuf, len << 1 );
+     if (ios == -1) {
+       sf_usleep(100000);
+     } else {
+       ios >>= 1;
+       if (ios < len ) {
+         buf += ios;
+         len -= ios;
+       } else {
+         break;
+       }
+     }
+   }
+ }
+ 
+ 
+ /*  SOUNDPLAYVOL  --  Set playback volume from 0 (silence) to 100 (full on). */
+ 
+ void soundplayvol(value)
+   int value;
+ {
+   volume = value;
+   soundterm();
+   soundinit(mode);
+ }
+ 
+ 
+ /*  SOUNDRECGAIN  --  Set recording gain from 0 (minimum) to 100 (maximum).  */
+ 
+ void soundrecgain(value)
+   int value;
+ {
+ }
+ 
+ 
+ /*  SOUNDDEST  --  Set destination for generated sound.  If "where"
+                    is 0, sound goes to the built-in speaker; if
+                    1, to the audio output jack. */
+ 
+ void sounddest(where)
+   int where;
+ {
+ }
+ 
+ /*  SOUNDGRAB  --  Return audio information in the record queue.  */
+ 
+ int soundgrab(buf, len)
+     char *buf;
+     int len;
+ {
+   long read_size;
+   int c;
+   int i;
+ 
+   if(len > BUFL) {
+     len = BUFL;
+   }
+ 
+   read_size = len;
+ 
+   while (TRUE) {
+     c = read(raudiof, rbuf, read_size << 1);
+     if (c < 0) {
+       if (errno == EINTR) {
+         continue;
+       }
+     } else {
+       c >>= 1;
+     }
+     break;
+   }
+   if (c < 0) {
+     perror("soundgrab");
+   }
+   
+   /* Convert 16 bit to µlaw */
+   for (i = 0; i < len; i++) {
+     buf[i] = audio_s2u(rbuf[i]);
+   }
+ 
+   return c;
+ }
+ 
+ /*  SOUNDFLUSH  --  Flush any queued sound.  */
+ 
+ void soundflush()
+ {
+ /*
+   soundterm();
+   soundinit(mode);
+ */
+ }
+ 
+ #endif /* amigaos */
