home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / newc_dev / talk1.lzh / TALK.C < prev    next >
C/C++ Source or Header  |  1988-06-18  |  11KB  |  534 lines

  1. /*
  2.  * TALK.C  Written by Jon L. Sherling, 6/18/88
  3.  * This program may be distributed anywhere provided that the
  4.  * source including these credits are provided as well.
  5.  */
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <exec/types.h>
  9. #include <exec/memory.h>
  10. /*
  11.  * External functions
  12.  */
  13. extern void *OpenLibrary();
  14. extern int  strlen();
  15. extern long Translate();
  16. extern void fclose();
  17. extern FILE *fopen();
  18. extern char *fgets();
  19. extern void *AllocMem();
  20. extern struct MsgPort *CreatePort();
  21.  
  22. /*
  23.  * local functions
  24.  */
  25. void bye(),
  26.      hello(),
  27.      main();
  28.  
  29. #define BUFLEN 80L            /* Translation buffer size    */    
  30. char phoneme[BUFLEN+1];            /* Translation buffer output    */
  31. char english[BUFLEN+1];            /* Translation buffer input    */
  32. char errormsg[80];
  33.  
  34. struct Library *TranslatorBase = 0L;    /* Translator library base ptr    */
  35. FILE *infile = 0L;
  36.  
  37. #define NUMBUFS 56
  38.  
  39. struct SOUNDBUFFER
  40. {   char *data;
  41.     ULONG  len;
  42.     UWORD  rate;
  43. }  buffer[NUMBUFS];
  44.  
  45. struct IOAudio *ioa = 0L;
  46. struct MsgPort *port;
  47. char *PortName;
  48.  
  49. /*
  50.  * Phoneme file names.  The $ should be interpreted as a /
  51.  */
  52. char names[NUMBUFS][3] =
  53. {
  54.     "$C",
  55.     "$H",
  56.     "AA",
  57.     "AE",
  58.     "AH",
  59.     "AO",
  60.     "AW",
  61.     "AX",
  62.     "AY",
  63.     "B",
  64.     "CH",
  65.     "D",
  66.     "DH",
  67.     "DX",
  68.     "EH",
  69.     "ER",
  70.     "EY",
  71.     "F",
  72.     "G",
  73.     "IH",
  74.     "IL",
  75.     "IM",
  76.     "IN",
  77.     "IX",
  78.     "IY",
  79.     "J",
  80.     "K",
  81.     "L",
  82.     "LX",
  83.     "M",
  84.     "N",
  85.     "NX",
  86.     "OH",
  87.     "OW",
  88.     "OY",
  89.     "P",
  90.     "Q",
  91.     "QX",
  92.     "R",
  93.     "RX",
  94.     "S",
  95.     "SH",
  96.     "T",
  97.     "TH",
  98.     "UH",
  99.     "UL",
  100.     "UM",
  101.     "UN",
  102.     "UW",
  103.     "V",
  104.     "W",
  105.     "WH",
  106.     "Y",
  107.     "Z",
  108.     "ZH",
  109.     "__",
  110. };
  111.  
  112. /*
  113.  * Start of program
  114.  */
  115. void main(argc,argv)
  116. int argc;
  117. char *argv[];
  118. {  register int i;
  119.    for (i = 0; i < NUMBUFS; i++)
  120.        buffer[i].data = 0L;
  121.    if (argc != 2)
  122.       bye("Usage: talk file");
  123.  
  124.    hello(argv[1]);
  125.  
  126.    while (fgets(english,(int)BUFLEN,infile))
  127.       GenPhonemeStr();
  128.    bye("\0");
  129.  
  130. }
  131.  
  132. /*
  133.  * GenPhonemeStr() is used to generate phoneme strings from 
  134.  * english text.  It then calls GenPhoneme to generate 
  135.  * individual phoneme references.
  136.  */
  137. GenPhonemeStr()
  138. {  register long p,pp;
  139.    int len;
  140.    for (pp = 0; p; pp += p)
  141.    {  len = strlen(&english[-pp])-1;
  142.       p = Translate(&english[-pp],(long)len,phoneme,BUFLEN);
  143.       if (p)
  144.          Translate(&english[-pp],(long)-p,phoneme,BUFLEN);
  145.       GenPhoneme(phoneme);
  146.    }
  147. }
  148.  
  149. #define PACK(a,b) ((((int)(a)) << 8) + ((int)(b)))
  150.  
  151. /*
  152.  * GenPhoneme() separates a phoneme string into individual
  153.  * phonemes.
  154.  */
  155. GenPhoneme(s)
  156. char *s;
  157. {  register char *current,*next;
  158.    int value;
  159.    printf("%s\n",s);
  160.    for (current = s,next = &s[1]; *current; current++,next++)
  161.    {   if (isdigit(*current))
  162.        {  /*
  163.            * stress value
  164.        */
  165.        value = *current - '0';
  166.        }
  167.        else
  168.        {  switch(*current)
  169.           {   case ' ':
  170.              value = 10;
  171.                  break;
  172.           case 'B':   case 'F':   case 'G':   case 'J':   case 'K':
  173.           case 'M':   case 'P':   case 'V':   case 'Y':
  174.              value = PACK(*current,0);
  175.              break;
  176.           case 'Z':   case 'T':   case 'S':   case 'D':   case 'W':
  177.           case 'L':   case 'N':   case 'Q':   case 'R':
  178.              if (*next == 'H' || *next == 'X')
  179.              {  value = PACK(*current,*next);
  180.             current++;next++;
  181.              }
  182.              else
  183.              {  value = PACK(*current,0);
  184.              }
  185.              break;
  186.           case 'A':   case 'I':  case 'O':  case 'U':  case 'E':
  187.           case 'C':   case '/':
  188.              value = PACK(*current,*next);
  189.              current++;next++;break;
  190.           case '.':   case '?':  case '-':  case ',':  case '(':
  191.           case ')':
  192.              value = 11;
  193.              break;
  194.           default:
  195.              value = 12;
  196.              break;
  197.           }
  198.        }
  199.        speak(value);
  200.    }
  201. }
  202.  
  203. /*
  204.  *  speak(value) will speak the phoneme associated with the value.
  205.  */
  206. speak(value)
  207. int value;
  208. {  /*
  209.     * 0-9 is stress value
  210.     * 10 is pause
  211.     * 11 is punctuation
  212.     * 12 is error
  213.     * all others are phoneme combinations
  214.     */
  215.     if (value < 10)
  216.        return;
  217.     switch(value)
  218.     {   case PACK('/','C'):
  219.            playbuf(0);
  220.            break;
  221.         case PACK('/','H'):
  222.            playbuf(1);
  223.            break;
  224.         case PACK('A','A'):
  225.            playbuf(2);
  226.            break;
  227.         case PACK('A','E'):
  228.            playbuf(3);
  229.            break;
  230.         case PACK('A','H'):
  231.            playbuf(4);
  232.            break;
  233.         case PACK('A','O'):
  234.            playbuf(5);
  235.            break;
  236.         case PACK('A','W'):
  237.            playbuf(6);
  238.            break;
  239.         case PACK('A','X'):
  240.            playbuf(7);
  241.            break;
  242.         case PACK('A','Y'):
  243.            playbuf(8);
  244.            break;
  245.         case PACK('B',0):
  246.            playbuf(9);
  247.            break;
  248.         case PACK('C','H'):
  249.            playbuf(10);
  250.            break;
  251.         case PACK('D',0):
  252.            playbuf(11);
  253.            break;
  254.         case PACK('D','H'):
  255.            playbuf(12);
  256.            break;
  257.         case PACK('D','X'):
  258.            playbuf(13);
  259.            break;
  260.         case PACK('E','H'):
  261.            playbuf(14);
  262.            break;
  263.         case PACK('E','R'):
  264.            playbuf(15);
  265.            break;
  266.         case PACK('E','Y'):
  267.            playbuf(16);
  268.            break;
  269.         case PACK('F',0):
  270.            playbuf(17);
  271.            break;
  272.         case PACK('G',0):
  273.            playbuf(18);
  274.            break;
  275.         case PACK('I','H'):
  276.            playbuf(19);
  277.            break;
  278.         case PACK('I','L'):
  279.            playbuf(20);
  280.            break;
  281.         case PACK('I','M'):
  282.            playbuf(21);
  283.            break;
  284.         case PACK('I','N'):
  285.            playbuf(22);
  286.            break;
  287.         case PACK('I','X'):
  288.            playbuf(23);
  289.            break;
  290.         case PACK('I','Y'):
  291.            playbuf(24);
  292.            break;
  293.         case PACK('J',0):
  294.            playbuf(25);
  295.            break;
  296.         case PACK('K',0):
  297.            playbuf(26);
  298.            break;
  299.         case PACK('L',0):
  300.            playbuf(27);
  301.            break;
  302.         case PACK('L','X'):
  303.            playbuf(28);
  304.            break;
  305.         case PACK('M',0):
  306.            playbuf(29);
  307.            break;
  308.         case PACK('N',0):
  309.            playbuf(30);
  310.            break;
  311.         case PACK('N','X'):
  312.            playbuf(31);
  313.            break;
  314.         case PACK('O','H'):
  315.            playbuf(32);
  316.            break;
  317.         case PACK('O','W'):
  318.            playbuf(33);
  319.            break;
  320.         case PACK('O','Y'):
  321.            playbuf(34);
  322.            break;
  323.         case PACK('P',0):
  324.            playbuf(35);
  325.            break;
  326.         case PACK('Q',0):
  327.            playbuf(36);
  328.            break;
  329.         case PACK('Q','X'):
  330.            playbuf(37);
  331.            break;
  332.         case PACK('R',0):
  333.            playbuf(38);
  334.            break;
  335.         case PACK('R','X'):
  336.            playbuf(39);
  337.            break;
  338.         case PACK('S',0):
  339.            playbuf(40);
  340.            break;
  341.         case PACK('S','H'):
  342.            playbuf(41);
  343.            break;
  344.         case PACK('T',0):
  345.            playbuf(42);
  346.            break;
  347.         case PACK('T','H'):
  348.            playbuf(43);
  349.            break;
  350.         case PACK('U','H'):
  351.            playbuf(44);
  352.            break;
  353.         case PACK('U','L'):
  354.            playbuf(45);
  355.            break;
  356.         case PACK('U','M'):
  357.            playbuf(46);
  358.            break;
  359.         case PACK('U','N'):
  360.            playbuf(47);
  361.            break;
  362.         case PACK('U','W'):
  363.            playbuf(48);
  364.            break;
  365.         case PACK('V',0):
  366.            playbuf(49);
  367.            break;
  368.         case PACK('W',0):
  369.            playbuf(50);
  370.            break;
  371.         case PACK('W','H'):
  372.            playbuf(51);
  373.            break;
  374.         case PACK('Y',0):
  375.            playbuf(52);
  376.            break;
  377.         case PACK('Z',0):
  378.            playbuf(53);
  379.            break;
  380.         case PACK('Z','H'):
  381.            playbuf(54);
  382.            break;
  383.     default:
  384.        /*
  385.         * Treat this as a pause for now....
  386.         */
  387.            playbuf(55);
  388.            break;
  389.     }
  390. }
  391.  
  392. /*
  393.  * playbuf takes its index and plays the buffer specified.
  394.  */
  395. playbuf(idx)
  396. int idx;
  397. {   PlaySound(buffer[idx].data,buffer[idx].len,1,(int)(3579545/buffer[idx].rate),64);
  398.     WaitIO(ioa);
  399. }
  400.  
  401. /*
  402.  * The initialization routine
  403.  */
  404. void hello(file)
  405. char *file;
  406. {  int i;
  407.    if (!(TranslatorBase = OpenLibrary("translator.library",0L)))
  408.       bye("Error opening translator device");
  409.    if (!(infile = fopen(file,"r")))
  410.    {  sprintf(errormsg,"Could not open \"%s\"",file);
  411.       bye(errormsg);
  412.    }
  413.    for (i = 0; i < NUMBUFS; i++)
  414.        loadsound(names[i],&buffer[i]);
  415.    StartSound();
  416. }
  417.  
  418. /*
  419.  * The cleanup routine
  420.  */
  421. void bye(s)
  422. char *s;
  423. {  int i;
  424.    if (s[0]) printf("%s\n",s);
  425.    if (ioa) StopSound();
  426.    for (i = 0; i < NUMBUFS; i++)
  427.    {   if (buffer[i].data)
  428.           FreeMem(buffer[i].data,buffer[i].len);
  429.    }
  430.    if (TranslatorBase) CloseLibrary(TranslatorBase);
  431.    if (infile) fclose(infile);
  432.    exit(0);
  433. }
  434.  
  435. loadsound(filename,buffer)
  436. char *filename;
  437. struct SOUNDBUFFER *buffer;
  438. {  FILE *fp;
  439.    ULONG len;
  440.    UWORD rec_rate;
  441.  
  442.    if (!(fp = fopen(filename,"r")))
  443.    {  printf("Missing sound file : \"%s\"\n",filename);
  444.       if (!(buffer->data = AllocMem(1000L,MEMF_CHIP|MEMF_CLEAR)))
  445.          bye("Out of memory");
  446.  
  447.       buffer->rate = 10000;
  448.       buffer->len  = 1000;
  449.       return;
  450.    }
  451.  
  452.    if (!fread(&len,sizeof(len),1,fp))
  453.    {  fclose(fp);
  454.       sprintf(errormsg,"Error reading sound file: \"%s\"",filename);
  455.       bye(errormsg);
  456.    }
  457.  
  458.    if (!fread(&rec_rate,sizeof(rec_rate),1,fp))
  459.    {  fclose(fp);
  460.       sprintf(errormsg,"Error reading sound file: \"%s\"",filename);
  461.       bye(errormsg);
  462.    }
  463.  
  464.    if (!(buffer->data = AllocMem(len,MEMF_CHIP|MEMF_CLEAR)))
  465.    {  fclose(fp);
  466.       bye("Out of memory");
  467.    }
  468.  
  469.    buffer->rate = rec_rate;
  470.    buffer->len  = len;
  471.  
  472.    if (!fread(buffer->data,len,1,fp))
  473.    {  fclose(fp);
  474.       sprintf(errormsg,"Error reading sound file: \"%s\"",filename);
  475.       bye(errormsg);
  476.    }
  477.    fclose(fp);
  478. }
  479.  
  480. #include "devices/audio.h"
  481.  
  482. #define LEFT0F     1
  483. #define RIGHT0F    2
  484. #define RIGHT1F    4
  485. #define LEFT1F     8
  486.  
  487. UBYTE allocationMap[] = {LEFT0F,LEFT1F,RIGHT0F,RIGHT1F};
  488.  
  489. StartSound()
  490. {
  491.    if (!(ioa = AllocMem((long)(sizeof(struct IOAudio)),MEMF_PUBLIC|MEMF_CLEAR)))
  492.       bye("Could not allocate IOAudio structure");
  493.    ioa->ioa_Request.io_Message.mn_Node.ln_Pri = 10;
  494.    PortName = "Sound Channel";
  495.    if (!(port = CreatePort(PortName,0L)))
  496.    {  FreeMem(ioa,(long)(sizeof(struct IOAudio)));
  497.       bye("Could not create port");
  498.    }
  499.    ioa->ioa_Request.io_Message.mn_ReplyPort = port;
  500.    ioa->ioa_Data = allocationMap;
  501.    ioa->ioa_Length = sizeof(allocationMap);
  502.    if (OpenDevice(AUDIONAME,0L,ioa,0L))
  503.    {  DeletePort(port);
  504.       FreeMem(ioa,(long)(sizeof(struct IOAudio)));
  505.       bye("Could not open audio device");
  506.    }
  507. }
  508.  
  509. PlaySound(buffer,buflen,repeat,period,volume)
  510. char *buffer;
  511. ULONG buflen;
  512. int repeat,period,volume;
  513. {
  514.     ioa->ioa_Request.io_Flags = ADIOF_PERVOL;
  515.     ioa->ioa_Request.io_Command = CMD_WRITE;
  516.     ioa->ioa_Period = period;
  517.     ioa->ioa_Volume = volume;
  518.     ioa->ioa_Cycles = repeat;
  519.     ioa->ioa_Length = buflen;
  520.     ioa->ioa_Data = (UBYTE *)buffer;
  521.     BeginIO(ioa);
  522. }
  523.  
  524. StopSound()
  525. {
  526.    AbortIO(ioa);
  527.    if (ioa->ioa_Request.io_Device)
  528.       CloseDevice(ioa);
  529.    if (ioa->ioa_Request.io_Message.mn_ReplyPort)
  530.       DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
  531.    if (ioa)
  532.       FreeMem(ioa,(long)(sizeof(struct IOAudio)));
  533. }
  534.