Software Archive
Read-only legacy content
17061 Discussions

Speech Recognition working but Crashes Unity

Andrey_B_
Beginner
1,158 Views

Hi everybody. I'm currently trying to implement voice recognition in Unity. I managed to do so. It recognizes commands from list of commands and performs actions related to the command. However, after approximately 10-30 seconds Unity crashes. I have no idea what causes this problem.

 

I would appreciate any advice!

Here's my code:

using System;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Text;
using System.IO;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Reflection;
using System.Diagnostics;

public class SpeechControl : MonoBehaviour
{
   
    private static List<PXCMAudioSource.DeviceInfo> devices = new List<PXCMAudioSource.DeviceInfo>();
    delegate void OnRecognitionDelegate(PXCMSpeechRecognition data);
     PXCMSpeechRecognition sr;
     PXCMAudioSource source;
     pxcmStatus status;
     PXCMSpeechRecognition.Handler handler;
    private static bool recognized;
    // Use this for initialization
    void Start()
    {
       
        recognized = false;
        PXCMSession session = PXCMSession.CreateInstance();
        status = session.CreateImpl<PXCMSpeechRecognition>(out sr);
        UnityEngine.Debug.Log("STATUS : " + status);
        PXCMSpeechRecognition.ProfileInfo pinfo;
        sr.QueryProfile(0, out pinfo);
        sr.SetProfile(pinfo);

        String[] cmds = new String[4] { "Create", "Save", "Load", "Run" };
        // Build the grammar.
        sr.BuildGrammarFromStringList(1, cmds, null);
        // Set the active grammar.
        sr.SetGrammar(1);

        source = session.CreateAudioSource();
        source.ScanDevices();

        for (int i = 0; ; i++)
        {
            PXCMAudioSource.DeviceInfo dinfo;
            if (source.QueryDeviceInfo(i, out dinfo) < pxcmStatus.PXCM_STATUS_NO_ERROR) break;

            devices.Add(dinfo);
            UnityEngine.Debug.Log("Device : " + dinfo.name);
                     
        }
        source.SetDevice(GetCheckedSource());
        handler = new PXCMSpeechRecognition.Handler();
        handler.onRecognition = OnRecognition;

    }
   

    public static PXCMAudioSource.DeviceInfo GetCheckedSource()
    {
        UnityEngine.Debug.Log("SELECTED : " + devices[0].name);
        return devices[0];
    }


    static void OnRecognition(PXCMSpeechRecognition.RecognitionData data)
    {
    
        UnityEngine.Debug.Log("RECOGNIZED sentence : " + data.scores[0].sentence);
        UnityEngine.Debug.Log("RECOGNIZED tags : " + data.scores[0].tags);

        if (data.scores[0].sentence == "Create")
            UnityEngine.Debug.Log("Call Create Function" );
        if (data.scores[0].sentence == "Save")
            UnityEngine.Debug.Log("Call Save Function" );
        if (data.scores[0].sentence == "Load")
            UnityEngine.Debug.Log("Call Load Function" );
        if (data.scores[0].sentence == "Run")
            UnityEngine.Debug.Log("Call Run Function" );
    }


    // Update is called once per frame
    void Update()
    {
        PXCMSession session = PXCMSession.CreateInstance();
        status = sr.StartRec(source, handler);
    

       
         System.Threading.Thread.Sleep(15);
       

        
        sr.StopRec();
        session.Dispose();
       
    }
    
}

 

0 Kudos
3 Replies
Lance_R_
Beginner
1,158 Views

Andrey, a complete Unity 5 voice command script that should work for you.  Used your implementation of the OnRecognition method in the sample.  Good luck.  Hope that works for you.  I certainly learned a lot here.  Unity is still crashing for me occasionally using this script, but I'm not exactly sure why.  I'm not even certain this script was to blame for my recent crashes.  Maybe drop a session.Dispose() down there too at the end, just in case, to clean up the memory.  Can't be too careful.  The OnApplicationQuit call in the Unity API, that's what you needed mainly, I think.  Of course, things like all those "using" namespaces... what's up with that?  And a private static bool?  Anyway... just copy and paste this whole script and change the name of the class.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class VoiceRec : MonoBehaviour
{

    private PXCMAudioSource source;
    private PXCMSpeechRecognition sr;
    private PXCMSession session;

	private static List<PXCMAudioSource.DeviceInfo> devices = new List<PXCMAudioSource.DeviceInfo>();
	private PXCMAudioSource.DeviceInfo device = new PXCMAudioSource.DeviceInfo();

	[Range(0.2f, 0.8f)]
	public float setVolume = 0.2f;

    void Start()
    {
        session = PXCMSession.CreateInstance();
        audioSourceCheck();
        initSession(session);
    }

    void audioSourceCheck()
    {
        /* Create the AudioSource instance */
        source = session.CreateAudioSource();

        if (source != null)
        {
            source.ScanDevices();

            for (int i = 0; ; i++)
            {
                PXCMAudioSource.DeviceInfo dinfo;
                if (source.QueryDeviceInfo(i, out dinfo) < pxcmStatus.PXCM_STATUS_NO_ERROR) break;

				devices.Add(dinfo);
				UnityEngine.Debug.Log("Device : " + dinfo.name);
            }
        }
    }

    void OnAlert(PXCMSpeechRecognition.AlertData data)
    {
        Debug.Log(data.label);
    }

    static void OnRecognition(PXCMSpeechRecognition.RecognitionData data)
    {

        UnityEngine.Debug.Log("RECOGNIZED sentence : " + data.scores[0].sentence);
        UnityEngine.Debug.Log("RECOGNIZED tags : " + data.scores[0].tags);

        if (data.scores[0].sentence == "Create")
            UnityEngine.Debug.Log("Call Create Function");
        if (data.scores[0].sentence == "Save")
            UnityEngine.Debug.Log("Call Save Function");
        if (data.scores[0].sentence == "Load")
            UnityEngine.Debug.Log("Call Load Function");
        if (data.scores[0].sentence == "Run")
            UnityEngine.Debug.Log("Call Run Function");
    }

    void initSession(PXCMSession session)
    {
        if (source == null)
        {
            Debug.Log("Source was null!  No audio device?");
            return;
        }

        // Set audio volume to 0.2 
        source.SetVolume(setVolume);

        // Set Audio Source 
        Debug.Log("Using device: " + device.name);
        source.SetDevice(device);

        // Set Module 
        PXCMSession.ImplDesc mdesc = new PXCMSession.ImplDesc();
        mdesc.iuid = 0;

        pxcmStatus sts = session.CreateImpl<PXCMSpeechRecognition>(out sr);

        if (sts >= pxcmStatus.PXCM_STATUS_NO_ERROR)
        {
            // Configure 
            PXCMSpeechRecognition.ProfileInfo pinfo;
            // Language
            sr.QueryProfile(0, out pinfo);
            Debug.Log(pinfo.language);
            sr.SetProfile(pinfo);

            // Set Command/Control or Dictation 
            sr.SetDictation();

            // Initialization 
            Debug.Log("Init Started");
            PXCMSpeechRecognition.Handler handler = new PXCMSpeechRecognition.Handler();
            handler.onRecognition = OnRecognition;
            handler.onAlert = OnAlert;

            sts = sr.StartRec(source, handler);

            if (sts >= pxcmStatus.PXCM_STATUS_NO_ERROR)
            {
                Debug.Log("Voice Rec Started");
            }
            else
            {
                Debug.Log("Voice Rec Start Failed");
            }
        }
        else
        {
            Debug.Log("Voice Rec Session Failed");
        }
    }

    void OnApplicationQuit()
    {
        sr.StopRec();
        Debug.Log("Clean up using OnApplicationQuit");
        sr.Dispose();
    }
}

 

0 Kudos
晓轩_王_
Beginner
1,158 Views

the unity support .net 2.0  ,but the libpxcclr.cs.dll is 4.0

how should i do?

why you can invoking PXCMSession session?

0 Kudos
Moore__Xavier
Beginner
1,158 Views

I would add a memory cleanup using OnDestroy() as well for the case of switching scenes. Also it's good practice to do null checks and try/catch around library functions and variables.

 

0 Kudos
Reply