Windows 10 BSOD when using DictationRecognizer in Unity

73 Views Asked by At

I'm facing quite a problem recently. While developing an application for my bachelor degree thesis I was forced to use the DictationRecognizer engine for Speech-To-Text in Unity 2021.3.23f1: as far as my understaing goes, this is a system that uses the Windows 10 built-in Speech-To-Text to return Unity with the data extracted from the microphone.

The problem is everytime I launch the application it crashes my entire PC and I face a Blue Screen Of Death with different error messages: so far I've got UNEXPECTED_STORE_EXCEPTION, IRLQ_NOT_LESS_OR_EQUAL, STORE_DATA_STRUCTURE_CORRUPTION and SYSTEM_SERVICE_EXCEPTION, as well as a couple of different ones regarding memory pages that I can't recall. It seems to me that the Dictation engine crashes in some strange way.

The strangest part is I've access to some similar code developed by one of my collegues and over there everything works perfectly: I can't share it here due to some reserved stuff contained in it, but I can assure you all that it is functionally equivalent, except for the fact that its code doesn't call the DictationRecognizer.Start() in the _startDictationRecognizer method but in the Unity Update function if the recognizer isn't already started. Anyway, here's my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Windows.Speech;

public class SpeechRecognizer : MonoBehaviour
{
    /// <summary>
    /// An event that is invoked everytime the dictation engine successfully detects a phrase.
    /// </summary>
    public UnityEvent<string> OnSpeechRecognized;

    public UnityEvent<DictationCompletionCause> OnDictationCompletion;

    //The dictation recognizer used to detect speech
    private DictationRecognizer _dictationRecognizer;

    private void Start()
    {
        _startDictationEngine();
    }

    private void OnDisable()
    {
        _stopDictationEngine();
    }

    private void OnApplicationQuit()
    {
        _stopDictationEngine();
    }

    private void _startDictationEngine()
    {
        _dictationRecognizer = new DictationRecognizer(ConfidenceLevel.Medium);

        _dictationRecognizer.DictationHypothesis += _dictationRecognizer_DictationHypothesis;
        _dictationRecognizer.DictationResult += _dictationRecognizer_DictationResult;
        _dictationRecognizer.DictationComplete += _dictationRecognizer_DictationComplete;
        _dictationRecognizer.DictationError += _dictationRecognizer_DictationError;

        _dictationRecognizer.Start();
        Debug.Log("Dictation engine is starting...");
    }

    private void _stopDictationEngine()
    {
        if (_dictationRecognizer != null)
        {
            _dictationRecognizer.DictationComplete -= _dictationRecognizer_DictationComplete;
            _dictationRecognizer.DictationError -= _dictationRecognizer_DictationError;
            _dictationRecognizer.DictationHypothesis -= _dictationRecognizer_DictationHypothesis;
            _dictationRecognizer.DictationResult -= _dictationRecognizer_DictationResult;

            if (_dictationRecognizer.Status == SpeechSystemStatus.Running)
            {
                _dictationRecognizer.Stop();
            }

            _dictationRecognizer.Dispose();
            _dictationRecognizer = null;
        }
    }

    private void _dictationRecognizer_DictationResult(string text, ConfidenceLevel confidence)
    {
        Debug.Log($"Speech recognized: {text} [confidence: {confidence}]");
        OnSpeechRecognized?.Invoke(text); 
    }

    private void _dictationRecognizer_DictationHypothesis(string text)
    {
        Debug.Log($"Dictation hypotesis: {text}");
    }

    private void _dictationRecognizer_DictationComplete(DictationCompletionCause cause)
    {
        Debug.Log($"Dictation complete: {cause}");
        OnDictationCompletion?.Invoke(cause);
        switch (cause)
        {
            case DictationCompletionCause.TimeoutExceeded:
            case DictationCompletionCause.PauseLimitExceeded:
            case DictationCompletionCause.Canceled:
            case DictationCompletionCause.Complete:
                // Restart required
                _stopDictationEngine();
                _startDictationEngine();
                break;
            case DictationCompletionCause.UnknownError:
            case DictationCompletionCause.AudioQualityFailure:
            case DictationCompletionCause.MicrophoneUnavailable:
            case DictationCompletionCause.NetworkFailure:
                // Error
                Debug.Log($"Error in the dictation recognition: {cause}");
                _stopDictationEngine();
                break;
        }
    }

    private void _dictationRecognizer_DictationError(string error, int hresult)
    {
        Debug.Log($"Dictation error: {error} [{hresult}]");
    }
}

I've already followed a few guides that detailed how to get rid of the BSOD with no success: it doesn't appear to be a driver issue, expecially because as I said before my collegues' project works perfectly. I nonetheless tried to run sfc /scannow as well as other troubleshooting utilies such as the memory check from Windows.

UPDATE: I changed the code slightly so that _dictationRecognizer.Start() is called in the Update method if the DictationRecognizer is not already running and removed the OnDictationCompletion UnityEvent. This seems to have reduced the frequency of the error a little bit. My hypotesis is that UnityEvents clash with the disposal of the DictationRecognizer and therefore try to access memory locations that have been returned to the operating system, thus causing the crash.

0

There are 0 best solutions below