Java Sphinx "Answers Itself"
Asked Answered
I

1

6

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.

Ivey answered 3/2, 2014 at 2:55 Comment(4)
sharing code may help.Henni
Added. I didn't originally share code because I figured maybe it was a Sphinx bug that was known or someone had a quick solution. I realize now that I should've added it in the first place. Sorry.Ivey
@Ivey can you share your project pleaseDriscoll
@Driscoll I don't think I have this code anymore. If you are having a similar issue I could try my best to help you out.Ivey
N
4

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");
Neoarsphenamine answered 3/2, 2014 at 10:32 Comment(2)
Ok, this is a right direction. You probably also need to call microphone.clear() to clear the data which it recorded. You can do it before microphone.startRecording().Neoarsphenamine
Thank you so much! Calling clear() before I startRecording() solved the problem!Ivey

© 2022 - 2024 — McMap. All rights reserved.