Welcome, Guest. Please login or register.

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

Description:

0 Members and 1 Guest are viewing this topic.

Offline jjansTopic starter

  • Full Member
  • ***
  • Join Date: Aug 2003
  • Posts: 241
    • Show only replies by jjans
Artificial Speech "narrator.device" and SASC/C++
« on: September 26, 2004, 07:49:54 PM »
I am following an old C manual example (Inside the Amiga with C by Thomas Berry published by SAMS) that is dated back to the Lattice days), and Workbench 1.3 in regards to creating a program that makes the Amiga speak using the narrator.device and Translate().

My system is A500, running 3.1 Roms, and I am getting no errors during compile with SASC/C++ 6.xx. I get no crashes when I run the program, and the device seems to open correctly, and the Translate() is returning a converted string to Phonetics OK.

The system is not making any sound however. I was wondering if 2.04 to 3.xx roms handle the speech routines differently than the old 1.3 Roms that I should be aware of?

Is there a modern source example available I could look at to compare with my old  example?

/***************************************************/
#include "stdafx.h"
#include "main_protos.h"

struct Library *TranslatorBase=NULL;
extern struct Library *OpenLibrary();
struct MsgPort *WPort, *RPort;
extern struct IORequest *CreateExtIO();
extern struct Library *OpenLibrary();
struct narrator_rb *wmes;
struct mouth_rb *rmes;

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

int main(void)
{
   UBYTE in_string[80], out_string[300];
   
   printf("Enter a string ");
   gets(in_string);
   
   if(get_phoneme(in_string, strlen(in_string),out_string, 300) == ERR)
   {
      puts("get_phoneme error!");
      exit(FALSE);
   }  
   printf("The phoneme translation of %s is %s\n", in_string, out_string);
   
   if(talk_to_me(out_string) == ERR)
      exit(FALSE);
   
   return 0;
}

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

int get_phoneme(in,inLen,out,outLen)
UBYTE *in,*out;
SHORT inLen,outLen;
{
   int error=0;
   
   TranslatorBase = (struct Library*)OpenLibrary("translator.library",1);
   if(TranslatorBase==NULL)
   {
      puts("Cannot Open Translator.library!");
       return ERR;
   }
   // Translate this string to phonetics
   if(error=Translate(in,inLen,out,outLen) != 0)
   {
      printf("Cannot Translate %d\n",error);
      return ERR;
   }
   
   CloseLibrary(TranslatorBase);
   
   return SUCCESS;
}

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

talk_to_me(speech)
UBYTE *speech;
{
   if((WPort=(struct MsgPort*)CreatePort(0,0)) == NULL)
      return (ERR);
     
   if((RPort=(struct MsgPort*)CreatePort(0,0)) == NULL)
      return (ERR);
     
   if((wmes=(struct narrator_rb*)CreateExtIO(WPort,sizeof(struct
   narrator_rb))) == NULL)
      return (ERR);      
   
   if((rmes=(struct mouth_rb*)CreateExtIO(RPort,sizeof(struct mouth_rb)))
   == NULL)
      return (ERR);
   
   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("narrator.device", 0, wmes, 0) != 0)
      return (ERR);
     
   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);
     
   while(rmes->voice.message.io_Error != ND_NoWrite)
   DoIO(rmes);
         
   return(SUCCESS);      
}
\\"Most Xenonites fly imports. Unfortunately yours is a domestic model. Don\\\'t be surprised if the gears work in reverse\\" - Volhaul\\\'s Revenge: Close Encounters of the Sludge Kind.

GVP A530, VXL 30/32, Supra 500XP, A590, A1000.
 

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show only replies by PiR
Re: Artificial Speech "narrator.device" and SASC/C++
« Reply #1 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 jjansTopic starter

  • Full Member
  • ***
  • Join Date: Aug 2003
  • Posts: 241
    • Show only replies by jjans
Re: Artificial Speech "narrator.device" and SASC/C++
« Reply #2 on: October 07, 2004, 12:11:31 AM »
Thanks for the example!

Initial compile still gives me no speech, but I have to take some time  to study your code to figure out why.

Your Health! :pint:  :pint:  :pint:  :pint:
\\"Most Xenonites fly imports. Unfortunately yours is a domestic model. Don\\\'t be surprised if the gears work in reverse\\" - Volhaul\\\'s Revenge: Close Encounters of the Sludge Kind.

GVP A530, VXL 30/32, Supra 500XP, A590, A1000.
 

Offline DonnyEMU

  • Hero Member
  • *****
  • Join Date: Sep 2002
  • Posts: 650
    • Show only replies by DonnyEMU
    • http://blog.donburnett.com
Re: Artificial Speech "narrator.device" and SASC/C++
« Reply #3 on: October 07, 2004, 07:26:38 AM »
This sounds silly but have you tried using the old AmigaDOS "SAY" command or redirected a text file to SPEAK: to make sure speech is actually make sure it's working??
======================================
Don Burnett Developer
http://blog.donburnett.com
don@donburnett.com
======================================
 

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show only replies by PiR
Re: Artificial Speech "narrator.device" and SASC/C++
« Reply #4 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
 

Offline itix

  • Hero Member
  • *****
  • Join Date: Oct 2002
  • Posts: 2380
    • Show only replies by itix
Re: Artificial Speech "narrator.device" and SASC/C++
« Reply #5 on: October 07, 2004, 01:36:59 PM »
Maybe you don't have narrator.device?
My Amigas: A500, Mac Mini and PowerBook
 

Offline jjansTopic starter

  • Full Member
  • ***
  • Join Date: Aug 2003
  • Posts: 241
    • Show only replies by jjans
Re: Artificial Speech "narrator.device" and SASC/C++
« Reply #6 on: October 07, 2004, 03:57:43 PM »
Well the AmigaDos 'Say' Command is working on all the machines I tested this on. I tried it on my client machine (also OS 3.1), rebooted to OS 1.3 (via SKICK), and even on WINUAE under different OS configs. Really got me stumped now.

I have a feeling I am missing something really simple here. It may be easier to simply call the exec cli command say (which is working) for my purposes, but then this may be more intense on resources will it not?

I have a feeling that time spent with Visual Studio C++ has spoiled me, and I have to re-read some more basics from the old manuals!:-o

Thanks for your input guys. I'll get it yet!!!!
Gotta go to work now    
\\"Most Xenonites fly imports. Unfortunately yours is a domestic model. Don\\\'t be surprised if the gears work in reverse\\" - Volhaul\\\'s Revenge: Close Encounters of the Sludge Kind.

GVP A530, VXL 30/32, Supra 500XP, A590, A1000.