Question

I'm having a problem with the Sphinx voice recognition library for Java. I am using it to get input and handle it. The first time I get input, it works. The second time, it immediately answers itself before I have a chance to talk. After that, it just continues to answer itself. I tried allocating before every input and deallocating after every input but that doesn't seem to work. What can I do?


Code:

This is the method that handles getting input:

public void getInput() {
        if (using) return;

        using = true;

        if (!allocated) {
            JTalk.speak("Please hold.");

            recognizer.allocate();
            allocated = true;
        }

        JTalk.speak("Speak now.");

        Result result = recognizer.recognize();

        if (result != null) {
            String resultText = result.getBestFinalResultNoFiller();

            JDispatcher.getInstance().matchInput(resultText);
        }

        else {
            JTalk.speak("Try again.");
        }

        using = false;
    }

What you need to know:

  • This is being called from a MouseListener for a TrayIcon.
  • speak(String) runs say <text> from the Runtime.
  • matchInput(String) iterates over all registered listeners in an array and tests for matches.

Update 2:

As per Nikolay Shmyrev's answer, I tried allocating the microphone in the constructor and starting, then stopping, the microphone at the appropriate times in getInput().

Here's the SphinxBridge class:

public class SphinxBridge {

    private ConfigurationManager cm;
    private Recognizer recognizer;
    private Microphone microphone;
    private boolean using = false;

    public SphinxBridge() {
        this.cm = new ConfigurationManager(SphinxBridge.class.getResource("input.config.xml"));
        this.recognizer = (Recognizer) cm.lookup("recognizer");
        this.microphone = (Microphone) cm.lookup("microphone");

        recognizer.allocate();
    }

    public void getInput() {
        if (using) return;

        using = true;

        if (!microphone.startRecording()) {
            JTalk.speak("Cannot start microphone.");
            return;
        }

        JTalk.speak("Speak now.");

        Result result = recognizer.recognize();

        if (result != null) {
            String resultText = result.getBestFinalResultNoFiller();

            JDispatcher.getInstance().matchInput(resultText);
        }

        else {
            JTalk.speak("Try again.");
        }

        microphone.stopRecording();

        using = false;
    }
}

However, this still doesn't work. The first, it works fine. However, for all subsequent times, it says Speak now and Try again at the same time.


Solution:

From the code above, I simply added

    microphone.clear();

above the line that starts recording.

Was it helpful?

Solution

You need to understand how microphone works. It just runs a thread and stores all the audio recorded into the buffer. So when you play a reply it's also stored into a buffer for processing.

You need to call microphone.stopRecording() to stop microphone recording while you are playing a TTS reply.

Also you need to call microphone.clear() before startRecording call to clear the data that was previously recorded. Such data still resides in input buffer.

To get microphone component from Configuration you can use something like:

 ConfigurationManager cm;
 ....
 microphone = (Microphone) cm.lookup("microphone");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top