1 2 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ 3 // \\ 4 // Centre for Speech Technology Research \\ 5 // University of Edinburgh, UK \\ 6 // Copyright (c) 1996,1997 \\ 7 // All Rights Reserved. \\ 8 // Permission is hereby granted, free of charge, to use and distribute \\ 9 // this software and its documentation without restriction, including \\ 10 // without limitation the rights to use, copy, modify, merge, publish, \\ 11 // distribute, sublicense, and/or sell copies of this work, and to \\ 12 // permit persons to whom this work is furnished to do so, subject to \\ 13 // the following conditions: \\ 14 // 1. The code must retain the above copyright notice, this list of \\ 15 // conditions and the following disclaimer. \\ 16 // 2. Any modifications must be clearly marked as such. \\ 17 // 3. Original authors' names are not deleted. \\ 18 // 4. The authors' names are not used to endorse or promote products \\ 19 // derived from this software without specific prior written \\ 20 // permission. \\ 21 // THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK \\ 22 // DISCLAIM ALL WARRANTIES With REGARD TO THIS SOFTWARE, INCLUDING \\ 23 // ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT \\ 24 // SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE \\ 25 // FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES \\ 26 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN \\ 27 // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, \\ 28 // ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF \\ 29 // THIS SOFTWARE. \\ 30 // \\ 31 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ 32 // \\ 33 // Author: Richard Caley (rjc@cstr.ed.ac.uk) \\ 34 // -------------------------------------------------------------------- \\ 35 // The thread which actually communicates with festival. \\ 36 // \\ 37 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ 38 39 40 package cstr.festival.client ; 41 42 import java.lang.*; 43 import java.util.*; 44 import java.awt.*; 45 import java.io.*; 46 import java.net.*; 47 48 import cstr.est.*; 49 50 class Job 51 { 52 Integer id; 53 String command; 54 Session session; 55 Job(Integer i, String c, Session s)56 public Job(Integer i, String c, Session s) 57 { 58 id=i; 59 command=c; 60 session=s; 61 } 62 } 63 64 class Festival extends Thread 65 { 66 public static final int FT_SCHEME = 1; 67 public static final int FT_WAVE = 2; 68 69 protected static byte [] endm; 70 protected Socket s; 71 protected String hostname=null; 72 protected InetAddress address = null; 73 protected int port=-1; 74 protected boolean closeOnExit; 75 76 protected PrintWriter out; 77 protected InputStream in; 78 79 protected boolean ok; 80 81 protected JobQueue jobs; 82 83 private byte buffer[]; 84 private int buffered_p; 85 private int buffered_e; 86 87 static { 88 String end="ft_StUfF_key"; 89 endm = new byte[end.length()]; 90 91 for(int i=0;i<endm.length; i++) 92 { 93 endm[i] = (byte)end.charAt(i); 94 } 95 96 } 97 Festival(Socket sock, boolean close)98 protected Festival(Socket sock, boolean close) 99 { 100 s=sock; 101 closeOnExit=close; 102 jobs = new JobQueue(); 103 buffer = new byte[8096]; 104 buffered_p=0; 105 buffered_e=0; 106 ok=true; 107 } 108 Festival(Socket sock)109 public Festival(Socket sock) 110 { 111 this(sock, false); 112 } 113 Festival(InetAddress addr, int p)114 public Festival(InetAddress addr, int p) 115 throws IOException 116 { 117 this(new Socket(addr, p), true); 118 address=addr; 119 port=p; 120 } 121 Festival(String host, int p)122 public Festival(String host, int p) 123 throws IOException, UnknownHostException 124 { 125 this(InetAddress.getByName(host), p); 126 hostname=host; 127 } 128 run()129 public void run() 130 { 131 try { 132 setPriority(getPriority()+1); 133 out = new PrintWriter(s.getOutputStream()); 134 in = s.getInputStream(); 135 while (true) 136 { 137 if (jobs.isEmpty()) 138 { 139 if (ok) 140 suspend(); 141 else 142 break; 143 } 144 else 145 { 146 Job job = (Job)jobs.get(); 147 // System.out.println("sending "+job.command); 148 out.println(job.command); 149 out.flush(); 150 151 String status; 152 153 job.session.notifyRunning(job.id); 154 155 while (true) 156 { 157 status = getStatus(); 158 if (status.startsWith("ER")) 159 { 160 job.session.notifyError(job.id, ""); 161 break; 162 } 163 else if (status.startsWith("LP")) 164 { 165 byte [] res=getResult(); 166 job.session.notifyResult(job.id, FT_SCHEME, res); 167 } 168 else if (status.startsWith("WV")) 169 { 170 byte[] res=getResult(); 171 job.session.notifyResult(job.id, FT_WAVE, res); 172 } 173 else if (status.startsWith("OK")) 174 { 175 break; 176 } 177 else 178 { 179 byte [] res=getResult(); 180 job.session.notifyError(job.id, "unknown type"); 181 } 182 } 183 184 job.session.notifyFinished(job.id); 185 } 186 } 187 } catch (IOException ex) { 188 System.err.println("IO Error '"+ex.getMessage()+"'"); 189 } finally { 190 try { 191 closeSocket(); 192 } catch (IOException ex) { 193 System.err.println("Error closing festival socket '"+ex.getMessage()+"'"); 194 } 195 while (!jobs.isEmpty()) 196 { 197 System.out.println("Left Job '"+((Job)jobs.get()).command+"'"); 198 } 199 } 200 } 201 connect()202 public void connect() 203 { 204 // System.err.println("Connecting"); 205 start(); 206 } 207 disconnect(boolean carefully)208 public void disconnect(boolean carefully) 209 { 210 // System.err.println("Disconnecting"); 211 ok=false; 212 resume(); 213 if (carefully) 214 { 215 try { 216 join(); 217 } catch (InterruptedException ex) { 218 stop(); 219 }; 220 } 221 else 222 stop(); 223 } 224 closeSocket()225 private void closeSocket() throws IOException 226 { 227 if (closeOnExit) 228 { 229 // System.err.println("Closing festival socket"); 230 s.close(); 231 } 232 } 233 newJob(Integer id, String c, Session s)234 public void newJob(Integer id, String c, Session s) 235 { 236 jobs.add(new Job(id,c,s)); 237 resume(); 238 } 239 240 // finally! To the things which talk to festival. 241 readTo(InputStream s, char end)242 private byte[] readTo(InputStream s, char end) throws IOException 243 { 244 if (buffered_e == buffered_p) 245 { 246 buffered_p=0; 247 buffered_e=s.read(buffer, 0, 8096); 248 } 249 250 byte [] res=null; 251 for(int i=buffered_p; i<buffered_e; i++) 252 if (buffer[i] == (byte)end) 253 { 254 res = new byte[i-buffered_p+1]; 255 break; 256 } 257 258 if (res==null) 259 res = new byte[buffered_e-buffered_p]; 260 261 for(int i=0; i< res.length; i++) 262 res[i] = buffer[buffered_p+i]; 263 264 buffered_p = buffered_p+res.length; 265 266 return res; 267 } 268 getLine()269 protected String getLine() throws IOException 270 { 271 StringBuffer line= new StringBuffer(20); 272 273 while (true) 274 { 275 byte [] bit = readTo(in, '\n'); 276 line.append(new String(bit)); 277 278 //System.out.println("got '"+line.toString()+"'"); 279 280 if (line.charAt(line.length()-1) == '\n') 281 break; 282 } 283 284 //System.out.println("result '"+line.toString()+"'"); 285 return line.toString(); 286 } 287 288 getStatus()289 protected String getStatus() throws IOException 290 { 291 String line = getLine(); 292 293 // System.out.println(" Status = '"+line+"'"); 294 return line==null?"EOF":line; 295 } 296 getResult()297 protected byte[] getResult() throws IOException 298 { 299 byte [] res = new byte[0]; 300 301 while (true) 302 { 303 byte [] bit = readTo(in, 'y'); 304 305 int end = bit.length-endm.length; 306 307 if (end < 0) 308 end = bit.length; 309 else 310 { 311 for(int i=0; i< endm.length; i++) 312 if (bit[i+end] != endm[i]) 313 { 314 end = bit.length; 315 break; 316 } 317 } 318 319 byte [] new_res = new byte[res.length+end]; 320 321 for (int i=0; i< res.length; i++) 322 new_res[i] = res[i]; 323 for (int i=0; i< end; i++) 324 new_res[res.length+i] = bit[i]; 325 326 res= new_res; 327 328 if (end < bit.length) 329 break; 330 } 331 332 return res; 333 334 335 /* 336 String line; 337 StringBuffer val = new StringBuffer(); 338 339 if (pending != null) 340 { 341 line=pending; 342 pending=null; 343 } 344 else 345 line = in.readLine(); 346 347 while (line != null) 348 { 349 int endm = line.indexOf("ft_StUfF_key"); 350 351 if (endm >=0) 352 { 353 val.append(line.substring(0, endm)); 354 pending = line.substring(endm+12); 355 break; 356 } 357 else 358 { 359 val.append(line); 360 val.append("\n"); 361 } 362 363 line = in.readLine(); 364 } 365 return val.toString(); 366 */ 367 } 368 } 369