Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Sphinx "Answers Itself"

Tags:

java

sphinx4

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.

like image 457
nrubin29 Avatar asked Feb 03 '14 02:02

nrubin29


1 Answers

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");
like image 57
Nikolay Shmyrev Avatar answered Nov 01 '22 16:11

Nikolay Shmyrev