home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
datafiles
/
text
/
c_manual
/
devices
/
narratordevice
/
example5.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-27
|
13KB
|
524 lines
/***********************************************************/
/* */
/* Amiga C Encyclopedia (ACE) V3.0 Amiga C Club (ACC) */
/* ------------------------------- ------------------ */
/* */
/* Book: ACM Devices Amiga C Club */
/* Chapter: Narrator Device Tulevagen 22 */
/* File: Example5.c 181 41 LIDINGO */
/* Author: Anders Bjerin SWEDEN */
/* Date: 92-04-26 */
/* Version: 1.00 */
/* */
/* Copyright 1992, Anders Bjerin - Amiga C Club (ACC) */
/* */
/* Registered members may use this program freely in their */
/* own commercial/noncommercial programs/articles. */
/* */
/***********************************************************/
/* This example demonstrates how you can let the Amiga read */
/* small stories. By altering the rate, pitch, mode, sex */
/* and volume parameters it can sound like several persons */
/* are talking. It can also be used to express emotions */
/* and stress important parts of the text. */
/* */
/* This example is using some home made functions which */
/* makes life a little bit easier. If you have to read a */
/* lot of text I recommend you to use special functions */
/* like these. It will then be much easier to write (and */
/* read) the program code. */
/* Declares the datatypes like STRPTR etc: */
#include <exec/types.h>
/* We are using the narrator device: */
#include <devices/narrator.h>
/* Size of the phonetic string buffer. Note that our */
/* "translate_and_say()" function will manage strings */
/* of any size. However, if the string has to be */
/* divided into several parts there will be a short */
/* pause between the parts while the function is */
/* translating the next part. To avoid this you should */
/* not use a too short phonetical string. */
#define PHONETIC_BUFFER_SIZE 200
/* The audio channels: */
/* Values: */
#define LEFT0B 0
#define RIGHT0B 1
#define RIGHT1B 2
#define LEFT1B 3
/* Bit fields: */
#define LEFT0F (1<<LEFT0B)
#define RIGHT0F (1<<RIGHT0B)
#define RIGHT1F (1<<RIGHT1B)
#define LEFT1F (1<<LEFT1B)
/* Pointer to the translator library: */
struct Library *TranslatorBase;
/* Declare a pointer to our reply port: */
struct MsgPort *replymp = NULL;
/* Declare a pointer to our narrator request block: */
struct narrator_rb *narrator_req = NULL;
/* Declare our functions: */
void main();
void clean_up( STRPTR text );
void prepare_to_read( void );
void translate_and_say
(
STRPTR original_string,
UWORD rate,
UWORD pitch,
UWORD mode,
UWORD sex,
UWORD volume
);
BYTE say
(
STRPTR translated_string,
UWORD rate,
UWORD pitch,
UWORD mode,
UWORD sex,
UWORD volume
);
void main()
{
/* Prepare the Amiga to read: (Open the translator */
/* library and narrator device, create and prepare */
/* the message port and request block.) */
prepare_to_read();
/* Tell a short story: */
/* The story teller: */
translate_and_say
(
"Mr. Hacker is sitting in his room reading a new C manual.",
DEFRATE,
DEFPITCH,
NATURALF0,
MALE,
MAXVOL/2
);
/* The story teller: */
translate_and_say
(
"His lovely wife enters.",
DEFRATE,
DEFPITCH,
NATURALF0,
MALE,
MAXVOL/2
);
/* The wife: */
translate_and_say
(
"Are you still reading the C manual?",
DEFRATE,
DEFPITCH + 100,
NATURALF0,
FEMALE,
MAXVOL/2
);
/* Mr. Hacker: */
translate_and_say
(
"Yes, it is a very good C Manual, made by the Amiga C Club.",
DEFRATE - 30,
DEFPITCH - 30,
NATURALF0,
MALE,
MAXVOL/2
);
/* The wife: */
translate_and_say
(
"Have you paid the registration fee?",
DEFRATE,
DEFPITCH + 100,
NATURALF0,
FEMALE,
MAXVOL/2
);
/* Mr. Hacker: */
translate_and_say
(
"No, why should I pay for something when I don't have to.",
DEFRATE - 30,
DEFPITCH - 30,
NATURALF0,
MALE,
MAXVOL/2
);
/* The wife: */
translate_and_say
(
"You horrible person!",
DEFRATE + 40,
DEFPITCH + 100,
NATURALF0,
FEMALE,
MAXVOL
);
/* The wife: */
translate_and_say
(
"If you do not pay for it I don't want to be married to you!",
DEFRATE + 20,
DEFPITCH + 100,
NATURALF0,
FEMALE,
MAXVOL
);
/* Mr. Hacker: */
translate_and_say
(
"But why are you so upset about it? You normally don't like to waste money.",
DEFRATE - 30,
DEFPITCH - 30,
NATURALF0,
MALE,
MAXVOL/2
);
/* The wife: */
translate_and_say
(
"Mr. Anders Bjerin has been working for several years with this C manual.",
DEFRATE,
DEFPITCH + 100,
NATURALF0,
FEMALE,
MAXVOL/2
);
/* The wife: */
translate_and_say
(
"He made it for you, and you don't want to repay him! That's bad manners.",
DEFRATE,
DEFPITCH + 100,
NATURALF0,
FEMALE,
MAXVOL/2
);
/* Mr. Hacker: */
translate_and_say
(
"Yes, you are right. I will pay the registration fee.",
DEFRATE - 30,
DEFPITCH - 30,
NATURALF0,
MALE,
MAXVOL/2
);
/* The story teller: */
translate_and_say
(
"From now on, Mr. and Mrs. Hacker were living happily ever after.",
DEFRATE,
DEFPITCH,
NATURALF0,
MALE,
MAXVOL/2
);
/* Clean up and quit: */
clean_up( "The End!" );
}
/* Close and return everything that has been */
/* opened and allocated before we quit: */
void clean_up( STRPTR text )
{
/* If we have a request block and the "io_Device" field */
/* is not zero, we know that the device has successfully */
/* been opened and must now be closed: */
if( narrator_req && narrator_req->message.io_Device )
CloseDevice( narrator_req );
/* Empty the reply port: */
while( GetMsg( replymp ) )
printf( "Collected a message at the reply port.\n" );
/* Remove the replyport: */
if( replymp )
DeletePort( replymp);
/* Dealocate the narrator request block: */
if( narrator_req )
DeleteExtIO( narrator_req, sizeof( struct narrator_rb ) );
/* Close the translator library: */
if( TranslatorBase )
CloseLibrary( TranslatorBase );
/* Print the last message: */
printf( "%s\n", text );
/* Quit: */
exit( 0 );
}
/* This function will open the translator library and narrator */
/* device, create and initialize the message port and request */
/* block. */
void prepare_to_read( void )
{
/* Store error values here: */
BYTE error;
/* Open the translator library: */
TranslatorBase = (struct Library *)
OpenLibrary( "translator.library", 0 );
/* Have we successfully opened the library? */
if( !TranslatorBase )
clean_up( "Could not open the translator library!" );
/* Get a reply port: (No name, priority 0) */
replymp = (struct MsgPort *)
CreatePort( NULL, 0 );
if( !replymp )
clean_up( "Could not create the reply port!" );
/* Allocate and preinitialize a narrator request block: */
narrator_req = (struct narrator_rb *)
CreateExtIO( replymp, sizeof( struct narrator_rb ) );
if( !narrator_req )
clean_up( "Not enough memory for the narrator request!" );
/* Open the Narrator Device: */
error = OpenDevice( "narrator.device", 0, narrator_req, 0 );
if( error )
{
/* Clear the "io_Device" flag since */
/* we have not opened the device: */
narrator_req->message.io_Device = NULL;
/* Quit: */
clean_up( "Could not open the Narrator Device!" );
}
/* The translator library and narrator device have now */
/* been opened. The Amiga can start to speak. */
}
/* This function will translate a string and will then */
/* automatically call the function "say()" to read */
/* translated text. The nice thing with this function */
/* is that it can handle strings of any size. If the */
/* translated string can not fit into the phonetical */
/* string, the original string is divided into smaller */
/* parts. */
/* */
/* You can alter the sound by chaning the parameters */
/* rate, pitch, mode, sex and volume. */
void translate_and_say
(
STRPTR original_string,
UWORD rate,
UWORD pitch,
UWORD mode,
UWORD sex,
UWORD volume
)
{
/* The phonetic string: */
char phonetic_string[ PHONETIC_BUFFER_SIZE ];
/* If all characters could be translated and stored */
/* in the phonetic string this variable will be set */
/* to zero. On the other hand, if some words could */
/* not be translated since they did not fit in the */
/* phonetic string this variable will contain a */
/* negative value on how many characters actually */
/* were translated. */
int char_translated;
/* This variable contsins the current position */
/* in the string which is translated: */
int current_position;
/* Print the sentence: */
printf( "%s\n", original_string );
/* Start with the first character in the original string: */
current_position = 0;
/* Translate (parts of) our string into phonetics: */
char_translated =
Translate( original_string,
strlen( original_string ),
phonetic_string,
PHONETIC_BUFFER_SIZE );
/* Let the Amiga read the translated text: */
/* (We ignore any error messages.) */
say( phonetic_string, rate, pitch, mode, sex, volume );
/* As long as Translate() does not return zero we stay */
/* in this while loop and continues to translate the */
/* original string into phonetics: */
while( char_translated )
{
/* Increase the current position in the original string: */
/* (Remember that "char_translated" variable is negative, */
/* and we must therefore use the "-=" operator and not */
/* the "+=" to increase the currrent position.[-- = +]) */
current_position -= char_translated;
/* Translate the following part our string into phonetics: */
/* (Note that when we put brackets after a string we we */
/* get the character at the specified position, but since */
/* we want the address of that position we also have to */
/* put the pointer "&" sign infront of the string.) */
char_translated =
Translate( &original_string[ current_position],
strlen( &original_string[ current_position] ),
phonetic_string,
PHONETIC_BUFFER_SIZE );
/* Let the Amiga read the translated text: */
/* (We ignore any error messages.) */
say( phonetic_string, rate, pitch, mode, sex, volume );
}
}
/* This function is given an already translated string */
/* which it will read. */
BYTE say
(
STRPTR translated_string,
UWORD rate,
UWORD pitch,
UWORD mode,
UWORD sex,
UWORD volume
)
{
/* The text should be read with any available channel: */
UBYTE allocation_array[]=
{
LEFT0F,
RIGHT0F,
RIGHT1F,
LEFT1F
};
/* Store error values here: */
BYTE error = 0;
/* Set our requirements: */
/* Set the length of the translated string: */
narrator_req->message.io_Length = strlen( translated_string );
/* Give it a pointer to the translated string: */
narrator_req->message.io_Data = (APTR) translated_string;
/* Send (write) the text to the device: */
narrator_req->message.io_Command = CMD_WRITE;
/* Desired channel combinations: */
narrator_req->ch_masks = allocation_array;
/* Size of the allocation array: */
narrator_req->nm_masks = sizeof( allocation_array );
/* Set rate: */
narrator_req->rate = rate;
/* Set pitch: */
narrator_req->pitch = pitch;
/* Set mode: */
narrator_req->mode = mode;
/* Set sex: */
narrator_req->sex = sex;
/* Set volume: */
narrator_req->volume = volume;
/* Start to read: */
SendIO( narrator_req );
/* Wait for the narrator to finish reading the text: */
error = WaitIO( narrator_req );
/* Were there any errors? */
if( error )
printf( "Error code: %d\n", narrator_req->message.io_Error );
/* Return any error values or zero if everything is OK: */
return( error );
}