
/* Minimal-capability speech support package.
 * Author:		Mark R. Rinfret
 * Date:		07/30/87
 * Description:
 *
 *		This package provides a quick and dirty means for adding
 *		speech to C language programs.  In order to use it, observe
 *		the following:
 *
 *			1. Call SpeechOn - return parameter of 0 => success.
 *			2. Call Say(<your message in English>) as often as the
 *			   application requires.
 *			3. Call SpeechOff to close libraries/ports/devices.
 */

#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <devices/narrator.h>
#include <libraries/translator.h>
#include <functions.h>

/*#define DEBUG */


#define PHONEME_MAX 1024L		/* size of phoneme buffer */

/* Which audio channels to use */

BYTE audio_chan[] = {3, 5, 10, 12};

struct Library *TranslatorBase = NULL;
struct narrator_rb voice_io;	/* Narrator I/O request block */
struct MsgPort *voice_port = NULL;
ULONG narrator_status = -1L,translate_error;

UBYTE Phonemes[PHONEME_MAX];	/* Phoneme text buffer */

/******************
 *    ROUTINES    *
 ******************/

/* Enable speech capability. */

SpeechOn(on)
	int on;
{

   if (!(TranslatorBase = (struct Library *)
    	OpenLibrary("translator.library", (long) LIBRARY_VERSION))) {
#ifdef DEBUG
      	DebugWrite("Can't open the translator library!\n");
#endif
fail:
	    SpeechOff();			/* close whatever's open */
      	return 1;
   }

	/* Open a reply port for the narrator. */

	if (!(voice_port = CreatePort(0L, 0L))) {
#ifdef DEBUG
		DebugWrite("Can't create narrator reply port!\n");
#endif
		goto fail;
	}

	voice_io.message.io_Message.mn_ReplyPort = voice_port;

   /* Open the device */
   if ((narrator_status = 
   			OpenDevice("narrator.device", 0L, &voice_io, 0L))) {
#ifdef DEBUG
      DebugWrite("Can't open the Narrator device!\n");
#endif
      goto fail;
   }


   return 0;
}

SpeechOff()
{
	if (voice_port) 
		DeletePort(voice_port);

   	if (!narrator_status)
      	CloseDevice(&voice_io);

   	if (TranslatorBase)
      	CloseLibrary(TranslatorBase);

   	return(0);
}

Say(English)
	char *English;
{
	if (!TranslatorBase) {
		if (SpeechOn())	return 1;
	}

    if (translate_error = 
		Translate(English, (long) strlen(English), 
				  Phonemes, PHONEME_MAX)) {
#ifdef DEBUG
         DebugWrite("Translator error!\n");
#endif
      }

/* Set up the write channel information */

	voice_io.ch_masks = (UBYTE *) (audio_chan);
	voice_io.nm_masks = sizeof(audio_chan);
	voice_io.mouths = 0;
	voice_io.message.io_Command = CMD_WRITE;
	voice_io.message.io_Offset = 0;
	voice_io.message.io_Data = (APTR)Phonemes;
	voice_io.message.io_Message.mn_Length = sizeof(voice_io);
	voice_io.message.io_Length = strlen(Phonemes);
	DoIO(&voice_io);
} 


#ifdef DEBUG
DebugWrite(msg)
	char *msg;
{
	puts(msg);
}

main()
{
	short i;
 	char *s;

static char *text[] = {
	"I am an Amiga computer.  I am currently testing my voice ability.",
	"This is pretty incredible, don't you agree?  I thought you would.",
	"This package is really a set of routines to be used by an application.",
	"All you have to do is call Speech On first, ",
	"then call Say as often as you like.",
	NULL
	};

	SpeechOn();
	for (i = 0;s = text[i]; ++i) {
		Say(s);
		Delay(30L);
	}
	SpeechOff();
}
#endif
