pocketSphinx continuous recognition loop has failed

Home Forums OpenEars pocketSphinx continuous recognition loop has failed

Viewing 4 posts - 1 through 4 (of 4 total)

  • Author
    Posts
  • #1021413
    Matt
    Participant

    I ran into an issue that for the most part is minor but I thought I would bring it up here for discussion because I am looking for an elegant solution.

    The issue is: with PocketsphinxController if you try to start listening while a phone is on a call it will fail and fire back pocketSphinxContinuousSetupDidFail.

    This is understandable as the phone’s audio session is occupied with the call. However after the call ends PocketsphinxController will still return isListening = YES; And trying to start listening after this point fails. The only solution I have found is to nil the controller and create a new one. But I am wondering if there is a more elegant way to detect a problem inside PocketsphinxController.

    Is it possible to reset a PocketsphinxController instance. Or nil it in a safe way. (for example I have found that if I call [pocketsphinxController stopListening] and set it to nil while it is calibrating that this can cause crashes if a new controller is created too soon).

    I am wondering about this broadly. If the controller fails for any reason is it safe to assume you have to throw it out and create a new one?

    #1021421
    Halle Winkler
    Politepix

    No, I think this is just a plain old bug – I probably just need to make sure there are no cases in which this happens after a failure is returned:

    PocketsphinxController will still return isListening = YES

    I actually can’t see how that is possible when reviewing the current code – every failure calls performContinuousFailureStopForIssue: and every call of that method sets isListening to FALSE, but it can get some testing after WWDC to see why the promise isn’t being fulfilled under that circumstance of a call interruption. Broadly, the idea is that you’ll keep the same instance around for your whole session and it will deal with exceptions politely and not have issues toggling between a started and a stopped state even if there has been a failure. I appreciate hearing about cases where this isn’t working yet.

    (for example I have found that if I call [pocketsphinxController stopListening] and set it to nil while it is calibrating that this can cause crashes if a new controller is created too soon).

    Sorry, not quite following this yet – why is it being set to nil while it is calibrating and/or why is it calibrating while it is stopping?

    To set it to nil, first ask it to stop and then when you have a callback in the OpenEarsEventsObserver method pocketsphinxDidStopListening you can set it to nil if you like. Until that callback, it is busy safely winding down its threads and it won’t be safe to stop.

    #1021425
    Matt
    Participant

    Looking at the source, it appears the failure happens inside ContinuousModel.m prepareTestAndOpenAudioDevice method. At this point it fails to open an audio device and posts a PocketsphinxContinuousSetupDidFail notification. performContinuousFailureStopForIssue: never gets called.

    If I work my way back, prepareTestAndOpenAudioDevice is called within listeningLoopWithLanguageModelAtPath:dictionaryAtPath:acousticModelAtPath:languageModelIsJSGF: at which point isListening=YES; prepareTestAndOpenAudioDevice fails and subsequently causes listeningLoopWithLanguageModelAtPath:… to return immediately.

    Hopefully that is of some help in the future, after WWDC.

    Sorry, not quite following this yet – why is it being set to nil while it is calibrating and/or why is it calibrating while it is stopping?

    This is mostly for robustness. For example I have a button that allows toggling pocketsphinxController listening (start/stop listening). Because I ran into the issue above I am trying to nil the controller when the user toggles the button to off/stop. In fact this may be the way to go anyways to clear up resources. This presents the problem where the user can toggle the switch off while the controller is calibrating, etc.

    Am I always guaranteed that pocketsphinxDidStopListening and/or pocketSphinxContinuousSetupDidFail will fire in the event that the controller fails?

    Then I could safely nil the controller if something went wrong and allow the user or system to toggle listening back on (which would start with a fresh controller).

    #1021426
    Halle Winkler
    Politepix

    Because I ran into the issue above I am trying to nil the controller when the user toggles the button to off/stop

    You definitely can’t nil the controller unless you’ve received a callback that listening has stopped – when it works otherwise it’s coincidental, due to lucky timing with the threads being released and your assignment of nil. You can nil it if the user sets it to off and then you get a callback. In the meantime before the callback you have to block further interaction with the on/off button or you will end up with unreachable threads with events in them that can lead to a bad termination, again except in lucky cases.

    The design is to have a single instance that works robustly, not to destroy and create instances over a session, so the effort should just go into the robustness for the single instance. It sounds like you found a case in which the normal chain of events doesn’t fire – I appreciate it and I’ll take a look at the case you found in a bit, thanks.

Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.