智能電話機器人,使用Microsoft語音識別技術(Speech sdk)(下)


接上文

  現在,硬件上的准備工作做完了.

  下一步,先打開Modem的電源,用SecureCRT連接串口,敲入些AT命令,看看Modem能否執行.

  這里簡單說一下AT命令:

    AT命令有兩種解釋一種是調制解調器命令語言,簡單來說就是一些固定格式的字符串,我們通過串口向Modem發送AT命令的字符串,Modem就會按照

    命令去執行不同的操作.AT命令的百度百科請看這里,具體的命令格式和使用方法請自行百度.

  我們先來試試撥號

    向串口發送命令 : atdt10086;\r

    不出意外的話Modem就會摘機,並發出撥號音,然后就會聽到10086的語音了.

  然后是按鍵交互

    比如我要按 1鍵 然后按 #號鍵則

    按鍵命令 : atd,1,#;\r

    逗號的作用是延時,讓多個按鍵之間有些間隔,防止對方識別不清

  然后是掛機

    掛機的命令是 : ath;\r

    發送這個命令,Modem就執行掛機動作了.

  這些基本動作都可以完成之后,下面就進入第二個問題了:

    用什么技術來實現語音識別1xx86那邊所說的語音?

  這里我經過一段時間的技術調查,最終決定使用微軟Windows 7 自帶的語音識別引擎

  這個引擎有兩種識別模式,第一種是自由識別,這種方式每當引擎識別出任意一段文字之后便會觸發識別事件SpeechRecognized

  另一種方式是關鍵詞識別,這種方式只有引擎識別出的文字符合關鍵詞,才會觸發識別事件SpeechRecognized

  我們采用關鍵詞模式進行識別,根據1xx86語音播報的不同關鍵詞,來按不同的按鍵,完成功能.

    這個功能在控制面板里可以看到 控制面板 -> 輕松訪問 -> 語音識別

  

 

  .Net 有對應的類庫可以調用,命名空間如下:

  

using System.Speech.Recognition;
using System.Speech.Synthesis;

 

  引擎使用方法:

  首先,創建語音識別引擎,設置音頻輸入設備

  

CultureInfo myCIintl = new CultureInfo("zh-CN");
foreach (RecognizerInfo config in SpeechRecognitionEngine.InstalledRecognizers())//獲取所有語音引擎
{
    if (config.Culture.Equals(myCIintl) && config.Id == "MS-2052-80-DESK")
    {
        Recognizer = new SpeechRecognitionEngine(config);
        Recognizer.SetInputToDefaultAudioDevice();//選擇默認的音頻輸入設備
        break;
    }//選擇中文的識別引擎
}
if (Recognizer != null)
{
    InitializeSpeechRecognitionEngine(fg);//初始化語音識別引擎
}
else
{
    MessageBox.Show("創建語音識別失敗");
}

  然后進行初始化,加載關鍵詞

/// <summary>
/// 初始化,加載關鍵詞組
/// </summary>
/// <param name="fg">關鍵詞組</param>
private void InitializeSpeechRecognitionEngine(string[] fg)
{
    Grammar customGrammar = CreateCustomGrammar(fg);
    //根據關鍵字數組建立語法
    Recognizer.UnloadAllGrammars();
    Recognizer.LoadGrammar(customGrammar);
    //加載語法
}

   然后開始識別

/// <summary>
/// 開始識別
/// </summary>
public void BeginRec()
{
    TurnSpeechRecognitionOn();
}

  上述簡單介紹了識別引擎的使用過程,我將此過程封裝為一個類,方便主程序調用

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

using System.Speech.Synthesis;
using System.Diagnostics;

namespace Sp10086
{
    public class SRecognition
    {
        /// <summary>
        /// 語音識別引擎
        /// </summary>
        public SpeechRecognitionEngine Recognizer { get; set; }

        //重載構造函數
        public SRecognition() : this(new string[]{" "})
        {
            
        }
        public SRecognition(string[] fg) //創建關鍵詞語列表
        {
            CultureInfo myCIintl = new CultureInfo("zh-CN");
            foreach (RecognizerInfo config in SpeechRecognitionEngine.InstalledRecognizers())//獲取所有語音引擎
            {
                if (config.Culture.Equals(myCIintl) && config.Id == "MS-2052-80-DESK")
                {
                    Recognizer = new SpeechRecognitionEngine(config);
                    Recognizer.SetInputToDefaultAudioDevice();//選擇默認的音頻輸入設備
                    break;
                }//選擇中文的識別引擎
            }
            if (Recognizer != null)
            {
                InitializeSpeechRecognitionEngine(fg);//初始化語音識別引擎
            }
            else
            {
                MessageBox.Show("創建語音識別失敗");
            }
        }
        /// <summary>
        /// 初始化,加載關鍵詞組
        /// </summary>
        /// <param name="fg">關鍵詞組</param>
        private void InitializeSpeechRecognitionEngine(string[] fg)
        {
            Grammar customGrammar = CreateCustomGrammar(fg);
            //根據關鍵字數組建立語法
            Recognizer.UnloadAllGrammars();
            Recognizer.LoadGrammar(customGrammar);
            //加載語法
        }
        /// <summary>
        /// 開始識別
        /// </summary>
        public void BeginRec()
        {
            TurnSpeechRecognitionOn();
        }
        /// <summary>
        /// 停止語音識別引擎
        /// </summary>
        public void StopRec()
        {
            TurnSpeechRecognitionOff();
        }
        /// <summary>
        /// 加載關鍵詞組
        /// </summary>
        /// <param name="fg">關鍵詞組</param>
        public void ChangeKeywords(string[] fg)
        {
            InitializeSpeechRecognitionEngine(fg);

            System.Threading.Thread.Sleep(100);

            foreach(Grammar g in this.Recognizer.Grammars)
            {
                Debug.WriteLine("正在聽:" + g.Name);
            }
        }
        /// <summary>
        /// 加載關鍵詞組
        /// </summary>
        /// <param name="fg">關鍵詞組</param>
        public void ChangeKeywords(string prefix, string[] fg)
        {
            GrammarBuilder grammarBuilder = new GrammarBuilder(prefix);
            string words = string.Empty;
            foreach (string s in fg)
            {
                words += "(" + prefix + s + ")";
            }
            grammarBuilder.Append(new Choices(fg));
            //根據關鍵字數組建立語法
            Recognizer.UnloadAllGrammars();
            Recognizer.LoadGrammar(new Grammar(grammarBuilder) { Name = words });

            System.Threading.Thread.Sleep(100);
            foreach (Grammar g in this.Recognizer.Grammars)
            {
                Debug.WriteLine("正在聽:" + g.Name);
            }
        }
        /// <summary>
        /// 創造自定義語法
        /// </summary>
        /// <param name="fg">關鍵詞組</param>
        /// <returns></returns>
        public virtual Grammar CreateCustomGrammar(string[] fg)
        {
            GrammarBuilder grammarBuilder = new GrammarBuilder();
            grammarBuilder.Append(new Choices(fg));

            string words = string.Empty;
            foreach (string s in fg)
            {
                words += "("+s+")";
            }
            return new Grammar(grammarBuilder) { Name = words };
        }
        /// <summary>
        /// 啟動語音識別函數
        /// </summary>
        private void TurnSpeechRecognitionOn()
        {
            if (Recognizer != null)
            {
                Recognizer.RecognizeAsync(RecognizeMode.Multiple); 
                //識別模式為連續識別
            }
            else
            {
                MessageBox.Show("創建語音識別失敗");
            }
        }
        /// <summary>
        /// 關閉語音識別函數
        /// </summary>
        private void TurnSpeechRecognitionOff()
        {
            if (Recognizer != null)
            {
                Recognizer.RecognizeAsyncCancel();
            }
            else
            {
                MessageBox.Show("創建語音識別失敗");
            }
        }
        
    }
}

 

  主程序調用方法如下:

  

SRecognition sr = new SRecognition();
sr.Recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);
sr.BeginRec();

  識別出關鍵詞之后的處理函數:

/// <summary>
/// 識別出關鍵字后的處理函數
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    //識別出的關鍵詞
    string text = e.Result.Text;
    switch (text)
    {
        case "歡迎使用中國移動":
            //根據關鍵詞不同,按不同的按鍵
            serialPort1.Write("atd,,1,#;\r");
            //然后改變引擎所關注的關鍵詞,進行下一步的識別
            sr.ChangeKeywords(new string[] { "查詢余額" });
            break;
        
        case "查詢余額":
            serialPort1.Write("atd,2,#;\r");
            sr.ChangeKeywords(new string[] { "xxx" });
            break;
        //以下過程涉及業務邏輯,故省略
        case "xxx":
            break;
        case "yyy":
            break;
        default:
            break;
    }
}

  過程如下:

  撥通電話 

  引擎開始識別 關鍵詞 "歡迎使用中國移動"

  "歡迎使用中國移動"識別出后,進行按鍵 1鍵 #號鍵 引擎換關鍵詞 "查詢服務"

  "查詢服務" 識別出后,進行按鍵 2鍵 #號鍵

  如此一直循環下去,都是按照1xx86的充值順序進行,一直進行到輸入充值卡密碼,進行按鍵,將充值卡密碼上送 引擎換關鍵詞 "充值成功"和"充值失敗"

  根據識別出的關鍵詞 是"充值成功"還是"充值失敗",進行記錄,錄入數據庫.

  最后掛機,完成.

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM