2010-03-16 12:27:00 djyangmaowei 阅读数 8225
  • Python全栈视频教程

    Python全栈视频培训教程,帮助开发者从零到一入门python:1.深入理解python语法机制与底层原理,2.深入实战python各种案例 , 3.语音识别,图形界面,多线程爬虫,语音合成,游戏控制等等精彩案例。

    213794 人正在学习 去看看 尹成

应用程序可以利用SpSharedRecoContext接口创建不同的与语音识别引擎的连接。每一个连接都可以使用各自的事件并且使用不同的语音识别语法(grammars)。每一个基于SAPI语音识别的应用程序必须具有至少一个SpSharedRecoContext接口。

 

第一种方法: 自己定义Grammar

 

using System;

using System.Collections;

using System.ComponentModel;

using System.Drawing;

using System.Data;

using System.Windows.Forms;

using System.Diagnostics;

using SpeechLib;

 

namespace WindowsFormsApplication3

{

    public partial class Form1 : Form

    {

        private SpeechLib.ISpeechGrammarRule menuRule = null;

        private SpeechLib.SpSharedRecoContext objRecoContext;

        private ISpeechRecoGrammar grammar;

        public Form1()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            // 得到一个RecoContext实例. 

            objRecoContext = new SpeechLib.SpSharedRecoContext();

            // 指派一个事件给Hypothesis Event(中间层暂定的识别,即,初级的,临时的识别).

            objRecoContext.Hypothesis += new _ISpeechRecoContextEvents_HypothesisEventHandler(Hypo_Event);

            // 指派一个事件给语音识别.

            objRecoContext.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler(Reco_Event);

            //创建grammer实例.

            grammar = objRecoContext.CreateGrammar(0);

 

            label1.Text = "Speak Out one of the following./r/n1. 人民 2. 马克思 3. 孙中山 4. 恩格斯/r/n5. 杨茂巍 6. 王芳 7. 世界 8. 成都";

            //激活菜单命令.   

            menuRule = grammar.Rules.Add("MenuCommands", SpeechRuleAttributes.SRATopLevel | SpeechRuleAttributes.SRADynamic, 1);

            object PropValue = "";

            menuRule.InitialState.AddWordTransition(null, "人民", " ", SpeechGrammarWordType.SGLexical, "人民", 1, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "马克思", " ", SpeechGrammarWordType.SGLexical, "马克思", 2, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "孙中山", " ", SpeechGrammarWordType.SGLexical, "孙中山", 3, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "恩格斯", " ", SpeechGrammarWordType.SGLexical, "恩格斯", 4, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "杨茂巍", " ", SpeechGrammarWordType.SGLexical, "杨茂巍", 5, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "王芳 ", " ", SpeechGrammarWordType.SGLexical, "王芳 ", 6, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "世界", " ", SpeechGrammarWordType.SGLexical, "世界", 7, ref PropValue, 1.0F);

            menuRule.InitialState.AddWordTransition(null, "成都", " ", SpeechGrammarWordType.SGLexical, "成都", 8, ref PropValue, 1.0F);

            grammar.Rules.Commit();

            grammar.CmdSetRuleState("MenuCommands", SpeechRuleState.SGDSActive);

        }

        private void Reco_Event(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)

        {

            textBox1.Text = Result.PhraseInfo.GetText(0, -1, true);

        }

        private void Hypo_Event(int StreamNumber, object StreamPosition, ISpeechRecoResult Result)

        {

            textBox2.Text = Result.PhraseInfo.GetText(0, -1, true);

        }

    }

}

第二种方法:
不定义Grammar 利用SAPI自动识别输入语音 准确率不高
public class SpRecognition
     {
          private static SpRecognition _Instance = null ;
          private SpeechLib.ISpeechRecoGrammar isrg ;
          private SpeechLib.SpSharedRecoContextClass ssrContex =null;
          private System.Windows.Forms.Control cDisplay  ;
          private SpRecognition()
         {
              ssrContex = new SpSharedRecoContextClass() ;
              isrg = ssrContex.CreateGrammar(1) ;          
              SpeechLib._ISpeechRecoContextEvents_RecognitionEventHandler recHandle =
                   new _ISpeechRecoContextEvents_RecognitionEventHandler(ContexRecognition) ;
              ssrContex.Recognition += recHandle ;
         }
         public void BeginRec(Control tbResult)
         {            
              isrg.DictationSetState(SpeechRuleState.SGDSActive) ;
              cDisplay = tbResult ;
         }
         public static SpRecognition instance()
         {
              if (_Instance == null)
                   _Instance = new SpRecognition() ;
              return _Instance ;
         }
         public void CloseRec()
         {
              isrg.DictationSetState(SpeechRuleState.SGDSInactive) ;
         }
          private void ContexRecognition(int iIndex,object obj,SpeechLib.SpeechRecognitionType type,SpeechLib.ISpeechRecoResult result)
         {
              cDisplay.Text += result.PhraseInfo.GetText(0,-1,true) ;
         }
 
     }
第三种方法:
外界读入xml grammar (c://1.xml)
  private SpeechLib.SpSharedRecoContext ssrc;
        private ISpeechRecoGrammar srg;
        private void button1_Click(object sender, EventArgs e)
        {
            ssrc = new SpSharedRecoContext();
            srg = ssrc.CreateGrammar(1);
            srg.CmdLoadFromFile("c://1.xml", SpeechLoadOption.SLODynamic);//读入规则
           // ssrc.EventInterests = SpeechRecoEvents.SREAllEvents;//在"语音事件"中有说明
            ssrc.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler(ssrc_Recognition);//添加识别事件     
            ssrc.Hypothesis += new _ISpeechRecoContextEvents_HypothesisEventHandler(Hypo_Event);
            srg.CmdSetRuleState(srg.Rules.Item(0).Name, SpeechRuleState.SGDSActive);//激活规则       
        }
        private void button2_Click(object sender, EventArgs e)
        {
          
        }
        private void button3_Click(object sender, EventArgs e)
        {
           
        }
        void ssrc_Recognition(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)
        {
            textBox1.Text = Result.PhraseInfo.GetText(0, -1, true);
        }
        private void Hypo_Event(int StreamNumber, object StreamPosition, ISpeechRecoResult Result)
        {
            textBox2.Text = Result.PhraseInfo.GetText(0, -1, true);
        }
1.xml
<?xml version="1.0" encoding="gb2312" ?> 
<GRAMMAR LANGID="804"> 
<RULE NAME="命令" TOPLEVEL="ACTIVE"> 
<L> 
<P>口令结束</P> 
<P>放大</P> 
<P>Home</P> 
<p>End</p> 
<P>上一页</P> 
<P>下一页</P> 
<P>向上</P> 
<P>向下</P> 
<P>左窗口</P> 
<P>右窗口</P> 
<P>关闭</P> 
<P>撤消</P> 
<P>刷新</P> 
</L> 
</RULE> 
</GRAMMAR>
如要源代码 请留下邮箱 

 

2019-07-31 09:57:28 qasxc78563 阅读数 149
  • Python全栈视频教程

    Python全栈视频培训教程,帮助开发者从零到一入门python:1.深入理解python语法机制与底层原理,2.深入实战python各种案例 , 3.语音识别,图形界面,多线程爬虫,语音合成,游戏控制等等精彩案例。

    213794 人正在学习 去看看 尹成

需要语音识别相应的文件包
在这里插入图片描述
在这里插入图片描述
1、
inc—>需要的头文件
lib—>函数接口 api
cmd.bnf----->语法:由自己定义
asr_record_demo—>执行程序

2、
运行服务器:出现问题
gec@ubuntu:/mnt/hgfs/share/code/x86/bin$ ./asr_record_demo
构建离线识别语法网络…
构建语法失败!11212
语音识别完毕.

解决方法:修改系统时间 2016.12.15

出现:
gec@ubuntu:/mnt/hgfs/share/7.19/code/x86/bin$ ./asr_record_demo
构建离线识别语法网络…
构建语法成功! 语法ID:cmd
离线识别语法网络构建完成,开始识别…
wait for connecting …

服务器开始运行

3、
在开发板运行代码时候出现问题
[root@gec /]#./voicectl
./voicectl: error while loading shared libraries: lib/libvnet.so: cannot open shared object file: No such file or directory

在当前路径下创建一个 lib ,将对应的库传到lib下
mkdir lib
cd lib
rx libvnet.so

[root@gec /]#./voicectl
./voicectl: error while loading shared libraries: libxml2.so.2: cannot open shared object file:No such file or directory
解决:
cd /lib
rx libxml2.so.2

4、
注意:
开发板 电脑 ubuntu ----->这三个IP不能一样!

5、
先在虚拟机运行asr_record_demo 文件,再运行开发板程序。

6、完整工程文件
https://download.csdn.net/download/qasxc78563/11456409

2019-07-16 18:06:55 u011990489 阅读数 154
  • Python全栈视频教程

    Python全栈视频培训教程,帮助开发者从零到一入门python:1.深入理解python语法机制与底层原理,2.深入实战python各种案例 , 3.语音识别,图形界面,多线程爬虫,语音合成,游戏控制等等精彩案例。

    213794 人正在学习 去看看 尹成

HTK 连续语音识别系统搭建

前言

本文参考自HTK BOOK,完成数字序列的连续语音识别系统搭建,数字按照中文发音,如果HTK安装存在问题,或者HTK工具、脚本存在缺失,不在本文范围内;step by step! 详细步骤! 话不多说,开始!

步骤

  1. 建立目标语法文件:digit.gram, 内容如下:

    $digit= ( one | two | three | four | five | six | seven | eight | nine | zero );
    (SENT-START <$digit > SENT-END)
    
  2. 由语法文件生成词网络 :
    执行命令HParse digit.gram digit.net 生成 digit.net 词网络,digit.net的内容大致如下:

    VERSION=1.0
    N=15   L=33   
    I=0    W=SENT-END            
    I=1    W=zero                
    I=2    W=!NULL               
    I=3    W=nine                
    I=4    W=eight               
    I=5    W=seven               
    ...
    J=23    S=2    E=8    
    J=24    S=12   E=8    
    J=25    S=2    E=9    
    J=26    S=12   E=9    
    J=27    S=2    E=10   
    J=28    S=12   E=10   
    J=29    S=2    E=11   
    J=30    S=12   E=11   
    J=31    S=14   E=12   
    J=32    S=0    E=13   
    
    
  3. 生成词典:dict
    在HTK BOOK中,是使用HDMan -m -w wlist -n monophones0 -l dlog dict beep names生成词典和monophones,beep和names这两个发音词典需要用户下载、编辑,然后HDMan 将wlist中的词依次标上发音,beep词典htk book中给出了链接下载,这里可能会报order的问题,词典必须先排序。
    在本文中,并未采用该词典,而是直接手动编辑,本文采用的是中文发音(虽然符号是英文的one,two…你也可以用中文‘一’,‘二’…,但不能用阿拉伯数字12345…,会出错),不会采用beep发音词典,以下是手动编辑的dict:

    SENT-END        sil
    SENT-START      sil
    eight           b a 
    five            u 
    four            s I 
    nine            j y ow 
    one             i 
    seven           q i 
    six             l y ow 
    three           s a nT 
    two             er 
    zero            l i ng 
    

    monophone.0,训练词典中的音素列表,手动编辑如下:

    l
    i
    ng
    er
    s
    a
    nT
    I
    u
    y
    ow
    q
    b
    j
    sil
    

    如果你有大量词汇,建议还是用HDMan来生成

  4. 录音:
    采用HTK自带的工具录音(仅windows),命令HSGen -l -n 200 digit.net dict > testprompts,生成testprompts,该文件是按照语法网络随机生成的sentence,然后按照testprompts的内容录音,testprompts文件内容大概如下:

    1. SENT-START one eight two SENT-END 
    2. SENT-START six three one two SENT-END 
    ...
    n-1. SENT-START eight five three eight six nine five eight seven eight one SENT-END 
    n. SENT-START five SENT-END 
    

    HTK的HSLab工具,执行HSLab noname,弹出界面如下,点击rec,说话,然后点击stop,最后save:
    在这里插入图片描述

  5. 建立词级别标注文件
    HTKTutorial目录下提供的prompts2mlf脚本,根据testprompts生成标注文件digit.mlf(需要根据你wav保存的文件名做适当编辑),mlf文件大致如下:

    #!MLF!#
    "*/noname_s1.lab"
    one
    eight
    two
    .
    "*/noname_s2.lab"
    six
    three
    one
    two
    .
    ......
    
  6. 建立音素级别标注文件
    HLEd 工具完成音素级别标注,命令HLEd -l * -d dict -i phones0.mlf mkphones0.led digit.mlf,其中mkphones0.led文件内容编辑如下,具体含义可查看htk book:

    EX
    IS sil sil
    DE sp
    

    生成的phones0.mlf文件如下:

    #!MLF!#
    "*/noname_s1.lab"
    sil
    i
    b
    a
    er
    sil
    .
    "*/noname_s2.lab"
    sil
    l
    y
    ow
    s
    a
    nT
    i
    er
    sil
    .
    ......
    
  7. wav编码
    编码即音频特征提取,本文跟htk book保持一致,采用mfcc特征
    命令:HCopy -T 1 -C mfcc.cfg -S wav.scp
    其中mfcc.cfg内容如下:

    # Coding parameters
    TARGETKIND = MFCC_0_D_A
    TARGETRATE = 100000.0
    SAVECOMPRESSED = T
    SAVEWITHCRC = T
    WINDOWSIZE = 250000.0
    USEHAMMING = T
    PREEMCOEF = 0.97
    NUMCHANS = 26
    CEPLIFTER = 22
    NUMCEPS = 12
    ENORMALISE = F
    

    wav.scp文件内容大致如下,根据你自己的路径和文件名来编辑,linux系统也一样:

    E:\htk_demo\noname_s1.wav E:\htk_demo\noname_s1.mfc
    E:\htk_demo\noname_s2.wav E:\htk_demo\noname_s2.mfc
    E:\htk_demo\noname_s4.wav E:\htk_demo\noname_s4.mfc
    E:\htk_demo\noname_s5.wav E:\htk_demo\noname_s5.mfc
    E:\htk_demo\noname_s6.wav E:\htk_demo\noname_s6.mfc
    ...
    

    执行完后,会生成与wav文件对应的mfcc特征文件

  8. 建立Flat Start Monophones (单高斯)
    大部分情况下,我们很难事先去做音素级别的标注,所以采用Flat Start 的方式初始化。
    命令HCompV -C mfcc.cfg -f 0.01 -m -S wav.scp -M hmm0 proto, 记得手动创建hmm0文件夹,同时需要先定义HMM模型,proto文件如下:

    ~o <VecSize> 39 <MFCC_0_D_A>
    ~h "proto"
    <BeginHMM>
    <NumStates> 5
    <State> 2
    <Mean> 39
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    <Variance> 39
    1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
    <State> 3
    <Mean> 39
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    <Variance> 39
    1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
    <State> 4
    <Mean> 39
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    <Variance> 39
    1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
    <TransP> 5
    0.0 1.0 0.0 0.0 0.0
    0.0 0.6 0.4 0.0 0.0
    0.0 0.0 0.6 0.4 0.0
    0.0 0.0 0.0 0.7 0.3
    0.0 0.0 0.0 0.0 0.0
    <EndHMM>
    

    在hmm0文件夹下会生成proto和vFloors文件,根据proto生成macros和hmmdefs(这两个文件是编辑生成的,可以是手动编辑,如果音素多可以自己写脚本来生成),macros文件如下:

    ~o
    	<Vecsize> 39
    	<MFCC_0_D_A>
    ~v "varFloor1"
    	<Variance> 39
    	1.088541e+00 2.759266e-01 8.010145e-01 2.981483e-01 3.207323e-01 4.224958e-01 4.494047e-01 3.928297e-01 4.084641e-01 2.565434e-01 3.993205e-01 4.826794e-01 1.410012e+00 2.136373e-02 1.195377e-02 1.668233e-02 1.507246e-02 1.611354e-02 1.933786e-02 2.011305e-02 1.927815e-02 2.169378e-02 1.602591e-02 1.967651e-02 1.954532e-02 2.136552e-02 2.477244e-03 1.944035e-03 2.285486e-03 2.498883e-03 2.829388e-03 3.157297e-03 3.519898e-03 3.458460e-03 3.624365e-03 2.942850e-03 3.379374e-03 3.317427e-03 2.681173e-03
    

    hmdefs文件如下(仅列了一个 “ l ” 音素,该文件每个音素会有一个定义块,初始化的方差、均值、转移概率矩阵均相同,拷贝N份即可):

    ~h "l"
    	<BEGINHMM>
    	<NUMSTATES> 5
    	<STATE> 2
    	<MEAN> 39
    	 -9.377042e+00 -4.822416e+00 -3.042469e+00 -5.939115e+00 -4.617982e+00 -4.224362e+00 -5.399785e+00 -5.159544e+00 -3.788313e+00 -4.386214e+00 -1.204342e+00 -3.189081e+00 5.352872e+01 2.898896e-02 3.909288e-03 -2.158518e-02 -3.186610e-02 -3.944690e-02 -4.742377e-02 -5.350538e-02 -7.708663e-03 4.139946e-02 1.856786e-03 -5.756102e-02 -5.623914e-02 4.934247e-02 4.745388e-03 -5.247342e-04 -2.377993e-03 -1.123370e-03 -5.118148e-03 -8.695127e-03 -9.420359e-03 -5.854615e-05 1.055271e-02 1.694474e-03 -1.449268e-02 -1.187816e-02 5.448273e-03
    	<VARIANCE> 39
    	 1.088541e+02 2.759267e+01 8.010145e+01 2.981483e+01 3.207323e+01 4.224958e+01 4.494047e+01 3.928297e+01 4.084641e+01 2.565434e+01 3.993206e+01 4.826794e+01 1.410012e+02 2.136373e+00 1.195377e+00 1.668233e+00 1.507246e+00 1.611354e+00 1.933786e+00 2.011306e+00 1.927815e+00 2.169379e+00 1.602591e+00 1.967651e+00 1.954532e+00 2.136552e+00 2.477244e-01 1.944035e-01 2.285486e-01 2.498883e-01 2.829388e-01 3.157297e-01 3.519898e-01 3.458460e-01 3.624365e-01 2.942850e-01 3.379374e-01 3.317427e-01 2.681173e-01
    	<GCONST> 1.131616e+02
    	<STATE> 3
    	<MEAN> 39
    	 -9.377042e+00 -4.822416e+00 -3.042469e+00 -5.939115e+00 -4.617982e+00 -4.224362e+00 -5.399785e+00 -5.159544e+00 -3.788313e+00 -4.386214e+00 -1.204342e+00 -3.189081e+00 5.352872e+01 2.898896e-02 3.909288e-03 -2.158518e-02 -3.186610e-02 -3.944690e-02 -4.742377e-02 -5.350538e-02 -7.708663e-03 4.139946e-02 1.856786e-03 -5.756102e-02 -5.623914e-02 4.934247e-02 4.745388e-03 -5.247342e-04 -2.377993e-03 -1.123370e-03 -5.118148e-03 -8.695127e-03 -9.420359e-03 -5.854615e-05 1.055271e-02 1.694474e-03 -1.449268e-02 -1.187816e-02 5.448273e-03
    	<VARIANCE> 39
    	 1.088541e+02 2.759267e+01 8.010145e+01 2.981483e+01 3.207323e+01 4.224958e+01 4.494047e+01 3.928297e+01 4.084641e+01 2.565434e+01 3.993206e+01 4.826794e+01 1.410012e+02 2.136373e+00 1.195377e+00 1.668233e+00 1.507246e+00 1.611354e+00 1.933786e+00 2.011306e+00 1.927815e+00 2.169379e+00 1.602591e+00 1.967651e+00 1.954532e+00 2.136552e+00 2.477244e-01 1.944035e-01 2.285486e-01 2.498883e-01 2.829388e-01 3.157297e-01 3.519898e-01 3.458460e-01 3.624365e-01 2.942850e-01 3.379374e-01 3.317427e-01 2.681173e-01
    	<GCONST> 1.131616e+02
    	<STATE> 4
    	<MEAN> 39
    	 -9.377042e+00 -4.822416e+00 -3.042469e+00 -5.939115e+00 -4.617982e+00 -4.224362e+00 -5.399785e+00 -5.159544e+00 -3.788313e+00 -4.386214e+00 -1.204342e+00 -3.189081e+00 5.352872e+01 2.898896e-02 3.909288e-03 -2.158518e-02 -3.186610e-02 -3.944690e-02 -4.742377e-02 -5.350538e-02 -7.708663e-03 4.139946e-02 1.856786e-03 -5.756102e-02 -5.623914e-02 4.934247e-02 4.745388e-03 -5.247342e-04 -2.377993e-03 -1.123370e-03 -5.118148e-03 -8.695127e-03 -9.420359e-03 -5.854615e-05 1.055271e-02 1.694474e-03 -1.449268e-02 -1.187816e-02 5.448273e-03
    	<VARIANCE> 39
    	 1.088541e+02 2.759267e+01 8.010145e+01 2.981483e+01 3.207323e+01 4.224958e+01 4.494047e+01 3.928297e+01 4.084641e+01 2.565434e+01 3.993206e+01 4.826794e+01 1.410012e+02 2.136373e+00 1.195377e+00 1.668233e+00 1.507246e+00 1.611354e+00 1.933786e+00 2.011306e+00 1.927815e+00 2.169379e+00 1.602591e+00 1.967651e+00 1.954532e+00 2.136552e+00 2.477244e-01 1.944035e-01 2.285486e-01 2.498883e-01 2.829388e-01 3.157297e-01 3.519898e-01 3.458460e-01 3.624365e-01 2.942850e-01 3.379374e-01 3.317427e-01 2.681173e-01
    	<GCONST> 1.131616e+02
    	<TRANSP> 5
    	 0.000000e+00 1.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
    	 0.000000e+00 6.000000e-01 4.000000e-01 0.000000e+00 0.000000e+00
    	 0.000000e+00 0.000000e+00 6.000000e-01 4.000000e-01 0.000000e+00
    	 0.000000e+00 0.000000e+00 0.000000e+00 7.000000e-01 3.000000e-01
    	 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
    	<ENDHMM>
    
  9. 嵌入式训练
    HERest 用于HMM模型的训练,命令HERest -C mfcc.cfg -I phones0.mlf -t 250.0 150.0 1000.0 -S wav.scp -H hmm0/macros -H hmm0/hmmdefs -M hmm1 monophones0

    重估的结果会保存在hmm1下,然后继续重估两次:
    HERest -C mfcc.cfg -I phones0.mlf -t 250.0 150.0 1000.0 -S wav.scp -H hmm1/macros -H hmm1/hmmdefs -M hmm2 monophones0
    HERest -C mfcc.cfg -I phones0.mlf -t 250.0 150.0 1000.0 -S wav.scp -H hmm2/macros -H hmm2/hmmdefs -M hmm3 monophones0
    hmm3训练结果作为最终模型集

  10. 确定静音模型
    编辑文件hmm3/hmmdefs,拷贝sil模型的中间状态来建立一个新的sp模型,并存储到新的hmmdefs中,放到新目录hmm4下
    执行命令HHEd -H hmm4/macros -H hmm4/hmmdefs -M hmm5 sil.hed monophones1,其中sil.hed内容如下:

    AT 2 4 0.2 {sil.transP}
    AT 4 2 0.2 {sil.transP}
    AT 1 3 0.3 {sp.transP}
    TI silst {sil.state[3],sp.state[2]}
    

    monophones1在monophones0添加一行,内容为 sp

    然后重估两次
    HERest -C mfcc.cfg -I phones_with_sp.mlf -t 250.0 150.0 1000.0 -S wav.scp -H hmm5/macros -H hmm5/hmmdefs -M hmm6 monophones1
    HERest -C mfcc.cfg -I phones_with_sp.mlf -t 250.0 150.0 1000.0 -S wav.scp -H hmm6/macros -H hmm6/hmmdefs -M hmm7 monophones1
    此处的phones_with_sp.mlf相比之前的phones0.mlf,词与词之前加入了停顿的“sp”,大致如下:

    #!MLF!#
    "*/noname_s1.lab"
    sil
    i
    sp
    b
    a
    sp
    er
    sil
    .
    "*/noname_s2.lab"
    sil
    l
    y
    ow
    sp
    s
    a
    nT
    sp
    i
    sp
    er
    sil
    .
    

    我的样本少,所以sp是手动添加的,如果你的样本多,那你需要在词一级的mlf中按词添加sp,然后再扩展成音素级,该过程可以脚本化

  11. 建造Triphones
    HTK工具HLEd,由phone生成triphone
    执行命令 HLEd -n triphones1 -l * -i triphones.mlf mktri.led phones_with_sp.mlf,生成triphone标注和triphones1
    其中mktri.led内容如下:

    WB sp
    WB sil
    TC
    
    

    进一步生成triphone的HMM模型
    执行命令 HHEd -B -H hmm7/macros -H hmm7/hmmdefs -M hmm8 mktri.hed monophones1,生成triphone的HMM模型,mktri.hed可使用HTKTutorial目录中提供的Perl 脚本maketrihed生成,

    CL triphones1
    TI T_l {(*-l+*,l+*,*-l).transP}
    TI T_i {(*-i+*,i+*,*-i).transP}
    TI T_ng {(*-ng+*,ng+*,*-ng).transP}
    TI T_er {(*-er+*,er+*,*-er).transP}
    TI T_s {(*-s+*,s+*,*-s).transP}
    TI T_a {(*-a+*,a+*,*-a).transP}
    TI T_nT {(*-nT+*,nT+*,*-nT).transP}
    TI T_I {(*-I+*,I+*,*-I).transP}
    TI T_u {(*-u+*,u+*,*-u).transP}
    TI T_y {(*-y+*,y+*,*-y).transP}
    TI T_ow {(*-ow+*,ow+*,*-ow).transP}
    TI T_q {(*-q+*,q+*,*-q).transP}
    TI T_b {(*-b+*,b+*,*-b).transP}
    TI T_j {(*-j+*,j+*,*-j).transP}
    
    

    重估两次:
    HERest -B -C mfcc.cfg -I triphones.mlf -t 250.0 150.0 1000.0 -s stats -S wav.scp -H hmm8/macros -H hmm8/hmmdefs -M hmm9 triphones1

    HERest -B -C mfcc.cfg -I triphones.mlf -t 250.0 150.0 1000.0 -s stats -S wav.scp -H hmm9/macros -H hmm9/hmmdefs -M hmm10 triphones1

  12. triphone绑定
    执行命令HDMan -b sp -n fulllist -g global.ded -l flog dict-tri dict生成fulllist,此处的dict是全部词典,不仅仅是训练词典,本文仅演示,使用的还是上文中的训练词典dict; 其中global.ded内容为

    	AS sp
    	RS cmu
    	MP sil sil sp
    	TC
    

    fulllist 会在下一步绑定中用到

    执行命令HHEd -B -H hmm10/macros -H hmm10/hmmdefs -M hmm11 tree.hed triphones1 > log,决策树状态的绑定
    其中tree.hed比较复杂,RM Demo中的mkclscript脚本可以生成该文件,但只包含TR 2的字段,前后分别需要加上以下内容:

    TR 0
    QS  "R_NonBoundary"	{ *+* }
    QS  "R_Silence"		{ *+sil }
    QS  "R_Stop"		{ *+p,*+pd,*+b,*+t,*+td,*+d,*+dd,*+k,*+kd,*+g }
    QS  "R_Nasal"		{ *+m,*+n,*+en,*+ng }
    QS  "R_Fricative"	{ *+s,*+sh,*+z,*+f,*+v,*+ch,*+jh,*+th,*+dh }
    QS  "R_Liquid"		{ *+l,*+el,*+r,*+w,*+y,*+hh }
    QS  "R_Vowel"		{ *+eh,*+ih,*+ao,*+aa,*+uw,*+ah,*+ax,*+er,*+ay,*+oy,*+ey,*+iy,*+ow }
    ...(过长,省略)
    QS  "L_oy"		{ oy-* }
    QS  "L_p"		{ p-* }
    QS  "L_pd"		{ pd-* }
    QS  "L_r"		{ r-* }
    QS  "L_s"		{ s-* }
    QS  "L_sh"		{ sh-* }
    QS  "L_t"		{ t-* }
    QS  "L_td"		{ td-* }
    QS  "L_th"		{ th-* }
    QS  "L_ts"		{ ts-* }
    QS  "L_uh"		{ uh-* }
    QS  "L_uw"		{ uw-* }
    QS  "L_v"		{ v-* }
    QS  "L_w"		{ w-* }
    QS  "L_y"		{ y-* }
    QS  "L_z"		{ z-* }
    

    TR 1
    AU fulllist
    CO tiedlist
    ST trees
    

    重估两次:
    HERest -B -C mfcc.cfg -I triphones.mlf -t 250.0 150.0 1000.0 -S wav.scp -H hmm11/macros -H hmm11/hmmdefs -M hmm12 tiedlist

    HERest -B -C mfcc.cfg -I triphones.mlf -t 250.0 150.0 1000.0 -S wav.scp -H hmm12/macros -H hmm12/hmmdefs -M hmm13 tiedlist

结果验证

录制测试音频,依旧用HSLab录音,wav音频内容发音为“123”,保存为test.wav,HCopy生成特征文件(参考之前的内容),编辑test.mlf如下:

E:\csdn_demo\noname_test.wav E:\csdn_demo\noname_test.mfc

HVite验证结果:
HVite -C mfcc.cfg -H hmm13/macros -H hmm13/hmmdefs -S test.scp -l * -i dest.mlf -w digit.net -p 0.0 -s 5.0 dict tiedlist
查看dest.mlf中的识别结果为one two three,即123,与音频内容一致:
在这里插入图片描述

结束语

整个流程比较长,本文只录制了不到10段音频,内容比较简单,仅作为自己的一个笔记,其中涉及到的一些资源文件,比如monophones,triphones1,dict等,受限于训练样本的区别,在大家的机器上需要根据各自的样本空间做修改。特别提醒,请以HTK BOOK作为标准模板,本文仅作为参考,若文中有错误的地方,欢迎大家指出。

版权声明:本文为博主原创文章,欢迎转载,转载请说明出处,博主联系方式qq:944131033或者微信:lawer979011

2014-10-28 10:05:00 anxuexie4674 阅读数 4
  • Python全栈视频教程

    Python全栈视频培训教程,帮助开发者从零到一入门python:1.深入理解python语法机制与底层原理,2.深入实战python各种案例 , 3.语音识别,图形界面,多线程爬虫,语音合成,游戏控制等等精彩案例。

    213794 人正在学习 去看看 尹成

WindowsPhone下语音操作包括:

1、程序内部的语音识别,用户可以通过语音识别进行输入或完成相关任务   

2、控制程序的语音命令,控制程序启动、打开,并可对页面跳转等进行操作

这篇文章将构建一个简单的语音识别(一般的会将说的话全部识别出来,而利用SRGS语法可识别一句话里面的组成)

SRGS(语音识别语法规范),可以定义复杂的语音识别规则.如:识别用同义词替换了词语,漏说了非关键词等。

SRGS须先保存到StorgeFile,再添加到SpeechRecognizer类的属性上。

//按钮点击事件,开始进行语音识别
private async void Button_Click(object sender, RoutedEventArgs e) {   string message = "";   try   {     SpeechRecognizer speechRecognizer = new SpeechRecognizer();
         
    //以下两个事件就不写了     speechRecognizer.StateChanged
+= speechRecognizer_StateChanged;//状态改变     speechRecognizer.RecognitionQualityDegrading += speechRecognizer_RecognitionQualityDegrading;//语音质量     //获取内置的SRGS语法文件,如只是简单的识别出将的话,不要这三行     StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("SRGSGrammar.xml");   SpeechRecognitionGrammarFileConstraint grammarFile = new SpeechRecognitionGrammarFileConstraint(file);     speechRecognizer.Constraints.Add(grammarFile);//添加SRGS语法约束     //speechRecognizer.UIOptions.ExampleText = "这里填的是有UI时候的示例";     
    //
分析语音     SpeechRecognitionCompilationResult compilationResult = await speechRecognizer.CompileConstraintsAsync();   if (compilationResult.Status == SpeechRecognitionResultStatus.Success)     {
      var result = await speechRecognizer.RecognizeAsync();//无界面的语音识别 若为.RecognizeWithUIAsync(); 则是显示系统本身的识别界面       if (result.Confidence == SpeechRecognitionConfidence.Rejected)
      {
        message
= "识别不到";       }       else       {         resultMessage.Text = result.Text; //识别结果       }     }   }   catch (Exception err)   {     message = "异常信息:" + err.Message + err.HResult;   }
}

 SRGSGrammar.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<grammar version="1.0" xml:lang="zh-cn" root="mediaMenu" tag-format="semantics/1.0" 
      xmlns=http://www.w3.org/2001/06/grammar 
    xmlns:sapi
="http://schemas.microsoft.com/Speech/2002/06/SRGSExtensions"><!- 这些都是必不可少的--> <rule id="city" scope="public"> <one-of> <!-- 匹配其中一个短语--> <item>北京</item> <item>上海</item> </one-of> </rule> <rule id="cross" scope="public"> <one-of> <item>到</item> <item>至</item> <item>飞往</item> </one-of> </rule> <rule id="Menu" scope="public"> <item> <ruleref uri="#date"/> <!--指定关联的其他规则的节点--> <tag>out.date = reles.latest();</tag> </item> <item repeat="0-1">从</item> <!--显示1次或0次--> <item> <ruleref uri="#city"/> <tag>out.city = rulels.latest();</tag> </item> <item> <ruleref uri="#cross"/> <tag>out.cross = rulels.latest();</tag> </item> <item> <ruleref uri="#city"/> <tag>out.city = rulels.latest();</tag> </item> </rule> </grammar>

以上可以实现识别"从(“从”可有可无) 北京/上海  到/至/飞往  北京/上海"
北京到上海、从北京到上海、北京飞往上海、从上海飞往北京、上海到北京等。

可惜的是,出发地和到达地是能够重复的。且只支持“ (从)出发地---到达地” 这样特定的规则

说多了其他的(废)话,就会识别出错。

 

PS:最近的项目上要添加语音识别功能,要求用的是百度语音识别的SDK/API,可惜前者只支持Android和Iphone

后者虽是各个平台通用,但工作量上大了一点,得先进行录音,之后再通过HttpWebRequest和API传输数据,解析。 

转载于:https://www.cnblogs.com/yffswyf/p/4056106.html

2018-07-18 21:36:49 qq_37927376 阅读数 1728
  • Python全栈视频教程

    Python全栈视频培训教程,帮助开发者从零到一入门python:1.深入理解python语法机制与底层原理,2.深入实战python各种案例 , 3.语音识别,图形界面,多线程爬虫,语音合成,游戏控制等等精彩案例。

    213794 人正在学习 去看看 尹成

 

 

微软语音识别分两种模式:听写识别模式和命令识别模式。

1.听写识别模式使用的是skd中提供的字典,特点是含有的词汇量大。这种方式适合没有预定的听写内容的应用。同时因为词汇量大直接导致识别的精度降低,识别速度较慢。

2.命令识别模式使用开发人员自己定义的字典库进行识别,使用xml格式文件。这种自定义的识别方式有缺点也有优点,缺点是语法库的词汇量小,只有在xml文件中写入的词语能够被识别出并不会输出其他多余的内容。而其优点是可以进行精确地数据匹配,识别出开发者希望程序识别出的内容。

一、安装Speech SDK 5.1(SAPI 5.1)

首先开发得需要Microsoft Speech SDK的支持,以下是下载地址
http://download.csdn.net/detail/michaelliang12/9510691

二、配置环境(vs2013)

设置: 
1,属性–配置属性–C/C++–常规–附加包含目录:C:\Program Files\Microsoft SDKs\Speech\v11.0\Include(具体路径与与你安装时的路径有关) 
2,属性–配置属性–链接器–输入–附加依赖项:sapi.lib;

三、源文件

注:在我做的程序中是将语音识别的内容编写为.h文件,在主程序中进行函数调用取得识别出的文字,对识别出的地名进行处理。

c++的码段:

#pragma once
#include <windows.h>
#include <sapi.h>
#include <iostream>
#include <string.h>
#include <atlbase.h>
#include "sphelper.h"
#include"string"
#include <atlbase.h>
using namespace std;
inline HRESULT BlockForResult(ISpRecoContext * pRecoCtxt, ISpRecoResult ** ppResult) //识别
{
	HRESULT hr = S_OK;
	CSpEvent event;
	while (SUCCEEDED(hr) &&
		SUCCEEDED(hr = event.GetFrom(pRecoCtxt)) &&
		hr == S_FALSE)
	{
		hr = pRecoCtxt->WaitForNotifyEvent(INFINITE);
	}

	*ppResult = event.RecoResult();
	if (*ppResult)
	{
		(*ppResult)->AddRef();
	}
	return hr;
}
string Speech_1()
{
	HRESULT hr = E_FAIL;
	string str;
	CSpDynamicString dstrText;//取得识别结果 
	
	if (SUCCEEDED(hr = ::CoInitialize(NULL))) //进行COM初始化
	{
		{
			CComPtr<ISpRecoContext> r_cpRecoCtxt;// 识别引擎上下文(context)的接口。
			CComPtr<ISpRecoGrammar> r_cpRecoGrammar;// 识别文法(grammar)的接口。
			CComPtr<ISpVoice> r_cpVoice;//语音发声(Voice)的接口
			CComPtr<ISpRecoResult> cpResult;//接收语音识别(SR)引擎识别的结果
			if (FAILED(hr = r_cpRecoCtxt.CoCreateInstance(CLSID_SpSharedRecoContext)))
			{
				printf("r_cpRecoCtxt.CoCreateInstance() fail. hr = %x", hr);
			}
			if (FAILED(hr = r_cpRecoCtxt->GetVoice(&r_cpVoice)))
			{
				printf("r_cpRecoCtxt->GetVoice() fail. hr = %x", hr);
			}
			if (r_cpRecoCtxt && r_cpVoice)
			{
				if (FAILED(hr = r_cpRecoCtxt->SetNotifyWin32Event()))
				{
					printf("r_cpRecoCtxt->SetNotifyWin32Event() fail. hr = %x", hr);
				}
				if (FAILED(hr = r_cpRecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION))))
				{
					printf("r_cpRecoCtxt->SetInterest() fail. hr = %x", hr);
				}
				if (FAILED(hr = r_cpRecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL)))
				{
					printf("r_cpRecoCtxt->SetAudioOptions() fail. hr = %x", hr);
				}
				if (FAILED(hr = r_cpRecoCtxt->CreateGrammar(7, &r_cpRecoGrammar)))//创建语法规则 
				{
					printf("r_cpRecoCtxt->CreateGrammar() fail. hr = %x", hr);
				}
				if (FAILED(hr = r_cpRecoGrammar->SetGrammarState(SPGS_DISABLED)))
				{
					printf("r_cpRecoGrammar->SetGrammarState() fail. hr = %x", hr);
				}
				if (FAILED(hr = r_cpRecoGrammar->LoadCmdFromFile(L"conf.xml", SPLO_DYNAMIC)))//加载语法规则 
				{
					printf("r_cpRecoGrammar->LoadCmdFromFile() fail. hr = %x", hr);
			    }
				USES_CONVERSION;/* USES_CONVERSION是用来转换类型的*/
				CComPtr<ISpRecoResult> cpResult;//接收语音识别(SR)引擎识别的结果
				while (SUCCEEDED(hr = BlockForResult(r_cpRecoCtxt, &cpResult)))
				{
					if (SUCCEEDED(cpResult->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE,
						TRUE, &dstrText, NULL)))
					{
						printf("%s", W2A(dstrText));//输出识别内容
						cpResult.Release();//释放结果
						str = W2A(dstrText);//取得识别内容
						if (!str.empty())
							break;
					}
					r_cpRecoGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE);
				}
			}
		}
		::CoUninitialize();//释放结果
	}
	return str;
}

conf.xml代码:

GRAMMAR LANGID="804"> 
    <DEFINE> 
       <ID NAME="CMD" VAL="10"/> 
    </DEFINE> 
    <RULE NAME="COMMAND" ID="CMD" TOPLEVEL="ACTIVE"> 
      <L> 
<p>图书馆</P> 
<p>东门</p> 
<p>西门</p> 
<p>操场</p> 
<p>艺术馆</p> 
<p>体育馆</p> 
<p>教学楼</p> 
<p>办公楼</p> 
      </L> 
    </RULE> 
</GRAMMAR> 

 以上的代码仅能实现词语匹配的功能。

在制作这个程序的过程中参考了网上的大部分资料,才能在那么短的时间里做出想要的功能。

参考网站

1.https://blog.csdn.net/qikaibinglan/article/details/4205325
2.https://blog.csdn.net/artemisrj/article/details/8723095

 

没有更多推荐了,返回首页