strange problem with java sound streaming audio
I am using a very basic java sound class to stream audio from Bing Translate for the pronounciation of Chinese characters. It's worked wonderfully for all of the 20 words I've tested except one.
When I try to get the pronunciation for the word 你 (which means you), I get the wrong sound. The strange thing is, when I take the URL that's formed in the code and manually put it into a browser (I'm using the Bing Translate HTTP API), I'm getting the correct sound. So it seems to me the error has to be somewhere in my code. The only place I can think of is the buffer.
The really strange thing is that I'm not getting silence or gibberish. Instead, the sound that's coming back is the way to say "one half" (literally saying "one part of two") in chinese. As I said before, when I put the URL into a browser I get the proper sound for "you."
EDIT: Also, if I put 你们 (which is plural for you and includes the original character) I get the correct sound back.
My code is below. In my pvsm, all I have is creating an instance of this class and then calling speakWord(你)
public开发者_JAVA百科 class WordSpeaker {
private static final String TEST_CONN = "http://api.microsofttranslator.com/v2/Http.svc/" +
"Detect?appId=5768596A4F34453BDAED3138E800D4F7EB5097B9&text=hello";
private static final String TEST_VAL = "en";
private static final String URL_FRONT = "http://api.microsofttranslator.com/v2/Http.svc/Speak?appId=" +
"5768596A4F34453BDAED3138E800D4F7EB5097B9" + "&text=";
private static final String URL_END = "&language=zh-cn";
private AudioInputStream audioStream = null;
private static final int EXTERNAL_BUFFER_SIZE = 128000;
public WordSpeaker() {
}
public void speakWord(String sWord) {
try {
URL bingTranslate = new URL(URL_FRONT + sWord + URL_END);
System.out.println(bingTranslate.toString());
audioStream = AudioSystem.getAudioInputStream(bingTranslate);
} catch (Exception e) {
e.printStackTrace();
}
AudioFormat format = audioStream.getFormat();
SourceDataLine line = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException le) {
System.out.println(le);
} catch (Exception e) {
e.printStackTrace();
}
line.start();
int bytesRead = 0;
byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
while (bytesRead != -1){
try{
bytesRead = audioStream.read(abData,0,abData.length);
} catch (Exception e){
e.printStackTrace();
}
if (bytesRead >=0){
int bytesWritten = line.write(abData,0,bytesRead);
}
}
line.drain();
line.close();
}
private boolean testBing() {
try {
URL test = new URL(TEST_CONN);
BufferedReader testRead = new BufferedReader(new InputStreamReader(test.openStream()));
String inLine = testRead.readLine();
return inLine.substring(inLine.lastIndexOf("\">") + 2, inLine.lastIndexOf("<")).equals(TEST_VAL);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
So I finally, figured this out with some help from the microsoft translate forum. It turns out that since I'm using special characters the encoding does matter. It's just strange how it worked for every single character except this one and this one still was able to produce some intelligible (albeit wrong) output.
The following line needs to be changed from
URL bingTranslate = new URL(URL_FRONT + sWord + URL_END);
to
URL bingTranslate = new URL(URL_FRONT + URLEncoder.encode(sWord, "UTF-8") + URL_END);
I only stumbled upon this because my URLs were getting a malfored URL error from the server when I attempted to play sounds from my jar file while it worked perfectly in the IDE.
精彩评论