/* * * DISCLAIMER: * * This program is provided as a service to the programmer * community to demonstrate one or more features of the Amiga * personal computer. These code samples may be freely used * for commercial or noncommercial purposes. * * Commodore Electronics, Ltd ("Commodore") makes no * warranties, either expressed or implied, with respect * to the program described herein, its quality, performance, * merchantability, or fitness for any particular purpose. * This program is provided "as is" and the entire risk * as to its quality and performance is with the user. * Should the program prove defective following its * purchase, the user (and not the creator of the program, * Commodore, their distributors or their retailers) * assumes the entire cost of all necessary damages. In * no event will Commodore be liable for direct, indirect, * incidental or consequential damages resulting from any * defect in the program even if it has been advised of the * possibility of such damages. Some laws do not allow * the exclusion or limitation of implied warranties or * liabilities for incidental or consequential damages, * so the above limitation or exclusion may not apply. * */ /* speech.demo.c ... as its name implies.... */ /* author: Rob Peck, 12/1/85 * * This code may be freely utilized to create programs for the Amiga. */ #include "exec/types.h" #include "exec/exec.h" #include "exec/nodes.h" #include "exec/lists.h" #include "exec/memory.h" #include "exec/interrupts.h" #include "exec/ports.h" #include "exec/libraries.h" #include "exec/io.h" #include "exec/tasks.h" #include "exec/execbase.h" #include "devices/narrator.h" #include "libraries/translator.h" struct MsgPort *readport=0; struct MsgPort *writeport=0; extern struct MsgPort *CreatePort(); extern struct IORequest *CreateExtIO(); struct narrator_rb *writeNarrator=0; struct mouth_rb *readNarrator=0; struct Library *TranslatorBase=0; UBYTE *sampleinput; /* pointer to sample input string */ UBYTE outputstring[500]; /* place to put the translation */ SHORT rtnCode; /* return code from function */ SHORT readError; SHORT writeError; SHORT error; BYTE audChanMasks[4] = { 3,5,10,12 }; /* which channels to use */ #define CANT_OPEN_TRANSLATOR -100 #define CANT_OPEN_NARRATOR -200 #define CREATE_PORT_PROBLEMS -300 #define CREATE_IO_PROBLEMS -400 #define CANT_PERFORM_WRITE -500 #define REVISION 1 extern struct Library *OpenLibrary(); main() { TranslatorBase = OpenLibrary("translator.library",REVISION); if(TranslatorBase == NULL) exit (CANT_OPEN_TRANSLATOR); sampleinput = "this is a test"; /* a test string of 14 characters */ rtnCode = Translate(sampleinput,14,outputstring,500); error = rtnCode + 100; if(rtnCode != 0) goto cleanup0; writeport = CreatePort(0,0); if(writeport == NULL) { error=CREATE_PORT_PROBLEMS; goto cleanup1; } readport = CreatePort(0,0); if(readport == NULL) { error=CREATE_PORT_PROBLEMS; goto cleanup2; } writeNarrator = (struct narrator_rb *)CreateExtIO(writeport, sizeof(struct narrator_rb)); if(writeNarrator == NULL) { error=CREATE_IO_PROBLEMS; goto cleanup3; } readNarrator = (struct mouth_rb *)CreateExtIO(readport, sizeof(struct mouth_rb)); if(readNarrator == NULL) { error=CREATE_IO_PROBLEMS; goto cleanup4; } /* SET UP THE PARAMETERS FOR THE WRITE-MESSAGE TO THE NARRATOR DEVICE */ /* show where to find the channel masks */ writeNarrator->ch_masks = (audChanMasks); /* and tell it how many of them there are */ writeNarrator->nm_masks = sizeof(audChanMasks); /* tell it where to find the string to speak */ writeNarrator->message.io_Data = (APTR)outputstring; /* tell it how many characters the translate function returned */ writeNarrator->message.io_Length = strlen(outputstring); /* if nonzero, asks that mouths be calculated during speech */ writeNarrator->mouths = 1; /* tell it this is a write-command */ writeNarrator->message.io_Command = CMD_WRITE; /* Open the device */ error = OpenDevice("narrator.device", 0, writeNarrator, 0); if(error != 0) goto cleanup4; /* SET UP THE PARAMETERS FOR THE READ-MESSAGE TO THE NARRATOR DEVICE */ /* tell narrator for whose speech a mouth is to be generated */ readNarrator->voice.message.io_Device = writeNarrator->message.io_Device; readNarrator->voice.message.io_Unit = writeNarrator->message.io_Unit; readNarrator->width = 0; readNarrator->height = 0; /* initial mouth parameters */ readNarrator->voice.message.io_Command = CMD_READ; /* initial error value */ readNarrator->voice.message.io_Error = 0; /* Send an asynchronous write request to the device */ writeError = SendIO(writeNarrator); if(writeError != NULL) { error=CANT_PERFORM_WRITE; goto cleanup5; } /* return immediately, run tasks concurrently */ /* keep sending reads until it comes back saying "no write in progress" */ while((readError = readNarrator->voice.message.io_Error) != ND_NoWrite) { DoIO(readNarrator); /* put task to sleep waiting for a different * mouth shape or return of the message block * with the error field showing no write in * process */ DrawMouth(readNarrator->width,readNarrator->height); /* user's own unique routine, not provided here */ } Delay(30); rtnCode = Translate("No it is not",13,outputstring,500); writeNarrator->sex = FEMALE; writeNarrator->pitch = MAXPITCH; /* raise pitch from default value */ writeNarrator->message.io_Data = (APTR)outputstring; writeNarrator->message.io_Length = strlen(outputstring); DoIO(writeNarrator); Delay(30); rtnCode = Translate("Please! I am speaking now!",26,outputstring,500); writeNarrator->sex = MALE; writeNarrator->pitch = DEFPITCH; writeNarrator->message.io_Data = (APTR)outputstring; writeNarrator->message.io_Length = strlen(outputstring); DoIO(writeNarrator); Delay(30); rtnCode = Translate( "Well, you are not very interesting, so I am going home!", 55,outputstring,500); writeNarrator->sex = FEMALE; writeNarrator->pitch = MAXPITCH; writeNarrator->message.io_Data = (APTR)outputstring; writeNarrator->message.io_Length = strlen(outputstring); DoIO(writeNarrator); Delay(30); rtnCode = Translate("Bye Bye",7,outputstring,500); writeNarrator->sex = MALE; writeNarrator->pitch = DEFPITCH; writeNarrator->rate = 7; /* slow him down */ writeNarrator->message.io_Data = (APTR)outputstring; writeNarrator->message.io_Length = strlen(outputstring); DoIO(writeNarrator); cleanup5: if(writeNarrator != 0) CloseDevice(writeNarrator); /* terminate access to the device */ /* now return system memory to the memory allocator */ cleanup4: if(readNarrator != 0) DeleteExtIO(readNarrator,sizeof(struct mouth_rb)); cleanup3: if(writeNarrator != 0) DeleteExtIO(writeNarrator,sizeof(struct narrator_rb)); cleanup2: if(readport != 0) DeletePort(readport); cleanup1: if(writeport != 0) DeletePort(writeport); cleanup0: if(TranslatorBase != 0) CloseLibrary(TranslatorBase); /* terminate access to the library */ if(error != 0) exit(error); } /* end of test */ DrawMouth(w,h) SHORT w,h; { return(0); /* dummy routine */ } int strlen(string) char *string; { int i,length; length = -1; for(i=0; i<256; i++) /* 256 characters max length at this time */ { if(*string++ == '\0') { length = i+1; break; }; } return(length); }