00001
00016 #define GITKR_SPEECH_FESTIVAL_C
00017
00018 #include "gitkrincludes.h"
00019
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <unistd.h>
00023 #include <string.h>
00024 #include <sys/types.h>
00025 #include <sys/socket.h>
00026 #include <netdb.h>
00027 #include <netinet/in.h>
00028 #include <arpa/inet.h>
00029
00030
00031 static gboolean festival_open(FT_Info *info) {
00032 return(((info->server_fd=festival_socket_open(info->server_host, info->server_port))!=-1));
00033 }
00034
00041 FT_Info *festival_initialize(char *host, int port, char *mode) {
00042 FT_Info *info;
00043
00044 info=calloc(1,sizeof(FT_Info));
00045
00046 info->server_host=((host!=NULL)?host:FESTIVAL_DEFAULT_SERVER_HOST);
00047 info->server_port=((port!=-1 )?port:FESTIVAL_DEFAULT_SERVER_PORT);
00048 info->text_mode =((mode!=NULL)?mode:FESTIVAL_DEFAULT_TEXT_MODE );
00049
00050 if(!festival_open(info)) {
00051 gitk_log("!! can't connect to festival speech service, try starting it");
00052 if(!system("festival >/tmp/festival.log --server &")) {
00053 sleep(1);
00054 if(!festival_open(info)) {
00055 gitk_log("!! can't connect to festival speech service, giving up");
00056 festival_done(info);return(NULL);
00057 }
00058 }
00059 else {
00060 gitk_log("!! can't start festival speech service");
00061 festival_done(info);return(NULL);
00062 }
00063 }
00064
00065 return(info);
00066 }
00067
00071 void festival_done(FT_Info *info) {
00072 if(!info) return;
00073
00074 if(info->server_fd!=-1) close(info->server_fd);
00075
00076 free(info);
00077 }
00078
00093 void festival__say_text(FT_Info *info, const char *text) {
00094 FILE *fd;
00095 const char *p;
00096 char str[1024];
00097 guint sl;
00098
00099 if(!info) return;
00100 if(info->server_fd == -1) return;
00101
00102 gitk_log_intro();
00103
00104 fd=fdopen(dup(info->server_fd),"wb");
00105
00106
00107 fprintf(fd,"(SayText \"");
00108 for(p=text;(p && (*p!='\0'));p++) {
00109
00110 if((*p=='"')||(*p=='\\')) putc('\\',fd);
00111 putc(*p,fd);
00112 }
00113 fputs("\")",fd);
00114
00115 fclose(fd);
00116
00117 fd=fdopen(dup(info->server_fd),"rb");
00118
00119 while(TRUE) {
00120
00121 fgets(str,1024,fd);
00122 sl=strlen(str);
00123 if(sl<3) break;
00124
00125 p=&str[sl-3];
00126 if(!strncmp(p,"WV\n",3)) {
00127 gitk_log("festival response : waveform");
00128 }
00129 else if(!strncmp(p,"LP\n",3)) {
00130 gitk_log("festival response : expression");
00131 fgets(str,1024,fd);
00132 sl=strlen(str);
00133 if(sl>0) {
00134 str[sl-1]='\0';
00135 gitk_log1(" expression : \"%s\"",str);
00136 }
00137 }
00138 else if(!strncmp(p,"ER\n",3)) {
00139 gitk_log("festival response : error");
00140 }
00141 else if(!strncmp(p,"OK\n",3)) {
00142 gitk_log("festival response : okay");
00143 break;
00144 }
00145 else {
00146 gitk_log1("unknown festival response : \"%s\"",str);
00147 }
00148 }
00149 fclose(fd);
00150 gitk_log_outro();
00151 }
00152
00153
00154
00156 static int festival_socket_open(const char *host, int port) {
00157 struct sockaddr_in serv_addr;
00158 struct hostent *serverhost;
00159 int fd;
00160
00161 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00162
00163 if (fd < 0) {
00164 gitk_log("festival_client: can't get socket");
00165 return -1;
00166 }
00167 memset(&serv_addr, 0, sizeof(serv_addr));
00168 if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
00169
00170 serverhost = gethostbyname(host);
00171 if (serverhost == (struct hostent *)0) {
00172 gitk_log("festival_client: gethostbyname failed");
00173 return -1;
00174 }
00175 memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length);
00176 }
00177 serv_addr.sin_family = AF_INET;
00178 serv_addr.sin_port = htons(port);
00179
00180 if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
00181 gitk_log("festival_client: connect to server failed");
00182 return -1;
00183 }
00184
00185 return fd;
00186 }