/* * * * * * * * * * * * * * * * * * * * * * 
 *  eSpeakPackage.h  -- Header to utilize the eSpeak package within C
 *
 *  eSpeak's author:  Jonathan Duddington
 *  eSpeak source:  http://espeak.sourceforge.net/
 *
 *  author of this adaptation package:  Henry M. Walker
 *
 * * * * * * * * * * * * * * * * * * * * * * /

/* Note: each function name starts with eSpeak to make it 
   easier to understand whether it is a speech function. */

#include "eSpeakPackage.h"
#include <sys/types.h>       /* file of data types needed for many compilers */
#include <unistd.h>          /* needed for fork, getpid procedures */
#include <stdlib.h>          /* needed for exit procedures */
#include <string.h>          /* needed for constructing full path name */
#include <stdio.h>
#include <espeak/speak_lib.h>

/* string to terminate connection to textlines-to-speech program */
char * terminating_string = "eSpeakABBCCCDDDEEEEFFFFdone";

/* directory of textlines-to-speech program */
char * speech_dir = "/home/walker/public_html/bluetooth-with-c/MyroC";

FILE * fpespeak;   /* variable for accessing textlines-to-speech program */

/* set up the local environment to utilize the eSpeak package 
 */
void eSpeakConnect ()
{  pid_t pid;                /* variable to record process id of child */
   
  /* start pulseaudio running for audio output */
   pid = fork();             /* create new process */
   if ( -1 == pid)           /* check for error in spawning child process */
     { perror ("error in fork");  
       exit (1);
     }

   if (0 == pid)             /* check if this is the new child process */
     { /* processing for child */
       printf ("starting pulseaudio\n");

       /* construct full path name of startPulseAudio program */
       char * prog_call = "startPulseAudio";
       char * full_script = malloc (strlen(speech_dir) + strlen(prog_call) + 2);
       full_script[0] = 0;
       strcpy (full_script, speech_dir);
       strcat (full_script, "/");
       strcat (full_script, prog_call);
       /* printf ("full programm call:  %s\n", full_script); */

       execlp (full_script, full_script, (char *)0);
       free (full_script);
       exit(0);
     } 
  else 
     { /* processing for parent */
       waitpid (pid);
       printf ("parent in eSpeakConnect\n"); 
     }

   /* start program textlines-to-speech running
      to speak successive lines of text
      
      textlines-to-speech takes successive lines from standard input
      input continues until "eSpeakABBCCCDDDEEEEFFFFdone" read
   */

   /* construct full path name of textlines-to-speech program */
   char * prog_call = "textlines-to-speech 2> /dev/null";
   char * full_call = malloc (strlen(speech_dir) + strlen(prog_call) + 2);
   full_call[0] = 0; /* start with null string */
   strcpy (full_call, speech_dir);
   strcat (full_call, "/");
   strcat (full_call, prog_call);
   /* printf ("full programm call:  %s\n", full_call); */
   
     /* start executing textlines-to-speech with input through pipe
      child process will handle espeak processing
    */

   fpespeak = popen (full_call, "w");
   if (fpespeak == NULL)
     { perror ("error in starting espeak framework");
       exit (1);
     }

   free (full_call);
}

/* clean up the local environment when the eSpeak package is no longer needed
 */
void eSpeakDisconnect ()
{  pid_t pid;                /* variable to record process id of child */
   

   /* stop textlines-to-speech with sentinel string*/
  fprintf (fpespeak, "%s", "eSpeakABBCCCDDDEEEEFFFFdone");
  fputc ('\n', fpespeak);

  /* close pipe to textlines-to-speech */
  pclose (fpespeak);

   /* terminate pulseaudio daemon */
   pid = fork();             /* create new process */
   if ( -1 == pid)           /* check for error in spawning child process */
     { perror ("error in fork");  
       exit (1);
     }

   if (0 == pid)             /* check if this is the new child process */
     { /* processing for child */
       printf ("stopping pulseaudio\n");
       char * prog_call = "stopPulseAudio";
       char * full_script = malloc (strlen(speech_dir) + strlen(prog_call) + 2);
       full_script[0] = 0;
       strcpy (full_script, speech_dir);
       strcat (full_script, "/");
       strcat (full_script, prog_call);
       /* printf ("full programm call:  %s\n", full_script); */

       execlp (full_script, full_script, (char *)0);
       free (full_script);
       exit(0);
     } 
  else 
     { /* processing for parent */
       waitpid (pid);
       /* printf ("parent in eSpeakDisconnect\n"); */
     }
}

/* create audio for the user
   @param text:  the string to be converted to audible speech
                 any string is valid, as long as it does not begin
                     eSpeakABBCCCDDDEEEEFFFF   
 */
void eSpeakTalk (const char * text)
{ 
  /* send text through pipe to textlines-to-speech program */
  fprintf (fpespeak, "%s", text);
  fputc ('\n', fpespeak);
}

/* set quality of voice to female or male 
   @param gender:  "female" sets woman's voice
                   "male" sets man's voice
   if gender is neither "female" nor "male", voice unchanged
*/
void eSpeakSetGender (const char * gender)
{
  int i;
  int len = strlen(gender)+1;

  /* capitalize input string */
  char genderCaps[len];
  for (i = 0; i < strlen(gender); i++)
    genderCaps[i] = tolower(gender[i]);
  genderCaps [len-1] = 0;
  
  if (strcmp("male", genderCaps) == 0)
    {
      /* tell textlines-to-speech to switch to male voice */
      fprintf (fpespeak, "%s", "eSpeakABBCCCDDDEEEEFFFFmale");
  fputc ('\n', fpespeak);
    }
  else if (strcmp("female", genderCaps) == 0)
    {
      /* tell textlines-to-speech to switch to female voice */
      fprintf (fpespeak, "%s", "eSpeakABBCCCDDDEEEEFFFFfemale");
  fputc ('\n', fpespeak);
    }
}

