java sound 流音频的奇怪问题

发布于 2024-11-13 11:41:24 字数 2864 浏览 2 评论 0原文

我正在使用一个非常基本的 java 声音类来从 Bing Translate 流式传输音频以实现汉字的发音。它对于我测试过的所有 20 个单词(除了一个)都非常有效。

当我尝试获取“你”(意思是“你”)这个词的发音时,我得到了错误的声音。奇怪的是,当我获取代码中形成的 URL 并手动将其放入浏览器(我使用的是 Bing Translate HTTP API)时,我得到了正确的声音。所以在我看来,错误一定是在我的代码中的某个地方。我唯一能想到的地方就是缓冲区。

真正奇怪的是我没有得到沉默或胡言乱语。相反,返回的声音是用中文说“一半”(字面意思是“二的一部分”)的方式。正如我之前所说,当我将 URL 输入浏览器时,我会听到“you”的正确发音。

编辑:另外,如果我输入你们(对你来说是复数,包括原始字符),我会得到正确的声音。

我的代码如下。在我的 pvsm 中,我所拥有的就是创建此类的一个实例,然后调用spokeWord(你)

    public 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;
        }
    }

}

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 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;
        }
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长安忆 2024-11-20 11:41:24

所以我最终在微软翻译论坛的帮助下解决了这个问题。事实证明,由于我使用特殊字符,编码确实很重要。奇怪的是,除了这个角色之外,它对每个角色都是如何工作的,而这个角色仍然能够产生一些可理解的(尽管是错误的)输出。

以下行需要更改为

URL bingTranslate = new URL(URL_FRONT + sWord + URL_END);

URL bingTranslate = new URL(URL_FRONT + URLEncoder.encode(sWord, "UTF-8") + URL_END);

只是偶然发现了这一点,因为当我尝试从 jar 文件中播放声音时,我的 URL 从服务器收到错误的 URL 错误,而它在 IDE 中运行良好。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文