Welcome, Guest. Please login or register.

Author Topic: Artificial Speech "narrator.device" and SASC/C++  (Read 3774 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show all replies
Re: Artificial Speech "narrator.device" and SASC/C++
« on: October 06, 2004, 02:55:35 PM »
Hi

I thought someone else will reply on this, but it seems like you're doomed with me.

Here is my reply for you: both improved (you asked for it), prepared for SAS/C 6.5x and with the answer for your question inside. Try it and find it out!

Cheers

Code: [Select]

/***************************************************/
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/translator.h>
#include <clib/alib_protos.h>
#include <dos/dos.h>
#include <devices/narrator.h>
#include <stdio.h>
#include <string.h>


const static BYTE audChanMasks[]={3,5,10,12};

/***************************************************************/

int get_phoneme( UBYTE *in, SHORT inLen, UBYTE *out, SHORT outLen)
{
  struct Library *TranslatorBase;
  int retVal, error;

  TranslatorBase = (struct Library*)OpenLibrary(&quot;translator.library&quot;,1);
  if( !TranslatorBase ) {
    puts(&quot;Cannot Open Translator.library!&quot;);
    return RETURN_FAIL;
  }
  retVal = RETURN_OK;
  // Translate this string to phonetics
  if(error=Translate(in,inLen,out,outLen) != 0 ) {
    printf(&quot;Cannot Translate %d\n&quot;,error);
    retVal = RETURN_FAIL;
  }

  CloseLibrary(TranslatorBase);

  return retVal;
}

/***************************************************************/

int talk_to_me(UBYTE *speech) {
  struct narrator_rb *wmes;
  struct mouth_rb *rmes;
  struct MsgPort *WPort;
  struct MsgPort *RPort;
  if((WPort=CreatePort(0,0)) == NULL)
    return RETURN_FAIL;
  if((RPort=CreatePort(0,0)) == NULL ) {
    DeletePort( WPort );
    return RETURN_FAIL;
  }

  if((wmes=(struct narrator_rb*)CreateExtIO(WPort,sizeof(struct narrator_rb))) == NULL) {
    DeletePort( RPort );
    DeletePort( WPort );
    return RETURN_FAIL;
  }

  if((rmes=(struct mouth_rb*)CreateExtIO(RPort,sizeof(struct mouth_rb))) == NULL) {
    DeleteExtIO( wmes );
    DeletePort( RPort );
    DeletePort( WPort );
    return RETURN_FAIL;
  }

  wmes->message.io_Command = CMD_WRITE;
  wmes->message.io_Data = (APTR)speech;
  wmes->message.io_Length = strlen(speech);
  wmes->ch_masks = audChanMasks;
  wmes->nm_masks = sizeof(audChanMasks);

  if(OpenDevice(&quot;narrator.device&quot;, 0, wmes, 0) != 0) {
    DeleteExtIO( rmes );
    DeleteExtIO( wmes );
    DeletePort( RPort );
    DeletePort( WPort );
    return RETURN_FAIL;
  }

  wmes->mouths = 0;
  wmes->volume = 64;
  wmes->rate = 20;
  wmes->sex = MALE;
  wmes->pitch = DEFPITCH;

  rmes->voice.message.io_Device = wmes->message.io_Device;
  rmes->voice.io_Unit = wmes->message.io_Unit;
  rmes->width = 0;
  rmes->height = 0;
  rmes->voice.message.io_Command = CMD_READ;
  rmes->voice.io_Error = 0;

  SendIO(wmes);

  {
    unsigned  cnt = 0;
    while(rmes->voice.message.io_Error != ND_NoWrite) {
      DoIO(rmes);
      ++cnt;
    }
    printf( &quot;cnt = %u\n&quot;, cnt );
  }
  WaitPort( WPort );

  CloseDevice( wmes );
  DeleteExtIO( rmes );
  DeleteExtIO( wmes );
  DeletePort( RPort );
  DeletePort( WPort );

  return RETURN_OK;
}

/***************************************************************/

int main(void)
{
  UBYTE in_string[] = &quot;test string&quot;, out_string[300];

  //printf(&quot;Enter a string &quot;);
  //gets(in_string);

  if( get_phoneme(in_string, strlen(in_string),out_string, 300) ) {
    puts(&quot;get_phoneme error!&quot;);
    return RETURN_FAIL;
  }
  printf(&quot;The phoneme translation of %s is %s\n&quot;, in_string, out_string);

  if( talk_to_me(out_string) )
    return RETURN_FAIL;

  return RETURN_OK;
}

 

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show all replies
Re: Artificial Speech "narrator.device" and SASC/C++
« Reply #1 on: October 07, 2004, 12:03:01 PM »
jjans

Oh, so thats wired, as I've tried this and had good expected results, as opposite to your example that didn't work for me.

The reason for this, as I suspect, is the fact that reading 'mouth parameters', DoIO(), is performed only once with failure (I didn't analyse the reason for it), and the whole program exits, before narrator.device even begin to speak, therefore it corrupts memory.
Notice WaitPort() I added to force waiting for narrator.device to finish.

Other changes:
- Cleanup (!!!!!) - Esspecially important in AmigaOS, as this cannot be perfored automatically by OS.
- Usage of other include files that allow to call functions directly from the libraries, without the overhead of so called subs. For that reason I could also change TranslatorBase into local variable.
- Changed function arguments declaration from the old K&R style to the new ANSI style.
- Some functional cleanup (what's the difference between return 0 from main on success end exit( FALSE ) on failure? In my opinion exit() should be avoided at all.
- Used 'const' for really constant array, giving the compiler the possibility to put it in the same hunk with the code itself, not with the data.

Besides this code looks good to me and should work. Try it after rebooting, mayby narrator.device stays corrupted...

Good luck