1

我在做一个电脑助手,这意味着它应该识别我的声音并给出反馈或做事,反馈应该是计算机生成的声音。我知道 Java 本身有一种方法可以实现这一点,例如使用 javax.speech。这个声音质量不是很好,但它不需要各种库,应该很容易使用。我目前有这个原型代码:

    public static void speech(String text) {
        if(text.trim() == "")
            return;

        String voiceName = "kevin16";

        try {
            SynthesizerModeDesc desc = new SynthesizerModeDesc(null, "general", Locale.US, null, null);
            Synthesizer synth = Central.createSynthesizer(desc);
            synth.allocate();
            synth.resume();
            desc = (SynthesizerModeDesc) synth.getEngineModeDesc();
            Voice[] voices = desc.getVoices();
            Voice voice = null;
            for(Voice entry : voices) {
                if(entry.getName().equals(voiceName)) {
                    voice = entry;
                    break;
                }
            }
            synth.getSynthesizerProperties().setVoice(voice);
            synth.speakPlainText(text, null);
            synth.waitEngineState(Synthesizer.QUEUE_EMPTY);
            synth.deallocate();

        } catch(Exception ex) {
            String message = " missing speech.properties in " + System.getProperty("user.home") + "\n";
            System.out.println("" + ex);
            System.out.println(message);
            ex.printStackTrace();
        }
    }

来自:将文本转换为语音java代码

当我执行代码时会导致错误,那是因为找不到文件 speech.properties,它应该在我的用户目录中。问题是我不知道从哪里得到这个文件,或者这个文件应该是什么,有人可以帮我吗?

另外,如果有人能给我一个好的演讲教程的链接,那就太好了,我在网上搜索过,但很难找到!

4

1 回答 1

4

我只需进行一些更改即可修复您的示例。

首先,我在 try-catch 块的开头添加了这些行:

        System.setProperty("FreeTTSSynthEngineCentral", "com.sun.speech.freetts.jsapi.FreeTTSEngineCentral");
        System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
        Central.registerEngineCentral("com.sun.speech.freetts.jsapi.FreeTTSEngineCentral");

这些行绕过了对那个讨厌的 speech.properties 文件的需求。

其次,声音名称是“ kevin16”,而不是“ kelvin16”。

第三,我把 to 移到了synth.resume()行后synth.getSynthesizerProperties().setVoice(voice)。这是因为如果没有预定义的声音,它就无法开始说话。

第四,你if(text.trim() == "")很糟糕,因为比较字符串使用==不是一个好主意。

这是生成的代码:

public static void speech(String text) {
    if (text == null || text.trim().isEmpty()) return;

    String voiceName = "kevin16";

    try {
        System.setProperty("FreeTTSSynthEngineCentral", "com.sun.speech.freetts.jsapi.FreeTTSEngineCentral");
        System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
        Central.registerEngineCentral("com.sun.speech.freetts.jsapi.FreeTTSEngineCentral");

        SynthesizerModeDesc desc = new SynthesizerModeDesc(null, "general", Locale.US, null, null);

        Synthesizer synth = Central.createSynthesizer(desc);
        synth.allocate();
        desc = (SynthesizerModeDesc) synth.getEngineModeDesc();
        Voice[] voices = desc.getVoices();
        Voice voice = null;
        for (Voice entry : voices) {
            if(entry.getName().equals(voiceName)) {
                voice = entry;
                break;
            }
        }
        synth.getSynthesizerProperties().setVoice(voice);
        synth.resume();
        synth.speakPlainText(text, null);
        synth.waitEngineState(Synthesizer.QUEUE_EMPTY);
        synth.deallocate();

    } catch(Exception ex) {
        String message = " missing speech.properties in " + System.getProperty("user.home") + "\n";
        System.out.println("" + ex);
        System.out.println(message);
        ex.printStackTrace();
    }
}
于 2013-01-25T20:38:25.350 回答