So I have a windows service with speech recognition implemented using the system.speech recognition engine. My speech recognition code runs fine when I start the service but no events for speech recognized fires. The strange thing is, if I run the exact same code, but in a console or WPF app instead, the event firing for speech recognition works just fine.
I have already attached a debugger to my service process to check what was going on behind the scenes. It seems as though the speech recognition engine properly loads the grammars, sets its mode to listen continuously, and properly sets up the speech recognized event. No exceptions are thrown so I am not too sure what is wrong here. Any ideas?
问题:
回答1:
Are you using the microphone or processing a WAV file? I'm not sure how the audio plumbing will work in a service if you are trying to use the default audio device. If you are trying to convert from audio files or a stream, make sure you are using an InProc recognizer.
If you are creating a server app, you probably should consider using the Microsoft.Speech API and the server recongizers. See What is the difference between System.Speech.Recognition and Microsoft.Speech.Recognition? and the Microsoft Speech Platform SDK - http://www.microsoft.com/en-us/download/details.aspx?id=27226
If you are trying to do continuous recognition without your app in the foreground, I believe the shared recognizer may be able to support your need. The Microsoft desktop recognizer that ships in Windows 7 and Vista can work in two modes: inproc or shared. Shared recognizers are useful on the desktop where voice commands are used to control any open applications. In System.Speech you can use SpeechRecognizer to access the shared desktop recognizer or SpeechRecognitionEngine to have a dedicated inproc recognizer for your application. You might be able to use the shared recognizer to provide continuous recognition to your application even when your app is not in the foreground.
There is a very good article that was published a few years ago at http://msdn.microsoft.com/en-us/magazine/cc163663.aspx. It is probably the best introductory article I’ve found so far. It says:
...recognition engine can be instantiated in another process called SAPISVR.EXE. This provides a shared recognition engine that can be used simultaneously by multiple applications. This design has a number of benefits. First, recognizers generally require considerably more run-time resources than synthesizers, and sharing a recognizer is an effective way to reduce the overhead. Second, the shared recognizer is also used by the built-in speech functionality of Windows Vista. Therefore, apps that use the shared recognizer can benefit from the system's microphone and feedback UI. There's no additional code to write, and no new UI for the user to learn.New to SAPI 5.3
回答2:
The SpeechRecognition should be run on seperate thread and is coming OOTB from SpeechRecognitionEngine , should something like that:
static ManualResetEvent _completed = null;
static void Main(string[] args)
{
_completed = new ManualResetEvent(false);
SpeechRecognitionEngine _recognizer = new SpeechRecognitionEngine();
_recognizer.RequestRecognizerUpdate(); // request for recognizer update
_recognizer.LoadGrammar(new Grammar(new GrammarBuilder("test")) Name = { "testGrammar" }); // load a grammar
_recognizer.RequestRecognizerUpdate(); // request for recognizer update
_recognizer.LoadGrammar(new Grammar(new GrammarBuilder("exit")) Name = { "exitGrammar" }); // load a "exit" grammar
_recognizer.SpeechRecognized += _recognizer_SpeechRecognized;
_recognizer.SetInputToDefaultAudioDevice(); // set the input of the speech recognizer to the default audio device
_recognizer.RecognizeAsync(RecognizeMode.Multiple); // recognize speech asynchronous
_completed.WaitOne(); // wait until speech recognition is completed
_recognizer.Dispose(); // dispose the speech recognition engine
}
void _recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result.Text == "test") // e.Result.Text contains the recognized text
{
Console.WriteLine("The test was successful!");
}
else if (e.Result.Text == "exit")
{
_completed.Set();
}
}
Also had a problem similar when i used SpeechRecognition and not SpeechRecognitionEngine. the above is a great sample of the usage + its listenining to events in another thread. p.s: i got the reference from a great article: Speech recognition, speech to text, text to speech, and speech synthesis in C# have Fun :)
回答3:
Have you tried setting the service to be allowed to interact with the desktop?
I believe that interaction with user interfacing devices like a microphone is covered by this setting.