I am building a Sphinx4 Java Server where Unity3D should communicate with. Sending audio data from Unity C# to the Java server works fine. Speech recognition with the received data works fine too. The problem appears when I try to send data from Java back to C#.
My current code: JAVA
package main;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import edu.cmu.sphinx.api.Configuration;
import edu.cmu.sphinx.api.SpeechResult;
import edu.cmu.sphinx.api.StreamSpeechRecognizer;
public class SpeechRecognition {
private static StreamSpeechRecognizer recognizer;
private static Configuration configuration;
public static void main(String[] args) {
configuration = new Configuration();
configuration.setAcousticModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us");
configuration.setDictionaryPath("resource:/edu/cmu/sphinx/models/en-us/cmudict-en-us.dict");
configuration.setLanguageModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us.lm.bin");
try {
recognizer = new StreamSpeechRecognizer(configuration);
ServerSocket serverSocket = new ServerSocket(82);
while (System.in.available() == 0) {
Socket socket = serverSocket.accept();
System.out.println("Client found");
String recognized = RecognizeText(socket.getInputStream());
System.out.println("sending now");
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String json = recognized;
out.print(json);
out.flush();
out.close();
socket.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Quitting...");
serverSocket.close();
}
private static String RecognizeText(InputStream stream) throws Exception {
recognizer.startRecognition(stream);
SpeechResult result;
String resultString="";
while ((result = recognizer.getResult()) != null) {
resultString = result.getHypothesis();
System.out.format("Hypothesis: %s\n", resultString);
}
recognizer.stopRecognition();
return resultString;
}
}
Now my C# code is like this:
void Start () {
dataPath = Application.dataPath;
t = new Thread(Client);
t.Start();
}
private void Client()
{
String input;
TcpClient tcpClient = new TcpClient("localhost", 82);
NetworkStream networkStream = tcpClient.GetStream();
BinaryWriter bw = new BinaryWriter(networkStream);
var filepath = dataPath + "/Resources/audio/test.wav";
FileStream filestream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
BinaryReader filereader = new BinaryReader(filestream);
byte[] bytes = filereader.ReadBytes((Int32)filestream.Length);
bw.Write(bytes);
bw.Flush();
StreamReader streamReader = new StreamReader(networkStream);
input = streamReader.ReadToEnd();
print("Received data: " + input + "\n");
}
The recognition takes around 10 seconds. When te result is given the system freezes. The Println("sending now") (in Java) is not printed. So it freezes before it even reaches it.
The weird thing is: When I only send text from Java to C# or from C# to Java, it works. If I want to send and receive on both ends, it freezes. And I need to send and receive data at the same time
I have found the anwser: The loop is not broken in RecognizeText, placing the return statement within the while loop fixes the issue, as the recognized text will be returned first anyway.