00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <sys/types.h>
00017 #include <unistd.h>
00018 #include <errno.h>
00019
00020 #include <vos/corelibs/vos/vos.hh>
00021
00022 #include "festtalk.hh"
00023
00024
00025
00026 char* FestTalk::festival_host = "127.0.0.1";
00027 int FestTalk::festival_port = 1314;
00028
00029
00030
00031 void FestTalk::set_server(char *host, int port) {
00032 festival_host = host;
00033 festival_port = port;
00034 }
00035
00036
00037 void FestTalk::festival_server_command(const char *cmd) throw (ServerCommError) {
00038 if(strcmp(cmd, VOS_TALK_NO_VOICE) != 0) {
00039 if( fprintf(socket_fp, "%s\n", cmd) <= 0)
00040 throw ServerCommError("Error writing command.");
00041 fflush(socket_fp);
00042 }
00043 }
00044
00045
00046 string sreplace( const string& s, const string& key, const string& value) {
00047 string tmp(s);
00048 unsigned int k;
00049 while( (k = tmp.find(key)) != tmp.npos )
00050 tmp = tmp.replace( k, key.length(), value);
00051 return tmp;
00052 }
00053 void FestTalk::festival_server_saytext(const string& text) throw (ServerCommError) {
00054
00055 string::size_type f = 0;
00056 string::size_type pos = 0;
00057
00058
00059
00060
00061 if(phrase_delim != NULL) {
00062 while( (f = text.find_first_of(phrase_delim, pos)) != text.npos) {
00063 if( fprintf(socket_fp, "(SayText \"%s\")", text.substr(pos, f).c_str()) <= 0)
00064 throw ServerCommError("Error writing command.");
00065 pos = f;
00066 }
00067 } else {
00068 if( fprintf(socket_fp, "(SayText \"%s\")\n", text.c_str()) <= 0 )
00069 throw ServerCommError("Error writing command.");
00070 }
00071 fflush(socket_fp);
00072 }
00073
00074
00075 void FestTalk::open_server(char *host, int port) throw (ServerCommError) {
00076 struct sockaddr_in address;
00077 LOG("Festival Talkative", 3, "Opening connection to Festival server at " << host << ":" << port);
00078 if( (socket_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
00079 LOG("Festival Talkative", 0, "Error creating socket. " << strerror(errno));
00080 throw ServerCommError(string("Error opening server: ") + strerror(errno));
00081 return;
00082 }
00083 struct hostent* he;
00084 if(!(he = gethostbyname(host))) {
00085 LOG("Festival Talkative", 0, "Error: Invalid address. " << host);
00086 throw ServerCommError("Invalid address.");
00087 return;
00088 }
00089 memset(&address, 0, sizeof(address));
00090 address.sin_port=htons(port);
00091 address.sin_family=AF_INET;
00092 address.sin_addr=*((struct in_addr *)he->h_addr);
00093 if( connect(socket_fd, (struct sockaddr *)&address, sizeof(address)) == -1) {
00094 LOG("Festival Talkative", 0, "Error connecting to server " << host << ":" << port << ". " << strerror(errno));
00095 throw ServerCommError(string("Error connecting to server: ") + strerror(errno));
00096 return;
00097 }
00098
00099 if(! (socket_fp = fdopen(socket_fd, "r+")) ) {
00100 LOG("Festival Talkative", 0, "Error opening stream from fd.");
00101 throw ServerCommError("Error opening stream fp from socket file descriptor!!");
00102
00103 return;
00104 }
00105 }
00106
00107
00108
00109 void FestTalk::close_server() {
00110 fclose(socket_fp);
00111 if ( shutdown(socket_fd, 2) < 0 ) {
00112 LOG("Festival Talkative", 0, "Warning: Error closing socket. " << strerror(errno));
00113 }
00114 }
00115
00116
00117
00118 FestTalk::FestTalk(MetaObject *super) throw (ServerCommError)
00119 : LocalTalkative(super), Talkative(super), MetaObject(super) {
00120 phrase_delim = NULL;
00121 try {
00122 open_server(festival_host, festival_port);
00123 } catch (ServerCommError e) {
00124 throw e;
00125 }
00126
00127 }
00128
00129
00130 FestTalk::~FestTalk() {
00131 close_server();
00132
00133 }
00134
00135
00136
00137 void FestTalk::do_say(TalkMessage& m) throw (ServerCommError) {
00138 LOG("Festival Talkative", 3, "Speaking message...");
00139 try {
00140 festival_server_command(m.sender.get_voice().c_str());
00141 festival_server_saytext(m.text);
00142 } catch (ServerCommError e) {
00143 throw e;
00144 }
00145 LOG("Festival Talkative", 3, "Done speaking.");
00146 }
00147
00148 void FestTalk::registerExtenders() {
00149 LocalSite::addLocalObjectExtension(typeid(FestTalk).name(), new_FestTalk);
00150 RemoteSite::addRemoteObjectExtension(typeid(FestTalk).name(), new_FestTalk);
00151 }
00152
00153
00154 MetaObject* FestTalk::new_FestTalk(MetaObject* superobject, const string& type) {
00155 return new FestTalk(superobject);
00156 }
00157
00158