/*
**	termSpeech.c
**
**	Speech support routines
**
**	Copyright © 1990-1994 by Olaf `Olsen' Barthel
**		All Rights Reserved
*/

#include "termGlobal.h"

	/* Local symbols. */

STATIC struct MsgPort		*NarratorPort;
STATIC struct narrator_rb	*NarratorRequest;
STATIC UBYTE __far		 SpeechString[512],
				 TranslatedString[512];
STATIC BYTE			 DidSpeak;

	/* DeleteSpeech():
	 *
	 *	Free the data associated with the speech function.
	 */

VOID
DeleteSpeech()
{
	if(DidSpeak)
	{
		if(!CheckIO(NarratorRequest))
			WaitIO(NarratorRequest);
	}

	if(NarratorRequest)
	{
		if(NarratorRequest -> message . io_Device)
			CloseDevice(NarratorRequest);

		DeleteIORequest(NarratorRequest);

		NarratorRequest = NULL;
	}

	if(NarratorPort)
	{
		DeleteMsgPort(NarratorPort);

		NarratorPort = NULL;
	}

	if(TranslatorBase)
	{
		CloseLibrary(TranslatorBase);

		TranslatorBase = NULL;
	}

	DidSpeak = FALSE;
}

	/* CreateSpeech():
	 *
	 *	Open translator.library and narrator.device, perform
	 *	the necessary setups for the speech function.
	 */

BYTE
CreateSpeech()
{
	if(TranslatorBase = OpenLibrary("translator.library",0))
	{
		if(NarratorPort = CreateMsgPort())
		{
			if(NarratorRequest = (struct narrator_rb *)CreateIORequest(NarratorPort,sizeof(struct narrator_rb)))
			{
				STATIC UBYTE AnyChannel[] =
				{
					LEFT0F,
					LEFT1F,
					RIGHT0F,
					RIGHT1F
				};

					/* Any channel will do. */

				NarratorRequest -> ch_masks		= AnyChannel;
				NarratorRequest -> nm_masks		= sizeof(AnyChannel);

					/* This is a write request. */

				NarratorRequest -> message . io_Command	= CMD_WRITE;
				NarratorRequest -> message . io_Data	= (APTR)SpeechString;

				if(!OpenDevice("narrator.device",0,NarratorRequest,0))
				{
					SpeechSetup();

					return(TRUE);
				}
			}
		}
	}

	DeleteSpeech();

	return(FALSE);
}

	/* Say(STRPTR String,...):
	 *
	 *	Translate a string into phonemes and speak it.
	 */

VOID __stdargs
Say(STRPTR String,...)
{
	if(SpeechConfig . Enabled && English)
	{
		if(!TranslatorBase)
			CreateSpeech();

		if(TranslatorBase)
		{
			va_list VarArgs;

			if(DidSpeak)
			{
				if(!CheckIO(NarratorRequest))
					WaitIO(NarratorRequest);
			}

			va_start(VarArgs,String);
			VSPrintf(TranslatedString,String,VarArgs);
			va_end(VarArgs);

			if(!Translate(TranslatedString,strlen(TranslatedString),SpeechString,511))
			{
				NarratorRequest -> message . io_Length = strlen(SpeechString);

				ClrSignal(PORTMASK(NarratorRequest -> message . io_Message . mn_ReplyPort));

				SendIO(NarratorRequest);

				DidSpeak = TRUE;
			}
			else
				DidSpeak = FALSE;
		}
	}
}

	/* SpeechSetup():
	 *
	 *	Transfer the configuration data into the setup.
	 */

VOID
SpeechSetup()
{
	if(NarratorRequest)
	{
		NarratorRequest -> rate		= SpeechConfig . Rate;
		NarratorRequest -> pitch	= SpeechConfig . Pitch;
		NarratorRequest -> sex		= SpeechConfig . Sex;
		NarratorRequest -> volume	= SpeechConfig . Volume;
		NarratorRequest -> sampfreq	= SpeechConfig . Frequency;
	}
}
