0

我以 Sphinx4 HelloWorld 为例,制作了自己的语法文件,其中包含“什么是病毒”或“什么是应用软件”之类的句子,简单的 JSGF 内容,我确实分别标记了每个句子,如下所示:

public <0> =     What is number twelve | 
                 What is twelve;
public <1> =     What is the title bar;
public <2> =     What is control | 
                 What is the control key;

没有 n-gram,因为我不完全理解它,我不确定它是否适用于这样一个简单的例子(或者我认为它不适用)。无论如何,代码只是 HelloWorld.java 的复制粘贴,并且识别效果很好,我会说它大约 90% 准确。

现在我把这段代码放到一个 Runnable 中,启动了一个新线程,突然间识别率非常可怕,大约为 10%(十分之一是正确的)。

显然,我直接在应用程序中使用我的麦克风(内置笔记本电脑麦克风)捕捉声音,并且我看到了一些建议,即声音应该根据我使用的字典(这是标准 WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz)重新采样,所以我的第一个问题是:内置的mic.startRecording() 方法可以做到吗?- 这个问题的原因是在主线程上运行的HelloWorld似乎不需要重新采样?

我的第二个问题是我认为多线程会显着降低性能是否正确?如果是的话,有没有办法在不对代码进行大修的情况下解决这个问题?

为了记录,我问是因为我正在使用 SWT 和 Sphinx4 在 Java 中编写一个简单的类似 Jeopardy 的语音识别游戏,主应用程序在主线程上运行,而识别在另一个线程上运行。我目前使用 ZipCity 示例识别听众的方式,但即使它在主线程上运行,它的效果也很糟糕,所以我将跳到更简单的识别方式,这就是我进行 HelloWorld 测试的原因。

编辑:我忘了提到我通常在错误的准确性示例中得到空的结果文本

这是代码,尽管它与示例中的完全相同:

好的工作之一:

public class main_class {

public static void main(String[] args) {
    ConfigurationManager cm;

    cm = new ConfigurationManager(main_class.class.getResource("/jsapi_pr/res/sapi.config.xml"));

    Recognizer recognizer = (Recognizer) cm.lookup("recognizer");
    recognizer.allocate();

    // start the microphone or exit if the program if this is not possible
    Microphone microphone = (Microphone) cm.lookup("microphone");
    if (!microphone.startRecording()) {
        System.out.println("Cannot start microphone.");
        recognizer.deallocate();
        System.exit(1);
    }

    // loop the recognition until the program exits.
    while (true) {

        System.out.println(recognizer.getState());

        Result result = recognizer.recognize();

        if (result != null) {
            String resultText = result.getBestFinalResultNoFiller();
            if(!resultText.isEmpty()) {
                System.out.println("You said: " + resultText + '\n');
            }
        } else {
            System.out.println("I can't hear what you said.\n");
        }
    }
}

工作不好的一个:

public class main_class {

    public static void main(String[] args) {
        runnable_test test = new runnable_test();
        test.begin();
    }
}

public class runnable_test implements Runnable {

    @Override
    public void run() {

        ConfigurationManager cm;

        cm = new ConfigurationManager(main_class.class.getResource("/jsapi_pr/res/sapi.config.xml"));

        Recognizer recognizer = (Recognizer) cm.lookup("recognizer");
        recognizer.allocate();

        // start the microphone or exit if the program if this is not possible
        Microphone microphone = (Microphone) cm.lookup("microphone");
        if (!microphone.startRecording()) {
            System.out.println("Cannot start microphone.");
            recognizer.deallocate();
            System.exit(1);
        }

        // loop the recognition until the program exits.
        while (true) {

            System.out.println(recognizer.getState());

            Result result = recognizer.recognize();

            if (result != null) {
                String resultText = result.getBestFinalResultNoFiller();
                if(!resultText.isEmpty()) {
                    System.out.println("You said: " + resultText + '\n');
                }
            } else {
                 System.out.println("I can't hear what you said.\n");
            }
        }
    }

    public void begin() {
        Thread thread = new Thread(this);
        thread.start();
    }
}

我会尽快尝试发布一些结果,但正如所说的第一个工作正常,第二个通常会触发 resultText.isEmpty(),即使它“识别”某些东西,它通常也是错误的。

EDIT2:我提高了麦克风的性能和音量,而且效果更好,但我仍然无法理解为什么会发生这种情况,因为正如我所说,在主线程中运行时,没有提高麦克风的结果仍然非常好。

主应用程序的性能也好得多,从 12 比 2 提高到 12 比 6。

4

0 回答 0