lf80
lf80

Reputation: 483

Event Handling InvalidCastException with Microsoft Speech Object Library 5.1 SpeechLib for Text-to-Speech in Unity Windows Desktop Game application

Considering that I can't utilize the System.Speech.dll, System.Speech.Synthesis namespace's SpeechSynthesizer Text-to-Speech, in my Unity Windows desktop 2D game, I need to employ the Microsoft Speech Object Library 5.1 for .NET Standard 2.1, known as SpeechLib. This entails adding the Interop.SpeechLib.dll to my Unity project assets. I'm currently exploring whether I can replicate functionalities such as SpeakStarted, SpeakCompleted, SpeakProgress, and events like VisemeReached, using SpeechLib:

using SpeechLib;
 
public class TTS : MonoBehaviour
{
    SpVoice voice = new SpVoice();

    private void Start()
    {
        TTS();
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            Speak("Hello world!");
        }
    }
    
    private void TTS()
    {
        voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(0);  
        voice.Volume = 100; 
        voice.Rate = 0;  
 
        voice.StartStream += OnStartStream;
        voice.EndStream += OnEndStream;
    }

    void OnDestroy()
    {
        voice.StartStream -= OnStartStream;
        voice.EndStream -= OnEndStream; 
        voice = null;
    }

    void Speak(string text)
    {
        voice.Speak(text, SpeechVoiceSpeakFlags.SVSFlagsAsync | SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak);
    }

However, it never displays debug output in the console upon reaching the event:

    private void OnStartStream(int StreamNumber, object StreamPosition)
    {
        Debug.Log("Speech started");
    }

    private void OnEndStream(int StreamNumber, object StreamPosition)
    {
        Debug.Log("Speech ended");
    }
}

I have also attempted to subscribe and unsubscribe to events using the following syntax:

voice.StartStream += new _ISpeechVoiceEvents_StartStreamEventHandler(OnStartStream);
voice.EndStream += new _ISpeechVoiceEvents_EndStreamEventHandler(OnEndStream);
// ...
voice.StartStream -= new SpeechLib._ISpeechVoiceEvents_StartStreamEventHandler(OnStartStream);
voice.EndStream -= new SpeechLib._ISpeechVoiceEvents_EndStreamEventHandler(OnEndStream);

or alternatively:

voice.StartStream += (int StreamNumber, object StreamPosition) => OnStartStream(StreamNumber, StreamPosition);
voice.EndStream += (int StreamNumber, object StreamPosition) => OnEndStream(StreamNumber, StreamPosition);

error:

InvalidCastException: Specified cast is not valid. (wrapper cominterop) SpeechLib.SpVoiceClass.remove_StartStream(SpeechLib._ISpeechVoiceEvents_StartStreamEventHandler) (wrapper cominterop-invoke) SpeechLib.SpVoiceClass.remove_StartStream(SpeechLib._ISpeechVoiceEvents_StartStreamEventHandler) TTS.OnDestroy () (at Assets/TTS.cs:180)

And there is no output with this:

speechEvents = (_ISpeechVoiceEvents_Event)voice;
speechEvents.StartStream += OnStartStream;
speechEvents.EndStream += OnEndStream;
// ...
if (speechEvents != null)
{
    speechEvents.StartStream -= OnStartStream;
    speechEvents.EndStream -= OnEndStream;
}    

Upvotes: 0

Views: 44

Answers (0)

Related Questions