10

如何在 MS Speech 中使用 ARPA 文件?Microsoft Speech Platform 11 Recognizer 的文档暗示可以从 ARPA 文件编译语法。

我能够编译一个 ARPA 文件——例如,微软提供的小例子——使用以下命令行:

CompileGrammar.exe -In stock.arpa -InFormat ARPA

我可以在以下测试中使用生成的 CFG 文件:

using Microsoft.Speech.Recognition;

// ...

using (var engine = new SpeechRecognitionEngine(new CultureInfo("en-US")))
{
    engine.LoadGrammar(new Grammar("stock.cfg"));
    var result = engine.EmulateRecognize("will stock go up");
    Assert.That(result, Is.Not.Null);
}

此测试通过,但请注意它使用EmulateRecognize(). 当我切换到使用实际的音频文件时,如下所示:

using (var engine = new SpeechRecognitionEngine(new CultureInfo("en-US"))) 
{
    engine.LoadGrammar(new Grammar("stock.cfg"));
    engine.SetInputToWaveFile("go-up.wav");
    var result = engine.Recognize();
}

结果始终为空,并且测试失败。

微软非常明确地声明它是受支持的,但即使是非常简单的示例似乎也不起作用。我究竟做错了什么?

4

2 回答 2

3

对于您的问题:</p>

MS Speech Platform 11 识别器是否支持 ARPA 编译语法?

答案是肯定的。

我这边的工作代码,只需更改三个属性:Culture/Grammar/WaveFile。我不知道你的完整代码,但根据我的测试和演示代码,我想根本原因是我们需要在我们这边处理SpeechRecognized,而你可能没有在你这边完成。

static bool completed;

        static void Main(string[] args)  
        {
            // Initialize an in-process speech recognition engine.  
            using (SpeechRecognitionEngine recognizer =
               new SpeechRecognitionEngine(new CultureInfo("en-us")))
            {

                // Create and load a grammar.   
                Grammar dictation = new Grammar("stock.cfg");
                dictation.Name = "Dictation Grammar";

                recognizer.LoadGrammar(dictation);

                // Configure the input to the recognizer.  
                recognizer.SetInputToWaveFile("test.wav");

                // Attach event handlers for the results of recognition.  
                recognizer.SpeechRecognized +=
                  new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);
                recognizer.RecognizeCompleted +=
                  new EventHandler<RecognizeCompletedEventArgs>(recognizer_RecognizeCompleted);

                // Perform recognition on the entire file.  
                Console.WriteLine("Starting asynchronous recognition...");
                completed = false;
                recognizer.RecognizeAsync();

                // Keep the console window open.  
                while (!completed)
                {
                    Console.ReadLine();
                }
                Console.WriteLine("Done.");
            }

            Console.WriteLine();
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

        // Handle the SpeechRecognized event.  
        static void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            if (e.Result != null && e.Result.Text != null)
            {
                Console.WriteLine("  Recognized text =  {0}", e.Result.Text);
            }
            else
            {
                Console.WriteLine("  Recognized text not available.");
            }
        }

        // Handle the RecognizeCompleted event.  
        static void recognizer_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Console.WriteLine("  Error encountered, {0}: {1}",
                e.Error.GetType().Name, e.Error.Message);
            }
            if (e.Cancelled)
            {
                Console.WriteLine("  Operation cancelled.");
            }
            if (e.InputStreamEnded)
            {
                Console.WriteLine("  End of stream encountered.");
            }
            completed = true;
        }

在此处输入图像描述 在此处输入图像描述

而 wav 的内容只是“将股票上涨”(持续时间约为 2 秒)。

欲了解更多信息:https ://docs.microsoft.com/en-us/dotnet/api/system.speech.recognition.speechrecognitionengine.setinputtowavefile?redirectedfrom=MSDN&view=netframework-4.7.2#System_Speech_Recognition_SpeechRecognitionEngine_SetInputToWaveFile_System_String_

于 2018-09-27T15:44:03.700 回答
1

根据您使用的 Microsoft Speech SDK 版本,此问题有两种不同的答案。(参见:System.Speech.Recognition 和 Microsoft.Speech.Recognition 有什么区别?

System.Speech(桌面版)

在这种情况下,请参阅seiya1223 的回答。那里的示例代码效果很好。

Microsoft.Speech(服务器版)

也许是因为服务器版本不包含“听写引擎”,Microsoft.Speech 库显然永远不会匹配源自 ARPA 的 CFG。但是,它仍然会假设SpeechRecognitionRejected通过事件所说的内容。以下是 seiya1223 桌面代码的必要更改:

  1. 当然,将您的 using 语句从 System.Speech 更改为 Microsoft.Speech。
  2. 为事件添加事件处理程序SpeechRecognitionRejected
  3. 在您的事件处理程序中,检查e.Result.Text最终假设的属性。

以下代码段应有助于说明:

static string transcription;

static void Main(string[] args)  
{
  using (var recognizer = new SpeechRecognitionEngine(new CultureInfo("en-us")))
  {
    engine.SpeechRecognitionRejected += SpeechRecognitionRejectedHandler;
    // ...
  }
}

void SpeechRecognitionRejectedHandler(object sender, SpeechRecognitionRejectedEventArgs e)
{
  if (e.Result != null && !string.IsNullOrEmpty(e.Result.Text))
    transcription = e.Result.Text;
}

此处理程序在识别结束时调用一次。例如,这里是 seiya1223 代码的输出,但使用了所有可用的事件处理程序和一堆额外的日志记录(强调我的):

开始异步识别...
在 SpeechDetectedHandler 中:
-AudioPosition = 00:00:01.2300000
在 SpeechHypothesizedHandler 中:
-语法名称 = Stock;结果文本 = 进入
SpeechHypothesizedHandler:
- 语法名称 = 股票;结果文本 = will
In SpeechHypothesizedHandler:
- 语法名称 = Stock; 结果文本 = will Stock
In SpeechHypothesizedHandler:
- 语法名称 = Stock; 结果文本 = will Stock Go
In SpeechHypothesizedHandler:
- 语法名称 = Stock; 结果文本 = 库存将
在 SpeechRecognitionRejectedHandler 中上涨:
- 语法名称 = 库存;

结果文本 =在 RecognizeCompletedHandler中将增加库存。
- 音频位置 = 00:00:03.2000000;InputStreamEnded = True
- 无结果。
完毕。

于 2018-10-04T16:14:45.097 回答