question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

KeywordRecognizer | Python | macOS: stop_recognition_async() does not work

See original GitHub issue

Describe the bug Calling stop_recognition_async() after recognize_once_async() does not appear to work correctly.

  1. It takes about 10 seconds to do whatever it is it does.
  2. The canceled callback do not run as a result of invoking it.
  3. get() on the ResultFuture returned by recognize_once_async() blocks forever.

To Reproduce Steps to reproduce the behavior:

  1. Run the below proof of concept
import azure.cognitiveservices.speech as speechsdk
import time


def speech_recognize_keyword_locally_from_microphone():
    """runs keyword spotting locally, with direct access to the result audio"""

    # Creates an instance of a keyword recognition model. Update this to
    # point to the location of your keyword recognition model.
    model = speechsdk.KeywordRecognitionModel("YourKeywordRecognitionModelFile.table")

    # The phrase your keyword recognition model triggers on.
    keyword = "YourKeyword"

    # Create a local keyword recognizer with the default microphone device for input.
    keyword_recognizer = speechsdk.KeywordRecognizer()

    done = False

    def recognized_cb(evt):
        # Only a keyword phrase is recognized. The result cannot be 'NoMatch'
        # and there is no timeout. The recognizer runs until a keyword phrase
        # is detected or recognition is canceled (by stop_recognition_async()
        # or due to the end of an input file or stream).
        result = evt.result
        if result.reason == speechsdk.ResultReason.RecognizedKeyword:
            print("RECOGNIZED KEYWORD: {}".format(result.text))
        nonlocal done
        done = True

    def canceled_cb(evt):
        result = evt.result
        if result.reason == speechsdk.ResultReason.Canceled:
            print("CANCELED: {}".format(result.cancellation_details.reason))
        nonlocal done
        done = True

    # Connect callbacks to the events fired by the keyword recognizer.
    keyword_recognizer.recognized.connect(recognized_cb)
    keyword_recognizer.canceled.connect(canceled_cb)

    # Start keyword recognition.
    result_future = keyword_recognizer.recognize_once_async(model)
    print(
        'Say something starting with "{}" followed by whatever you want...'.format(
            keyword
        )
    )
    # If active keyword recognition needs to be stopped before results, it can be done with
    #
    stop_future = keyword_recognizer.stop_recognition_async()
    print(f"{time.monotonic()} Stopping...")
    stopped = stop_future.get()
    print(f"{time.monotonic()} Stopped")
    result = result_future.get()
    print(f"{time.monotonic()} Done")

    # Read result audio (incl. the keyword).
    if result.reason == speechsdk.ResultReason.RecognizedKeyword:
        time.sleep(2)  # give some time so the stream is filled
        result_stream = speechsdk.AudioDataStream(result)
        result_stream.detach_input()  # stop any more data from input getting to the stream

        save_future = result_stream.save_to_wav_file_async(
            "AudioFromRecognizedKeyword.wav"
        )
        print("Saving file...")
        saved = save_future.get()
    else:
        result_stream = speechsdk.AudioDataStream(result)
        result_stream.detach_input()


if __name__ == "__main__":
    speech_recognize_keyword_locally_from_microphone()

Expected behavior The canceled callbacks are called, get() on the future returned by recognize_once_async() returns a result indicating cancellation, and get() on the future returned by stop_recognition_async() returns almost immediately.

Version of the Cognitive Services Speech SDK 1.16.0

Platform, Operating System, and Programming Language

  • OS: macOS Big Sur 11.2.3.
  • Hardware: x64
  • Programming language: Python
  • Browser: N/A

Additional context I’m assuming that get() on the future returned by recognize_once_async() should still return after stopping because the documentation says “A future that is fulfilled once recognition has been initialized.” “Initialized” doesn’t seem to require successful recognition, which leads me to infer that it should still return on cancellation.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
oscholzcommented, May 20, 2021

reopening and labeling it as accepted so @CtrlZvi gets notified when we resolve this after we fix this bug.

0reactions
pankoponcommented, Oct 21, 2022

Closed as the Speech SDK 1.24.0 has been released.

Read more comments on GitHub >

github_iconTop Results From Across the Web

why is my speech recognition not working in python
So when I search for that error, I find pyaudio installation always fails on mac What have you tied, and what went wrong...
Read more >
Scripting API: KeywordRecognizer
KeywordRecognizer listens to speech input and attempts to match uttered phrases to a list of registered keywords. There can be many keyword recognizers...
Read more >
Android Keyword Recognizer Issues : r/Unity3D
I have the game working on Windows using keywordrecognizer but I can't build out the scene for android. I think I have to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found