Exergist Ответов: 0

Как использовать spinprocrecocontext и триггерные события с помощью C#


Я очень близок к завершению личного проекта по модификации речевого словаря Windows с помощью C# (SAPI 5.4). Последний бит, над которым я работаю, - это как получить набор телефона SAPI для данного слова. Я нашел способ сделать это с помощью формы C# и устного распознавания, полученного с помощью SpSharedRecoContext Однако я пытаюсь заставить распознавание работать с голосовым файлом (*.wav) в качестве входного сигнала. Я понимаю, что это нужно сделать через интернет. SpInprocRecoContext.

Почти каждый пример из Microsoft, который я нашел относительно распознавания SAPI 5.4 (например вот этот для VB) - это для SpSharedRecoContext, а не SpInprocRecoContext (и я думаю, что видел комментарии, что некоторые из этих примеров не содержат деталей). Кроме того, я нашел несколько тем о переполнении стека (в основном на них ответил Эрик Браун, см. тема 1, тема 2, тема 3) это упоминание об использовании SpInprocRecoContext требует большей настройки, чем SpSharedRecoContext, но Мне еще предстоит найти окончательный ответ на то, как захватывать события распознавания голоса при использовании SpInprocRecoContext в C#.

Как я могу продолжать в том же духе? Любая помощь будет чрезвычайно признательна!!

Что я уже пробовал:

Вот мой код на данный момент:
using SpeechLib;
using System;

namespace SpeechTest
{
    class Program
    {       
        static void Main(string[] args)
        {
            string MyText = "dolphins"; // Text string of interest
            string WaveFile = @"C:\Reco\MYWAVE.wav"; // Path to wav file used for voice recognition

            // Declare important recognition objects
            SpInprocRecognizer Recognizer;
            SpInProcRecoContext RecoContext;
            ISpeechRecoGrammar grammar;
            ISpeechFileStream MyFileStream;
            ISpeechVoice MyVoice;

            // Create recognizer and recognition context
            RecoContext = new SpInProcRecoContext();
            Recognizer = (SpInprocRecognizer)RecoContext.Recognizer;            

            // Set up recognition event handling            
            RecoContext.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler(RecoContext_Recognition);

            // Set up the grammar
            grammar = RecoContext.CreateGrammar(); // Initialize the grammar
            grammar.DictationLoad("", SpeechLoadOption.SLOStatic); // Set up dictation grammar
            grammar.DictationSetState(SpeechRuleState.SGDSActive); // Activate the grammar

            // Set up audio input for SpInProcRecoContext
            SpObjectTokenCategory Category = new SpObjectTokenCategory();
            Category.SetId(SpeechStringConstants.SpeechCategoryAudioIn);
            SpObjectToken AudioToken = new SpObjectToken();
            AudioToken.SetId(Category.Default);
            Recognizer.AudioInput = AudioToken;

            //Category.SetId(SpeechStringConstants.SpeechCategoryRecognizers); // <== generates a runtime error!!!
            //SpObjectToken EngineToken = new SpObjectToken();
            //EngineToken.SetId(Category.Default);
            //Recognizer.Recognizer = EngineToken;

            //Category.SetId(SpeechStringConstants.SpeechCategoryRecoProfiles); // <== generates a runtime error!!!
            //SpObjectToken ProfileToken = new SpObjectToken();
            //ProfileToken.SetId(Category.Default);
            //Recognizer.Profile = ProfileToken;

            // Create an audio file stream from MyText
            MyFileStream = new SpFileStream(); // Create new SpFileStream instance
            TextToWave(MyText, WaveFile); // Call function to create a wav file that voices MyText
            MyFileStream.Open(WaveFile, SpeechStreamFileMode.SSFMOpenForRead, true);

            // Activate the recognizer and input the audio file stream into the recognizer
            RecoContext.State = SpeechRecoContextState.SRCS_Enabled;
            Recognizer.State = SpeechRecognizerState.SRSActive;
            Recognizer.AudioInputStream = MyFileStream; // <== generates a runtime error!!!

            // Output info and cleanup
            Console.WriteLine(MyText + " = " + SAPIPhonemes);
            MyFileStream.Close();
            Console.ReadLine();
        }

        static void TextToWave(string text, string file)
        {
            SpFileStream fileStream = new SpFileStream();
            SpVoice voice = new SpVoice();

            fileStream.Open(file, SpeechStreamFileMode.SSFMCreateForWrite, true);
            voice.AudioOutputStream = fileStream;
            voice.Speak(text);

            fileStream.Close();
        }

        public static string SAPIPhonemes = null;

        public static void RecoContext_Recognition(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)
        {
            // This event is recognized and all the below code works fine when using SpSharedRecoContext

            Console.WriteLine(Result.ToString());
            string SAPIPhonemes = null;
            SpPhoneConverter MyPhoneConverter = new SpPhoneConverter();
            MyPhoneConverter.LanguageId = 1033;

            foreach (ISpeechPhraseElement MyPhrase in Result.PhraseInfo.Elements)
            {
                SAPIPhonemes += " " + MyPhoneConverter.IdToPhone(MyPhrase.Pronunciation);
            }
        }
    }
}

Для справки вот основанный на форме код SpSharedRecoContext, который работает:
using SpeechLib;
using System;
using System.Windows.Forms;

namespace RecoForm
{
    public partial class Form1 : Form
    {
        // Speech Recognition Object
        SpSharedRecoContext listener;

        // Grammar object
        ISpeechRecoGrammar grammar;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // nothing
        }

        public string ps;
        private void button1_Click(object sender, EventArgs e)
        {
            if (btnListen.Text == "Start Listening")
            {
               // textBox1.Clear();
                try
                {

                    listener = new SpSharedRecoContext();
                    listener.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler(listener_Reco);
                    grammar = listener.CreateGrammar(0);
                    grammar.DictationLoad("", SpeechLoadOption.SLOStatic);
                    grammar.DictationSetState(SpeechRuleState.SGDSActive);
                    btnListen.Text = "Stop Listening";
                    if (ps == "1")
                    {
                        listener.Resume();
                        ps = "0";
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else if (btnListen.Text == "Stop Listening")
            {
                listener.Pause();
                btnListen.Text = "Start Listening";
                if (ps == "0")
                {
                    ps = "1";
                }
            }
        }        

        public void listener_Reco(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)
        {
            string heard = Result.PhraseInfo.GetText(0, -1, true);
            textBox1.Text += " " + heard;

            SpPhoneConverter MyPhoneConverter = new SpPhoneConverter();
            MyPhoneConverter.LanguageId = 1033;

            foreach (ISpeechPhraseElement MyPhrase in Result.PhraseInfo.Elements)
                textBox2.Text += " " + MyPhoneConverter.IdToPhone(MyPhrase.Pronunciation);
        }
    }
}

// https://stackoverflow.com/questions/11935533/c-sharp-sapi-5-4-languages

Вот еще один пример (в VB) , который объединяет примеры Microsoft (здесь и здесь) который все еще не работает (см. комментарии в Command1_Click, чтобы найти место, где я столкнулся с ошибкой времени выполнения):
Imports SpeechLib

Public Class Form1
    Const WaveFile = "C:\Reco\MYWAVE.wav"

    Dim WithEvents RC As SpInProcRecoContext
    Dim Recognizer As SpInprocRecognizer
    Dim myGrammar As ISpeechRecoGrammar
    Dim MyFileStream As SpeechLib.SpFileStream
    Dim MyVoice As SpeechLib.SpVoice
    Dim MyText As String

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        On Error GoTo EH

        RC = New SpInProcRecoContext
        Recognizer = RC.Recognizer

        myGrammar = RC.CreateGrammar
        myGrammar.DictationSetState(SpeechRuleState.SGDSActive)
        MyVoice = New SpVoice
        MyVoice.Voice = MyVoice.GetVoices("gender=male").Item(0)

        Dim Category As SpObjectTokenCategory
        Category = New SpObjectTokenCategory
        Category.SetId(SpeechStringConstants.SpeechCategoryAudioIn)

        Dim Token As SpObjectToken
        Token = New SpObjectToken
        Token.SetId(Category.Default)
        Recognizer.AudioInput = Token

        TextBox1.Text = "play the eight of clubs"

EH:
        If Err.Number Then ShowErrMsg()
    End Sub

    Private Sub Command1_Click(sender As Object, e As EventArgs) Handles Command1.Click
        MyFileStream = MakeWAVFileFromText(TextBox1.Text, WaveFile)
        MyFileStream.Open(WaveFile)
        Recognizer.AudioInputStream = MyFileStream ' ==> produces a runtime error!!!
    End Sub

    Private Sub RC_Recognition(ByVal StreamNumber As Long, ByVal StreamPosition As Object, ByVal RecognitionType As SpeechLib.SpeechRecognitionType, ByVal Result As SpeechLib.ISpeechRecoResult)
        On Error GoTo EH

        TextBox2.Text = Result.PhraseInfo.GetText

EH:
        If Err.Number Then ShowErrMsg()
    End Sub

    Private Sub ShowErrMsg()

        ' Declare identifiers:
        Const NL = vbNewLine
        Dim T As String

        T = "Desc: " & Err.Description & NL
        T = T & "Err #: " & Err.Number
        MsgBox(T, vbExclamation, "Run-Time Error")
        End

    End Sub

    Private Function MakeWAVFileFromText(ByVal strText As String, ByVal strFName As String) As SpFileStream

        On Error GoTo EH

        ' Declare identifiers:
        Dim FileStream As SpFileStream
        Dim Voice As SpVoice

        ' Instantiate Voice and FileStream objects:
        Voice = New SpVoice
        FileStream = New SpFileStream

        ' Open specified .wav file, set voice output
        ' to file, and speak synchronously:
        FileStream.Open(strFName, SpeechStreamFileMode.SSFMCreateForWrite, True)
        Voice.AudioOutputStream = FileStream
        Voice.Speak(strText, SpeechVoiceSpeakFlags.SVSFIsXML)

        ' Close file and return reference to FileStream object:
        FileStream.Close()
        MakeWAVFileFromText = FileStream

EH:
        If Err.Number Then ShowErrMsg()
    End Function
End Class

' https://msdn.microsoft.com/en-us/library/ee125184%28v=vs.85%29.aspx
' https://msdn.microsoft.com/en-us/library/ee125344(v=vs.85).aspx

0 Ответов