找到发音的正确性

时间:2013-05-25 05:50:32

标签: c# windows voice voice-recognition phonetics

我需要借助Microsoft语音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);
            }


        }
    }
}

这是与音素相关的直接代码段(从上面的代码中提取)

   //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);
        }


    }

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

enter image description here

所以,请告诉我,根据MSDN,这是“音素”。那么,这实际上是“音素”吗?我从未见过这些,这就是原因。

以上代码是根据此链接http://msdn.microsoft.com/en-us/library/microsoft.speech.recognition.srgsgrammar.srgstoken.pronunciation(v=office.14).aspx

完成的

1 个答案:

答案 0 :(得分:4)

好的,这就是我如何处理这个问题。

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

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

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

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

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

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