在sphinx4 5prealpha中运行Dialog演示时无法访问麦克风

abc*_*abc 8 java sphinx4 cmusphinx

我正在尝试运行sphinx 4 pre aplha的对话框演示,但它会出错.

我正在创建一个实时语音应用程序.

我使用maven导入了项目,并遵循本指南的堆栈溢出:https://stackoverflow.com/a/25963020/2653162

该错误说明有关16 khz和通道为单声道的问题.很明显它是关于抽样的东西.关于麦克风也是如此.

我看了如何将麦克风设置更改为16 khz和16 bit,但在Windows 7中没有这样的选项

: 仅赢得7中的选项

问题是,HelloWorld和对话框演示在sphinx4 1.06测试版中运行良好,但在我尝试了最新版本后,它会出现以下错误:

Exception in thread "main" java.lang.IllegalStateException: javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian not supported.
    at edu.cmu.sphinx.api.Microphone.<init>(Microphone.java:38)
    at edu.cmu.sphinx.api.SpeechSourceProvider.getMicrophone(SpeechSourceProvider.java:18)
    at edu.cmu.sphinx.api.LiveSpeechRecognizer.<init>(LiveSpeechRecognizer.java:34)
    at edu.cmu.sphinx.demo.dialog.Dialog.main(Dialog.java:145)
Caused by: javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian not supported.
    at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:513)
    at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:121)
    at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:413)
    at edu.cmu.sphinx.api.Microphone.<init>(Microphone.java:36)
    ... 3 more
Run Code Online (Sandbox Code Playgroud)

无法弄清楚如何解决这个问题.

aet*_*ker 5

如果您修改SpeechSourceProvider以返回恒定的麦克风参考,它将不会尝试创建多个麦克风参考,这是问题的根源。

public class SpeechSourceProvider {
    private static final Microphone mic = new Microphone(16000, 16, true, false);

    Microphone getMicrophone() {
        return mic;
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是,您不希望多个线程尝试访问单个资源,但是对于演示而言,识别器会根据需要停止和启动,以便它们不会争夺麦克风。


小智 1

正如 Nickolay 在源锻造论坛(此处)中所解释的那样,当前使用麦克风资源的识别器需要释放麦克风资源,以便另一个识别器能够使用麦克风。在修复 API 的同时,我对 sphinx API 中的某些类进行了以下更改作为临时解决方法。这可能不是最好的解决方案,猜测在提出更好的解决方案之前,这会起作用。


我创建了一个MicrophoneExtention与该类具有相同源代码命名的类Microphone,并添加了以下方法:

    公共无效closeLine(){
        线.close();
    }

同样的LiveSpeechRecognizerExtention类与类的源代码一样LiveSpeechRecognizer,并做了如下修改:

  • 使用我定义的 MicrohphoneExtention 类:
    private final MicroPhoneExtention microphone;
  • 在构造函数内部,
    microphone =new MicrophoneExtention(16000, 16, true, false);
  • 并添加以下方法:
    公共无效closeRecognitionLine(){
        麦克风.closeLine();
    }



最后我编辑了DialogDemo.

    配置配置 = new Configuration();
    配置.setAcousticModelPath(ACOUSTIC_MODEL);
    配置.setDictionaryPath(DICTIONARY_PATH);
    配置.setGrammarPath(GRAMMAR_PATH);
    配置.setUseGrammar(true);

configuration.setGrammarName("dialog"); LiveSpeechRecognizerExtention recognizer = new LiveSpeechRecognizerExtention(configuration); Recognizer.startRecognition(true); while (true) { System.out.println("Choose menu item:"); System.out.println("Example: go to the bank account"); System.out.println("Example: exit the program"); System.out.println("Example: weather forecast"); System.out.println("Example: digits\n"); String utterance = recognizer.getResult().getHypothesis(); if (utterance.startsWith("exit")) break; if (utterance.equals("digits")) { recognizer.stopRecognition(); recognizer.closeRecognitionLine(); configuration.setGrammarName("digits.grxml"); recognizer=new LiveSpeechRecognizerExtention(configuration); recognizeDigits(recognizer); recognizer.closeRecognitionLine(); configuration.setGrammarName("dialog"); recognizer=new LiveSpeechRecognizerExtention(configuration); recognizer.startRecognition(true); } if (utterance.equals("bank account")) { recognizer.stopRecognition(); recognizerBankAccount(Recognizer); recognizer.startRecognition(true); } if (utterance.endsWith("weather forecast")) { recognizer.stopRecognition(); recognizer.closeRecognitionLine(); configuration.setUseGrammar(false); configuration.setLanguageModelPath(LANGUAGE_MODEL); recognizer=new LiveSpeechRecognizerExtention(configuration); recognizeWeather(recognizer); recognizer.closeRecognitionLine(); configuration.setUseGrammar(true); configuration.setGrammarName("dialog"); recognizer=new LiveSpeechRecognizerExtention(configuration); recognizer.startRecognition(true); } } Recognizer.stopRecognition();

Run Code Online (Sandbox Code Playgroud)

显然,DialogDemo需求中的方法签名正在改变......希望这有所帮助......最后一点,我不确定我所做的是否完全合法。如果我做错了什么,请指出我的错误:D