/*
**	$Id: termSpeech.c,v 1.3 92/04/07 20:12:03 olsen Sta Locker: olsen $
**	$Revision: 1.3 $
**	$Date: 92/04/07 20:12:03 $
**
**	Speech support routines
**
**	Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
**		All Rights Reserved
*/

#include "termGlobal.h"

	/* Local symbols. */

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

struct Library			*TranslatorBase;

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

VOID
DeleteSpeech()
{
	if(DidSpeak)
	{
		ULONG Mask = 1 << NarratorRequest -> message . io_Message . mn_ReplyPort -> mp_SigBit;

		if(SetSignal(0,0) & Mask)
		{
			SetSignal(0,Mask);

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

	if(TranslatorBase)
	{
		CloseLibrary(TranslatorBase);

		TranslatorBase = NULL;
	}

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

		DeleteIORequest(NarratorRequest);

		NarratorRequest = NULL;
	}

	if(NarratorPort)
	{
		DeleteMsgPort(NarratorPort);

		NarratorPort = 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)))
			{
					/* Any channel will do. */

				NarratorRequest -> ch_masks		= &AnyChannel[0];
				NarratorRequest -> nm_masks		= 4;

					/* 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(UBYTE *String,...):
	 *
	 *	Translate a string into phonemes and speak it.
	 */

VOID
Say(UBYTE *String,...)
{
	if(TranslatorBase && SpeechConfig . Enabled && English)
	{
		va_list VarArgs;

		if(DidSpeak)
		{
			ULONG Mask = 1 << NarratorRequest -> message . io_Message . mn_ReplyPort -> mp_SigBit;

			if(SetSignal(0,0) & Mask)
			{
				SetSignal(0,Mask);

				WaitIO(NarratorRequest);
			}
			else
			{
				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);

			SetSignal(0,1 << NarratorRequest -> message . io_Message . mn_ReplyPort -> mp_SigBit);

			SendIO(NarratorRequest);

			DidSpeak = TRUE;
		}
	}
}

	/* 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;
	}
}
