[comp.sys.amiga.tech] narrator problem

phi@goanna.oz (Philip Hingston) (07/11/89)

Can any gurus out there help with the following problem? I cobbled this
piece of code from bits and pieces here and there. Mostly it works fine
but it is not robust. Sometimes it crashes the machine, sometimes after
sending some phonemes to be spoken, they are repeated indefinitely, sometimes
no "shape" messages are recieved, sometimes the narrator decides not to
respond any more, sometimes the machine hangs up. As you can see, a few problems
arise! Any suggestions?
						Thanks	phi.

#define NRB    struct narrator_rb
#define MRB    struct mouth_rb

/* pointers to message ports and io request blocks */
static struct MsgPort *WPort = NULL;
static struct MsgPort *RPort = NULL;
static NRB *wmes = NULL;
static MRB *rmes = NULL;

/* preferences for allocation of audio channels */
static BYTE AudMask[] = {3, 5, 10, 12};

/* set up machinery for talking */
OpenTalk()
{
    WPort = (struct MsgPort *)CreatePort(0, 0);
    if(WPort == NULL) return FALSE;

    RPort = (struct MsgPort *)CreatePort(0, 0);
    if(RPort == NULL) return FALSE;

    wmes = (NRB *)CreateExtIO(WPort, sizeof(NRB));
    if(wmes == NULL) return FALSE;

    rmes = (MRB *)CreateExtIO(WPort, sizeof(MRB));
    if(rmes == NULL) return FALSE;

    wmes->message.io_Command = CMD_WRITE;

    if(OpenDevice("narrator.device", 0, wmes, 0)) return FALSE;

    rmes->voice.message.io_Device = wmes->message.io_Device;
    rmes->voice.message.io_Unit = wmes->message.io_Unit;
    rmes->voice.message.io_Command = CMD_READ;

    return TRUE;
}

/* say something */
void SayIt(phonemes, volume, rate, pitch, sex, freq, mode)
char *phonemes;
short volume, rate, pitch, sex, freq, mode;
{
    wmes->ch_masks = AudMask;
    wmes->nm_masks = sizeof(AudMask);
    wmes->mouths   = 1;

    wmes->volume   = volume;
    wmes->rate	   = rate;
    wmes->pitch    = pitch;
    wmes->sex	   = sex;
    wmes->sampfreq = freq;
    wmes->mode	   = mode;

    wmes->message.io_Data = (APTR)phonemes;
    wmes->message.io_Length = strlen(phonemes);

    /* Here's the crunch */
    SendIO(wmes);
    rmes->voice.message.io_Error = 0;
    DoIO(rmes);
    while(rmes->voice.message.io_Error != ND_NoWrite) {
        SetMouth(rmes->width, rmes->height, rmes->shape);
        DoIO(rmes);
        }
    SetMouth(5, 0, 0);
    GetMsg(WPort);
}

kodiak@amiga.UUCP (Robert R. Burns) (07/13/89)

In article <2210@goanna.oz> phi@goanna.oz (Philip Hingston) writes:
)    /* Here's the crunch */
)    SendIO(wmes);
...
)    while(rmes->voice.message.io_Error != ND_NoWrite) {
...
)    GetMsg(WPort);

You are assuming that when the read responds with ND_NoWrite, that the 
write request will be completed and waiting for you at the WPort.  This
is not necessarily the case -- i.e. there's a race condition here.

Change GetMsg(WPort) to WaitIO(wmes).

- Kodiak
-- 
Bob Burns, {cbmvax,oliveb,well}!amiga!kodiak	   _
	| /_  _|. _ |	   Commodore __		  |_) _ |_  _ )'
	|<(_)(_)|(_\|<	    /\ |  ||| _` /\	  |_)(_\| )(_\ |
	| \ Software	___/..\|\/|||__|/..\___		   Faith