【问题标题】:Finding pronunciation correctness寻找发音正确性
【发布时间】:2013-05-25 05:50:31
【问题描述】:

我需要借助微软语音 SDK (System.Speech.Recognition) 来识别用户发音的“质量”。我正在使用 MS Speech Engine - US,所以我真正需要的是找出说话者的声音与“北美”口音的接近程度。

执行此操作的一种方法是检查用户的声音与美国英语语音发音的接近程度。正如 MSDN 中提到的,这个过程似乎是由它自己在语音 SDK 中完成的,所以我需要把它弄出来。由于我们也可以自己为引擎设置语音,我相信这是可能的。

但是,我不清楚自己必须做什么。那么,如何才能了解用户的发音质量/与美国北美英语语音发音的接近程度?用户只需说出预定义的句子,例如“Hello World。我在这里”。

更新

通过使用以下代码,我得到了某种“音素”(如 MSDN 中所述)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Windows.Forms;
using System.IO;

namespace US_Speech_Recognizer
{
    public class RecognizeSpeech
    {
        private SpeechRecognitionEngine sEngine; //Speech recognition engine
        private SpeechSynthesizer sSpeak; //Speech synthesizer
        string text3 = "";

        public RecognizeSpeech()
        {
            //Make the recognizer ready
            sEngine = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("en-US"));


            //Load grammar
            Choices sentences = new Choices();
            sentences.Add(new string[] { "I am hungry" });

            GrammarBuilder gBuilder = new GrammarBuilder(sentences);

            Grammar g = new Grammar(gBuilder);

            sEngine.LoadGrammar(g);

            //Add a handler
            sEngine.SpeechRecognized +=new EventHandler<SpeechRecognizedEventArgs>(sEngine_SpeechRecognized);


            sSpeak = new SpeechSynthesizer();
            sSpeak.Rate = -2;



            //Computer speaks the words to get the phones
            Stream stream = new MemoryStream();
            sSpeak.SetOutputToWaveStream(stream);


            sSpeak.Speak("I was hungry");
            stream.Position = 0;
            sSpeak.SetOutputToNull();


            //Configure the recognizer to stream
            sEngine.SetInputToWaveStream(stream);

            sEngine.RecognizeAsync(RecognizeMode.Single);


        }


        //Start the speech recognition task
        private void sEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            string text = "";

            if (e.Result.Text == "I am hungry")
            {
                foreach (RecognizedWordUnit wordUnit in e.Result.Words)
                {
                    text = text + wordUnit.Pronunciation + "\n";
                }

                MessageBox.Show(e.Result.Text + "\n" + text);
            }


        }
    }
}

这是音素相关的直接代码sn-p(摘自以上代码)

   //Start the speech recognition task
    private void sEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    {
        string text = "";

        if (e.Result.Text == "I am hungry")
        {
            foreach (RecognizedWordUnit wordUnit in e.Result.Words)
            {
                text = text + wordUnit.Pronunciation + "\n";
            }

            MessageBox.Show(e.Result.Text + "\n" + text);
        }


    }

以下是我的输出。我得到的音素从第二行开始显示。第一行简单地显示了识别的句子

所以,请告诉我,根据 MSDN,这是“音素”。那么,这实际上是“音素”吗?我从来没有见过这些,这就是为什么。

上面的代码是按照这个链接做的http://msdn.microsoft.com/en-us/library/microsoft.speech.recognition.srgsgrammar.srgstoken.pronunciation(v=office.14).aspx

【问题讨论】:

  • 投反对票的人最好能发表评论
  • 也许这个相关的答案有用吗? stackoverflow.com/a/2909005/2065121
  • @RogerRowland:感谢您的回复。这个答案很有趣。我会检查一下
  • @其他成员:也请提供您的答案:)

标签: c# windows voice voice-recognition phonetics


【解决方案1】:

好的,这就是我解决问题的方法。

首先,使用发音主题加载听写引擎,这将返回用户说出的音素(在识别事件中)。

其次,使用ISpEnginePronunciation::GetPronunciations 方法(正如我概述的here)获取单词的参考音素。

一旦你有了两组音素,你就可以比较它们。本质上,音素由空格分隔,每个音素由一个短标签表示(在American English Phoneme Representation 规范中描述)。

鉴于此,您应该能够通过使用任意数量的近似字符串匹配方案(例如,Levenshtein distance)比较音素来计算分数。

通过比较电话 ID 而不是字符串,您可能会发现问题更简单; ISpPhoneConverter::PhoneToId 可以将音素字符串转换为一组phoneID,每个音素一个ID。这将为您提供一对以 null 结尾的整数数组,可能更适合您的比较算法。

您可以使用引擎置信度来惩罚匹配项,因为引擎置信度低表明传入的音频与引擎对音素的想法不太匹配。

【讨论】:

  • 您好,我正在使用 C#。我做了一些工作来获取音素,它产生了一些字符。我正在发布代码和输出的屏幕截图,请告诉我这些是否是“音素”。请再次查看我的问题,我正在对其进行编辑并应用这些数据
  • 是的,这些音素看起来大致正确,尽管看起来它使用的是 IPA(国际音素字母)音素集,而不是 SAPI 音素集。
  • 由于您使用的是 C# 和 System.Speech.Recognition,因此您还应该使用 DictationGrammar("grammar:dictation#Pronunciation");如果这不起作用,您将不得不回退到 C++。 (您可能仍需要对某些部分使用 C++,因为 ISpEnginePronunciation 不会通过 System.Speech.Recognition 公开。)
  • 非常感谢您的回复。 “ISpEnginePronunciation”是让电脑说话,让电脑的音素说话对不对?我通过将计算机语音加载到“流”中并将其扔给识别器来做到这一点。该代码也在上面的注释“//计算机说出话来获取电话”下。 :) 你怎么看?
  • 另一个问题,当给出自定义语法时,即使你听起来不同,它总是给出相同的输出。但听写语法不会发生这种情况。这是为什么?
猜你喜欢
  • 1970-01-01
  • 2019-03-25
  • 2018-05-16
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多