
/*
     Say.c      Version 1.0

     True BASIC subroutine written in C.  You pass it
     a True BASIC string, and it speaks the string aloud
     using the Amiga's voice synthesizer.

     See Appendices D and E of your "User's Guide" for
     more information.

*/


#include <Assembly/tb.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <devices/narrator.h>
#include <libraries/translator.h>

#define CONVSIZE 400 /* size of our phonetic conversion buffer */

LONG TranslatorBase;
LONG SysBase;

struct MsgPort *writeport=0;
struct narrator_rb *writeNarrator=0;
BYTE audChanMasks[4] = {3,5,10,12};

extern struct MsgPort *CreatePort();
extern LONG AbsExecBase;

void say(argp)

   struct TBString ***argp; /* pointer to parameters */

  {register struct TBString *sp;
   register char *cp;
   char outputstring[CONVSIZE];
   WORD loc,len,error;

   SysBase = AbsExecBase;

   TranslatorBase = OpenLibrary("translator.library",0);
   if (TranslatorBase == 0) goto done;

   writeport = CreatePort(0,0);
   if (writeport == NULL) goto done;

   writeNarrator = (struct narrator_rb *)
        AllocMem(sizeof(struct narrator_rb),MEMF_CLEAR | MEMF_PUBLIC);
   if (writeNarrator == NULL) goto done;

   writeNarrator->message.io_Message.mn_Node.ln_Type = NT_MESSAGE;
   writeNarrator->message.io_Message.mn_ReplyPort = writeport;
   writeNarrator->ch_masks = audChanMasks;
   writeNarrator->nm_masks = sizeof(audChanMasks);
   writeNarrator->message.io_Data = (APTR) outputstring;
   writeNarrator->mouths = 0;
   writeNarrator->message.io_Command = CMD_WRITE;

   error = OpenDevice("narrator.device",0,writeNarrator,0);
   if (error) goto done;

   sp = **argp; /* point to string */
   len = sp->length; /* get length */
   cp = sp->text; /* point to text */

   for (cp = sp->text,loc = 1; loc != 0; cp -= loc, len += loc)
     {loc = Translate(cp,len,outputstring,CONVSIZE);
      writeNarrator->message.io_Length = strlen(outputstring);
      error = DoIO(writeNarrator);
      if (error) goto done;}

   done:

   if (writeNarrator)
        FreeMem(writeNarrator,sizeof(struct narrator_rb));
   if (writeport)
        DeletePort(writeport);
   if (TranslatorBase)
        CloseLibrary(TranslatorBase);}
