home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / lib / c / say.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  6.2 KB  |  274 lines

  1. /* <<ACE>> code for SAY command and SAY(n) function.
  2. ** Copyright (C) 1998 David Benn
  3. ** 
  4. ** This program is free software; you can redistribute it and/or
  5. ** modify it under the terms of the GNU General Public License
  6. ** as published by the Free Software Foundation; either version 2
  7. ** of the License, or (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  
  18.    Author: David J Benn
  19.      Date: 6th-8th,10th,11th,14th March 1993,
  20.        10th January 1994,
  21.        20th March 1994,
  22.        2nd,3rd November 1995
  23. */
  24.  
  25. #include <exec/types.h>
  26. #include <exec/exec.h>
  27. #include <devices/narrator.h>
  28.  
  29. #define ERR         1
  30. #define OK             0
  31.  
  32. #define STOP        0
  33. #define GO        1
  34.  
  35. #define T       -1L
  36. #define F        0L
  37.  
  38. #define SYNC        0
  39. #define ASYNC        1
  40. #define DEFSYNC     SYNC
  41.  
  42. #define DEFCHANNEL 10
  43. #define DEFCNTL        0
  44.  
  45. /* I/O structures */
  46. struct MsgPort *WPort=NULL;
  47. struct MsgPort *RPort=NULL;
  48. struct narrator_rb *wmes=NULL;
  49. struct mouth_rb *rmes=NULL;
  50.  
  51. /* audio channel data */
  52. UBYTE audChanMasks[4];
  53.  
  54. /* default speech characteristics -- see devices/narrator.h */
  55. SHORT defvoice[] = {DEFPITCH,DEFMODE,DEFRATE,DEFSEX,DEFFREQ,DEFVOL,
  56.             DEFCHANNEL,DEFSYNC,DEFCNTL};
  57.  
  58. /* mouth width and height */        
  59. LONG mouth_x,mouth_y;
  60.  
  61. /* external functions */
  62. ULONG    stringlength();
  63.  
  64. /* functions */
  65. void cleanup_narrator()
  66. {
  67.  if (wmes)  CloseDevice(wmes);
  68.  if (WPort) DeletePort(WPort);
  69.  if (RPort) DeletePort(RPort);
  70.  if (wmes)  DeleteExtIO(wmes);
  71.  if (rmes)  DeleteExtIO(rmes);
  72. }
  73.  
  74. void nullify_struct_ptrs()
  75. {
  76.  wmes=NULL;
  77.  rmes=NULL;
  78.  WPort=NULL;
  79.  RPort=NULL;
  80. }
  81.  
  82. UWORD aud_chan_masks(n)
  83. LONG n;
  84. {
  85.  /* set the audio channel masks and return the number of masks
  86.     (default is same as for n=10). */
  87.  
  88.  switch(n)
  89.  {
  90.   case 0  : audChanMasks[0]=1;  return(1); break;
  91.   case 1  : audChanMasks[0]=2;  return(1); break;
  92.   case 2  : audChanMasks[0]=4;  return(1); break;
  93.   case 3  : audChanMasks[0]=8;  return(1); break;
  94.   case 4  : audChanMasks[0]=3;  return(1); break;
  95.   case 5  : audChanMasks[0]=5;  return(1); break;
  96.   case 6  : audChanMasks[0]=10; return(1); break;
  97.   case 7  : audChanMasks[0]=12; return(1); break;
  98.   case 8  : audChanMasks[0]=2;  audChanMasks[1]=4;  return(2); break;
  99.   case 9  : audChanMasks[0]=1;  audChanMasks[1]=8;  return(2); break;
  100.   case 10 : audChanMasks[0]=3;  audChanMasks[1]=5;
  101.         audChanMasks[2]=10; audChanMasks[3]=12; return(4); break;  
  102.   case 11 : audChanMasks[0]=1;  audChanMasks[1]=2;
  103.         audChanMasks[2]=4;  audChanMasks[3]=8;  return(4); break;
  104.   default : audChanMasks[0]=3;  audChanMasks[1]=5;
  105.         audChanMasks[2]=10; audChanMasks[3]=12; return(4); break;
  106.  }
  107. }
  108.  
  109. int setup_write_req(speech,voice)
  110. UBYTE *speech;
  111. SHORT *voice;
  112. {
  113. UWORD num_masks;
  114.  
  115.  if ((WPort=(struct MsgPort *)CreatePort(NULL,0L))==NULL) return(ERR);
  116.  
  117.  if ((wmes=(struct narrator_rb *)
  118.     CreateExtIO(WPort,sizeof(struct narrator_rb)))==NULL) return(ERR);
  119.  
  120.  if (voice == NULL) voice=defvoice; /* default speech settings */
  121.  
  122.  wmes->message.io_Command=CMD_WRITE;
  123.  wmes->message.io_Data=(APTR)speech;
  124.  wmes->message.io_Length=stringlength(speech);
  125.  
  126.  num_masks=aud_chan_masks((LONG)voice[6]); /* set audChanMasks */
  127.  wmes->ch_masks=audChanMasks;
  128.  wmes->nm_masks=num_masks;
  129.  
  130.  if (OpenDevice("narrator.device",0L,wmes,0L) != 0) 
  131.  {
  132.     cleanup_narrator();
  133.     nullify_struct_ptrs();
  134.     return(ERR);
  135.  }
  136.  
  137.  wmes->pitch=voice[0];
  138.  wmes->mode=voice[1];
  139.  wmes->rate=voice[2];
  140.  wmes->sex=voice[3];
  141.  wmes->sampfreq=voice[4];
  142.  wmes->volume=voice[5];
  143.  wmes->mouths=voice[7];  /* synchronous/asynchronous speech */
  144. }
  145.  
  146. int setup_read_req()
  147. {
  148.  if ((RPort=(struct MsgPort *)CreatePort(NULL,0L))==NULL) return(ERR);
  149.  
  150.  if ((rmes=(struct mouth_rb *)
  151.     CreateExtIO(RPort,sizeof(struct mouth_rb)))==NULL) return(ERR);
  152.  
  153.  rmes->voice.message.io_Device=wmes->message.io_Device;
  154.  rmes->voice.message.io_Unit=wmes->message.io_Unit;
  155.  rmes->width=0;
  156.  rmes->height=0;
  157.  rmes->voice.message.io_Command=CMD_READ;
  158.  rmes->voice.message.io_Error=0;
  159. }
  160.  
  161. void say_it(voice)
  162. SHORT *voice;
  163. {
  164.  /* synchronous I/O */
  165.  if (voice[7] == SYNC)
  166.  {
  167.   DoIO(wmes);
  168.   cleanup_narrator();
  169.   nullify_struct_ptrs();
  170.  }
  171.  else
  172.   /* asynchronous I/O */
  173.   BeginIO(wmes);
  174. }
  175.  
  176. LONG read_mouth()
  177. {
  178.  /* return mouth width and height if asynchronous I/O active */
  179.  if (rmes == NULL) return(F);
  180.  
  181.  if (rmes->voice.message.io_Error != ND_NoWrite) 
  182.  {
  183.   DoIO(rmes);
  184.   mouth_x=(LONG)rmes->width;
  185.   mouth_y=(LONG)rmes->height;
  186.   return(T);
  187.  }
  188.  else
  189.  {
  190.   cleanup_narrator();
  191.   nullify_struct_ptrs();
  192.   return(F);
  193.  }
  194. }
  195.  
  196. LONG sayfunc(n)
  197. LONG n;
  198. {
  199.  /* return data from active asynchronous speech */
  200.  
  201.  switch(n)
  202.  {
  203.   case 0  : return(read_mouth());  /* T or F */
  204.         break;
  205.  
  206.   case 1  : return(mouth_x);
  207.         break;
  208.  
  209.   case 2  : return(mouth_y);
  210.         break;
  211.   
  212.   default : return(F);
  213.  }
  214. }
  215.  
  216. void cleanup_last_say()
  217. {
  218.  /* wait for async I/O to cease then clean up */
  219.  WaitIO(wmes);
  220.  cleanup_narrator();
  221.  nullify_struct_ptrs();
  222. }
  223.  
  224. int check_for_async_speech(voice)
  225. SHORT *voice;
  226. {
  227.  /* already active asynchronous speech I/O? */
  228.  if (wmes) 
  229.  {
  230.   switch(voice[8])
  231.   {
  232.    case 0 : cleanup_last_say();
  233.         return(GO);
  234.         break;    /* wait for last SAY to finish then do current SAY */
  235.  
  236.    case 1 : AbortIO(wmes);
  237.         cleanup_last_say();
  238.         return(STOP);
  239.         break;    /* interrupt last SAY and don't do current SAY */
  240.  
  241.    case 2 : AbortIO(wmes);
  242.         cleanup_last_say();
  243.         return(GO);
  244.         break;    /* interrupt last SAY, then do current SAY */
  245.  
  246.    default : return(STOP); 
  247.          break;    /* unknown value -> just exit */
  248.   }
  249.  }
  250.  else return(GO);
  251. }
  252.  
  253. void say(voice,str)
  254. SHORT *voice;
  255. UBYTE *str;
  256. {
  257.  if (voice && check_for_async_speech(voice) == STOP) return;
  258.  
  259.  /* setup I/O requests */ 
  260.  if (setup_write_req(str,voice)==ERR) return;
  261.  if (setup_read_req()==ERR) return;
  262.  
  263.  /* carry out I/O */
  264.  say_it(voice);
  265. }
  266.  
  267. void cleanup_async_speech()
  268. {
  269.  /* used as a final check by an ACE program 
  270.     in case there is any active asynchronous
  271.     speech. */ 
  272.  if (wmes) cleanup_last_say();
  273. }
  274.