分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

CSpeechRecognition类封装了语音识别操作所需调用的几个接口,使用它进行语音识别编程很方便,也很简洁。

CSpeechRecognition类的定义如下:

///

// active speech engine

#include <atlbase.h>

extern CComModule _Module;

#include <atlcom.h>

#include <sapi.h>

#include <sphelper.h>

#include <spuihelp.h>

///

// speech message

#define WM_SREVENT   WM_USER+102

 

class CSpeechRecognition 

{

public:

   CSpeechRecognition();

   virtual ~CSpeechRecognition();

 

   // initialize

   BOOL Initialize(HWND hWnd = NULL, BOOL bIsShared = TRUE);

   void Destroy();

 

   // start and stop

   BOOL Start();

   BOOL Stop();

   BOOL IsDictationOn()

   {

       return m_bOnDictation;

   }

 

   // event handler

   void GetText(WCHAR **ppszCoMemText, ULONG ulStart = 0, ULONG nlCount = -1);

 

   // voice training

   HRESULT VoiceTraining(HWND hWndParent);

 

   // microphone setup

   HRESULT MicrophoneSetup(HWND hWndParent);

 

   // token list

   HRESULT InitTokenList(HWND hWnd, BOOL bIsComboBox = FALSE);

 

   // error string

   CString GetErrorString()

   {

       return m_sError;

   }

 

   // interface

     CComPtr<ISpRecognizer> m_cpRecoEngine;  // SR engine

       CComPtr<ISpRecoContext> m_cpRecoCtxt;   //Recognition contextfor dictation

     CComPtr<ISpRecoGrammar> m_cpDictationGrammar;  // Dictation grammar

 

private:

   CString m_sError;

    BOOL    m_bOnDictation;

};

其中定义的消息WM_SREVENT用于指示语音识别事件,该消息将通知到函数指定的响应窗口。

类中定义了3个接口指针m_cpRecoEngine,m_cpRecoCtxt和m_cpDictationGrammar,分别用于引用语音识别引擎的3个重要接口IspRecognizer,ISpRecoContext和IspRecoGrammar

函数Initialize语音识别引擎基本工作环境包括引擎识别上下文语法音频事件等的

BOOL CSpeechRecognition::Initialize(HWND hWnd, BOOL bIsShared)

{

   // com library

   if (FAILED(CoInitialize(NULL)))

   {

       m_sError=_T("Error intialization COM");

       return FALSE;

   }

 

   // SR engine

    HRESULT hr = S_OK;

    if (bIsShared)

    {

        // Shared reco engine.

        // For a shared reco engine, the audio gets setup automatically

        hr = m_cpRecoEngine.CoCreateInstance( CLSID_SpSharedRecognizer );

    }

   else

   {

       hr = m_cpRecoEngine.CoCreateInstance(CLSID_SpInprocRecognizer);

 

   }

 

   // RecoContext

    if( SUCCEEDED( hr ) )

    {

        hr = m_cpRecoEngine->CreateRecoContext( &m_cpRecoCtxt );

    }

 

    // Set recognition notification for dictation

    if (SUCCEEDED(hr))

    {

  hr = m_cpRecoCtxt->SetNotifyWindowMessage( hWnd, WM_SREVENT, 0, 0 );

    }

   

    if (SUCCEEDED(hr))

    {

        // when the engine has recognized something

        const ULONGLONG ullInterest = SPFEI(SPEI_RECOGNITION);

        hr = m_cpRecoCtxt->SetInterest(ullInterest, ullInterest);

    }

 

    // create default audio object

    CComPtr<ISpAudio> cpAudio;

    hr = SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN, &cpAudio);

 

    // set the input for the engine

    hr = m_cpRecoEngine->SetInput(cpAudio, TRUE);

    hr = m_cpRecoEngine->SetRecoState( SPRST_ACTIVE );

 

   // grammar

    if (SUCCEEDED(hr))

    {

        // Specifies that the grammar we want is a dictation grammar.

        // Initializes the grammar (m_cpDictationGrammar)

        hr = m_cpRecoCtxt->CreateGrammar( 0, &m_cpDictationGrammar );

    }

    if  (SUCCEEDED(hr))

    {hr = m_cpDictationGrammar->LoadDictation(NULL, SPLO_STATIC);

    }

    if (SUCCEEDED(hr))

    {

        hr = m_cpDictationGrammar->SetDictationState( SPRS_ACTIVE );

    }

    if (FAILED(hr))

    {

        m_cpDictationGrammar.Release();

    }

 

    return (hr == S_OK);

}

 

释放函数Destroy被类的析构函数调用,释放了类所引用的所有接口:

void CSpeechRecognition::Destroy()

{

   if (m_cpDictationGrammar)

       m_cpDictationGrammar.Release();

   if (m_cpRecoCtxt)

       m_cpRecoCtxt.Release();

   if (m_cpRecoEngine)

       m_cpRecoEngine.Release();

   CoUninitialize();

}

函数Start和Stop用来控制开始和停止接受及识别语音,它们通过调用引擎接口的SetRecoState方法来实现:

BOOL CSpeechRecognition::Start()

{

   if (m_bOnDictation)

       return TRUE;

 

         HRESULT hr = m_cpRecoEngine->SetRecoState( SPRST_ACTIVE );

   if (FAILED(hr))

         return FALSE;

 

   m_bOnDictation = TRUE;

   return TRUE;

}

 

BOOL CSpeechRecognition::Stop()

{

   if (! m_bOnDictation)

       return TRUE;

 

       HRESULT hr = m_cpRecoEngine->SetRecoState( SPRST_INACTIVE );

   if (FAILED(hr))

return FALSE;

 

   m_bOnDictation = FALSE;

   return TRUE;

}

函数GetText是获取从语音中已识别出的文字的关键,应该在响应识别事件/消息的响应函数中调用,其代码如下所示。

void CSpeechRecognition::GetText(WCHAR **ppszCoMemText, ULONG ulStart, ULONG nlCount)

{

    USES_CONVERSION;

    CSpEvent event;

 

    // Process all of the recognition events

    while (event.GetFrom(m_cpRecoCtxt) == S_OK)

    {

        switch (event.eEventId)

        {

            case SPEI_RECOGNITION:

       // There may be multiple recognition results, so get all of them

                {

                 HRESULT hr = S_OK;

                 if (nlCount == -1)

              event.RecoResult()->GetText(SP_GETWHOLEPHRASE,

SP_GETWHOLEPHRASE, TRUE, ppszCoMemText, NULL);

                 else

                 {

                 ASSERT(nlCount > 0);

                 event.RecoResult()->GetText(ulStart, nlCount, FALSE,

                        ppszCoMemText, NULL);

                 }

                }

                break;

        }

    }

}

函数InitTokenList调用SpInitTokenComboBox和SpInitTokenListBox函数来实现语音语言在列表或组合列表中的列表显示和选择:

HRESULT CSpeechRecognition::InitTokenList(HWND hWnd, BOOL bIsComboBox)

{

   if (bIsComboBox)

       return SpInitTokenComboBox(hWnd, SPCAT_RECOGNIZERS);

   else

       return SpInitTokenListBox(hWnd, SPCAT_RECOGNIZERS);

}

语音识别涉及语音的输入,通常用话筒来输入语音。进行语音识别前,需要判断话筒的位置和设置是否合理,以保证语音识别引擎能获得有效的语音输入。函数MicrophoneSetup调用语音识别引擎接口的DisplayUI方法来显示一个设置话筒的向导,如图11-4所示。示例代码如下所示:

HRESULT CSpeechRecognition::MicrophoneSetup(HWND hWndParent)

{

   return m_cpRecoEngine->DisplayUI(hWndParent, NULL, SPDUI_MicTraining, NULL, 0);

}

语音训练是语音识别的重要基础,为了获得期望的识别效果,必须进行语音训练,以让语音识别引擎熟悉说话者的口音。函数VoiceTraining调用语音识别引擎接口的DisplayUI方法来显示一个语音训练向导,如图11-5所示。示例代码如下所示:

HRESULT CSpeechRecognition::VoiceTraining(HWND hWndParent)

{

   return m_cpRecoEngine->DisplayUI(hWndParent, NULL, SPDUI_UserTraining, NULL, 0);

}

CText2Speech类似,CSpeechRecognition类也提供错误处理机制,由GetErrorString函数可以获得错误信息。

11.3.2  示例:用CSpeechRecognition类编制听写程序

使用CSpeechRecognition类来编写语音识别程序很简单,下面让我们实现一个听写程序Stenotypist,其界面如图11-6所示。

用VisualC++编制Stenotypist的步骤和要点如下:

1)使用AppWizard生成一个基于对话框的项目Stenotypist

2)将SpeechRecognition.H,SpeechRecognition.CPP增加到Stenotypist项目中;

3)在资源编辑器中编辑好响应的控件;

4)用ClassWizard为控件在CStenotypistDlg 类中生成相应的成员;

5)修改StenotypistDlg.h文件,为类CStenotypistDlg增加相应的变量和函数;

6)用ClassWizard为CStenotypistDlg 类添加对控件和消息的响应函数。StenotypistDlg.h的代码如下。

#include "SpeechRecognition.h"

 

// CStenotypistDlg dialog

 

class CStenotypistDlg : public CDialog

{

// Construction

public:

   CStenotypistDlg(CWnd* pParent = NULL); // standard constructor

 

// Dialog Data

   //{{AFX_DATA(CStenotypistDlg)

   enum { IDD = IDD_STENOTYPIST_DIALOG };

   CButton    m_btDictation;

   CString    m_strText;

   //}}AFX_DATA

 

   // ClassWizard generated virtual function overrides

   //{{AFX_VIRTUAL(CStenotypistDlg)

   protected:

   virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

   //}}AFX_VIRTUAL

 

   CSpeechRecognition   m_SpeechRecognition;

 

// Implementation

protected:

   HICON m_hIcon;

 

   // Generated message map functions

   //{{AFX_MSG(CStenotypistDlg)

   virtual BOOL OnInitDialog();

   afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

   afx_msg void OnPaint();

   afx_msg HCURSOR OnQueryDragIcon();

   afx_msg void OnButtonVt();

   afx_msg void OnButtonMs();

   afx_msg void OnButtonDictate();

   //}}AFX_MSG

   afx_msg LRESULT OnSREvent(WPARAM, LPARAM);

   DECLARE_MESSAGE_MAP()

};

注意,在CStenotypistDlg类中定义了一个CSpeechRecognition类的对象。

在OnInitDialog函数中调用CSpeechRecognition函数和设置语音语言列表:

BOOL CStenotypistDlg::OnInitDialog()

{

   CDialog::OnInitDialog();

 

   // Add "About..." menu item to system menu.

 

   // IDM_ABOUTBOX must be in the system command range.

   ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

   ASSERT(IDM_ABOUTBOX < 0xF000);

 

   CMenu* pSysMenu = GetSystemMenu(FALSE);

   if (pSysMenu != NULL)

   {

       CString strAboutMenu;

       strAboutMenu.LoadString(IDS_ABOUTBOX);

       if (!strAboutMenu.IsEmpty())

       {

          pSysMenu->AppendMenu(MF_SEPARATOR);

          pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

       }

   }

 

    // Set the icon for this dialog.  The framework does this automatically

   //  when the application's main window is not a dialog

   SetIcon(m_hIcon, TRUE);         // Set big icon

   SetIcon(m_hIcon, FALSE);    // Set small icon

  

   // TODO: Add extra initialization here

   if (! m_SpeechRecognition.Initialize(m_hWnd))

AfxMessageBox(m_SpeechRecognition.GetErrorString());

m_SpeechRecognition.InitTokenList(GetDlgItem(IDC_LIST1)->m_hWnd);

 

   m_SpeechRecognition.Stop();

  

   return TRUE;  // return TRUE  unless you set the focus to a control

}

开始听写和停止听写的实现较简单,只需调用CSpeechRecognition类的响应函数就能实现,其代码如下所示。注意,停止和开始是互相切换的。

void CStenotypistDlg::OnButtonDictate()

{

   if (m_SpeechRecognition.IsDictationOn())

   {

       m_SpeechRecognition.Stop();

       m_btDictation.SetWindowText("听写(&D)");

 

       SetWindowText("听写者 - 请按<听写>按钮开始听写!");

   }

   else

   {

       m_SpeechRecognition.Start();

       m_btDictation.SetWindowText("停止(&S)");

 

       SetWindowText("听写者 - 正在记录,请口述...");

   }

}

设置话筒和语音训练也通过直接调用CSpeechRecognition类的成员函数来实现:

void CStenotypistDlg::OnButtonVt()

{  m_SpeechRecognition.VoiceTraining(m_hWnd);

}

 void CStenotypistDlg::OnButtonMs()

{  m_SpeechRecognition.MicrophoneSetup(m_hWnd);

}

为了响应消息WM_SREVENT,需要添加相应的消息响应函数:

BEGIN_MESSAGE_MAP(CStenotypistDlg, CDialog)

   //{{AFX_MSG_MAP(CStenotypistDlg)

   ON_WM_SYSCOMMAND()

   ON_WM_PAINT()

   ON_WM_QUERYDRAGICON()

   ON_BN_CLICKED(IDC_BUTTON_VT, OnButtonVt)

   ON_BN_CLICKED(IDC_BUTTON_MS, OnButtonMs)

   ON_BN_CLICKED(IDC_BUTTON_DICTATE, OnButtonDictate)

   //}}AFX_MSG_MAP

   ON_MESSAGE(WM_SREVENT, OnSREvent)

END_MESSAGE_MAP()

 

LRESULT CStenotypistDlg::OnSREvent(WPARAM, LPARAM)

{  WCHAR *pwzText;

   m_SpeechRecognition.GetText(&pwzText);

  

   m_strText += CString(pwzText);

   UpdateData(FALSE);

 

   return 0L;

}

7)为了调用Speech引擎,应该在Microsoft Visual C++编程环境中设置好相应的include和lib设置:

设置include路径

    通过Project→Settings菜单项打开Project Settings对话框;

    点击C/C++项;

    在Category下拉列表中选取Preprocessor

    在“Additional include directories”编辑框中输入安装Speech SDK的include的路径,默认的路径是C:/Program Files/Microsoft Speech SDK 5.1/Include

设置lib信息

    通过Project→Settings菜单项打开Project Settings对话框;

    选择Link项;

    在Category下拉列表中选取Input

    在“Additional library path”编辑框中输入安装Speech SDK的lib的路径,默认的路径是C:/Program Files/Microsoft Speech SDK 5.1/ Lib/i386

    将“sapi.lib输入“Object/library modules所标识的编辑框中

8)编译连接该项目,就可让听写者开始听写了。

Stenotypist项目的所有源代码都存放在附盘的/Source/Stenotypist目录下。

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

一个超简单的语音识别编程,听写程序相关推荐

  1. 一个超简单的反编译任务(IDAPro、X32dbg)

    一个超简单的反汇编任务 所需工具 IDAPro.X32dbg.Visual C++ 6.0 实验步骤 首先,我们新建一个简单的程序并编译运行. 这里笔者建立了一个弹窗程序,运行结果如下: 进行IDA逆 ...

  2. java jsp网页计算器_使用JSP制作一个超简单的网页计算器的实例分享

    实现一个简单的计算器程序,要求:使用jsp+javabean模式实现. 项目源代码如下: 文件:calculator.jsp 简单的计算机 进行计算 --%> cal.calculate(); ...

  3. 从零学习pytorch 第1课 搭建一个超简单的网络

    课程目录(在更新,喜欢加个关注点个赞呗): 从零学习pytorch 第1课 搭建一个超简单的网络 从零学习pytorch 第1.5课 训练集.验证集和测试集的作用 从零学习pytorch 第2课 Da ...

  4. 一个超简单的android任务列队(排队)3

    一个超简单的android任务列队(排队)3 上一篇讲到了列队中的任务超时,这一篇继续对列队任务进行扩展,新增插入任务到列队中,可以实现插队功能,实现异步请求列队.来看代码,在LineUpTaskHe ...

  5. 一个超简单的Qt数字按键

    由于只需要几个数字按键,没必要加入软件盘,在输入框旁边直接加了一块数字键,超简单,删除键使用的键盘事件,其余均为在lineedit插入字符,超级easy!对于简单按键需求的同学有参考价值! 1.在界面 ...

  6. 一个超简单超简单的表白程序

    刷微博的时候看到一个特别有意思的程序,而且特别简单,适合用来表白和套路朋友,真的超级简单. 先看演示 原理我也不太懂,毕竟不是专业对口,直接上操作过程 1.随便新建一个文本文件 2. 打开输入代码 3 ...

  7. 使用MVC模式实现一个超简单的网上书店系统

    使用MVC模式实现网上书店(大二实验报告) 1.问题描述: 主页面要求实现如下图所示: 登录前,若选择"个人中心",则提示请登录:登录后,页面显示如图所示: 在主页面显示" ...

  8. 【Python 局域网控制】——做一个超简单的局域网指令控制电脑

    程序分为两部分,一个是客户端也是被操控的端口,另一个是服务端就是用来操作被操控的端口 点个赞留个关注吧!! 程序很简单,是通过局域网聊天系统改造而成,没有高级的GUI框架,只有简简单单的DOS窗口,这 ...

  9. 【Matlab】一个超简单的生成顺序数组的方法

    比如我想生成一个1到100的一维数组. 可以先定义一个长度为100的数组,然后接着一个for循环,就可以实现. 不过略显复杂,复杂的我都不想打个示例了. 下面介绍一个方法,在MATLAB里,一句话生成 ...

最新文章

  1. JSON Web Tokens测试工具
  2. exit的用法python_python 中exit,sys.exit,os._exit用法
  3. ZooKeeper管理员指南——部署与管理ZooKeeper
  4. 计算机内存比外存容量大吗,内存容量一般比外存容量大吗
  5. 暴风影音“猝死” ,官网、APP全挂了!网友:我的青春说没就没了
  6. OpenCV的Mat和Halcon的HObject类型互相转换
  7. Elasticsearch mysql 增量同步
  8. verilog 之数字电路 边沿检测电路
  9. 【音乐】自挂东南枝歌词原诗句(一)——2015年1月2日
  10. Git学习8 Git分支操作
  11. 手工焊的优缺点有哪些?
  12. python转cython_10分钟带你入门Cython
  13. Qtxlsx操作Excel之使用
  14. GBase 8a数据库加载流程介绍
  15. 学业竞技实业网址窗口
  16. python可以爬取58同城代码_爬取58同城—字体反爬
  17. 关于 Discuz! 的二次开发
  18. HttpClient+NTLM认证
  19. 关于TJJTDS出生的故事:
  20. Linux下GA-945GZM-S2网卡驱动安装

热门文章

  1. 生物信息学习——bowtie2使用手册
  2. 五篇经典好文,值得一看(2)
  3. Spark Streaming通过Socket检测空气质量
  4. com.android.phone目录,手机开机一直显示quot;com.android.phone已停止quot;肿么弄
  5. 最近火了的妈妈写给初二早恋儿子的一封信,初为人母,感慨这位妈妈的底蕴,留着以后借鉴
  6. 转:在收费车棚内丢失车辆的责任承担
  7. 类ExampleA继承Exception,类ExampleB继承ExampleA。 有如下代码片断:
  8. SQL批量快速替换文章标题关键词的方法语法 快速批量替换某个词技巧
  9. Android开发软件Eclipse安装教程
  10. picpick尺子像素大小精度不够准确_关于图片尺寸、输出尺寸和分辨率之间的关系,你真的理解吗?...