Windows 系统调用.COM.微软语言引擎简单应用(C#)

Windows 系统调用.COM.微软语言引擎简单应用(C#)

  本文主要讲述,如何调用微软的语言引擎...

应用场景
  如看图识字软件等等....(我可不是作语言软件的、这个子是做着玩的)

涉及技术
  动态调用Com对象(全反射、没有引用com ocx)
  取得系统存在的各种语言引擎
  使用引擎进行朗读
  使用引擎进行保存声音

[代码下载/download]

程序图列:

主要功能描述
  1. 实列变量等,构造函授等

      取得所有的 识别对象模块集合,放入下拉框

    代码

      
    object  _spVoiceCls  =   null ;      // 保存朗读用的 SAPI.SpVoice 
             const   int  SpFlags  =   1 // SpeechVoiceSpeakFlags.SVSFlagsAsyn
             object  _oISpeechObjectTokens  =   null // 保存 SAPI.ISpeechObjectTokens 就是系统有的语音引擎集合
             int  TokensCount  =   0 //  语音引擎集合 数
            DictionaryEntry[] _deTokens = null // 榜定下拉框用的

            
    public  MainForm()
            {
                InitializeComponent();
                
    this .HandleDestroyed  +=   new  EventHandler(Form1_HandleDestroyed);
            }

    private   void  Form1_Load( object  sender, EventArgs e)
            {

                InitSAPI();
                
            }


  2. 系统事件:程序加载

      取得所有的 识别对象模块集合,放入下拉框

    代码

      
    void  InitSAPI()
            {
                
    // 创建语音对象朗读用
                _spVoiceCls  =  CreateComObject( " SAPI.SpVoice " );

                
    if  (_spVoiceCls  ==   null )
                {

                    MessageBox.Show(
    " 您的系统没有,微软语音组件 " );
                    Application.Exit();
                }
                
    else
                {
    // 取得所有的 识别对象模块集合

                    
                    _oISpeechObjectTokens 
    =  CallComMethod( " GetVoices " , _spVoiceCls);  // 取得 SAPI.ISpeechObjectTokens
                    
    // 识别对象集合 Count;
                     object  r  =  GetComPropery( " Count " , _oISpeechObjectTokens);
                    
    if  (r  is   int )
                    {

                        TokensCount 
    =  ( int )r;

                        
    if  (TokensCount  >   0 )
                        {
                            
    // 取得全部语音识别对象模块,及名称,以被以后使用
                            _deTokens  =   new  DictionaryEntry[TokensCount];
                            
    for  ( int  i  =   0 ; i  <  TokensCount; i ++ )
                            {
                                
    // 从集合中取出单个 识别对象模块
                                 object  oSpObjectToken  =  CallComMethod( " Item " , _oISpeechObjectTokens, i);  // 返回 SAPI.SpObjectToken
                                
    // 取名称
                                 string  Description  =  CallComMethod( " GetDescription " , oSpObjectToken)  as   string ;
                                
    // 放到 DictionaryEntry 对象中,key 是 识别对象模块,value 是名称
                                _deTokens[i]  =   new  DictionaryEntry(oSpObjectToken, Description);

                            }
                            
    // 邦定到 下拉框
                            cboxTokens.DisplayMember  =   " Value " ;
                            cboxTokens.ValueMember 
    =   " Key " ;
                            cboxTokens.DataSource 
    =  _deTokens;
                            cboxTokens.SelectedIndex 
    =   0 ;
                        }

                    }

                }

            }


  3. 用户事件:朗读

      朗读输入的文本信息

    代码

    private   void  btnSynthesis_Click( object  sender, EventArgs e)
            {
                
    string  msg  =  rTxtMsg.Text.Trim();
                
    if  (msg.Length  !=   0 )
                {

                    
    if  (_spVoiceCls  !=   null )
                    {
                        
                        
    // 设置语言引擎
                        SetComProperty( " Voice " , _spVoiceCls, cboxTokens.SelectedValue);
                        
    // 调用Speak 函数,msg 是要播放的文本,1 是异步播放,因为是异步的 com 对象不立刻释放
                        CallComMethod( " Speak " , _spVoiceCls, msg, SpFlags);

                    }
                }

            }

  4. 用户事件:保存声音

      将输入的文本信息生成音频文件保存到文件

    代码
      
             private   void  Save()
            {
                
    string  msg  =  rTxtMsg.Text.Trim();
                
    if  (msg.Length  !=   0 )
                {
                    
    using  (SaveFileDialog sfd  =   new  SaveFileDialog())
                    {
                        sfd.Filter 
    =   " wav 文件 (*.wav)|*.wav " ;
                        sfd.RestoreDirectory 
    =   true ;
                        
    if  (sfd.ShowDialog()  ==  DialogResult.OK)
                        {
                            
    /*
                             Enum SpeechStreamFileMode;
                                  SSFMOpenForRead = 0;
                                  SSFMOpenReadWrite = 1;
                                  SSFMCreate = 2;
                                  SSFMCreateForWrite = 3;

                             
    */

                            
    int  SpFileMode  =   3 ; //  SpeechStreamFileMode.SSFMCreateForWrite                    

                            
    object  oSpFileStream  =  CreateComObject( " SAPI.SpFileStream " );  // 创建 SAPI.SpFileStream
                             object  oSpVoice  =  CreateComObject( " SAPI.SpVoice " );  // 创建 SAPI.SpVoice

                            
                            
    try
                            {
                                CallComMethod(
    " Open " , oSpFileStream, sfd.FileName, SpFileMode,  false );  // 打开流
                                SetComProperty( " Voice " , oSpVoice, cboxTokens.SelectedValue);  // 设置 Voice 属性,让谁朗读
                                SetComProperty( " AudioOutputStream " , oSpVoice, oSpFileStream);  // 设置流

                                CallComMethod(
    " Speak " , oSpVoice, msg, SpFlags);  // 调用 Speak

                                CallComMethod(
    " WaitUntilDone " , oSpVoice, Timeout.Infinite);  //
                                CallComMethod( " Close " , oSpFileStream);  // 关闭流

                                MessageBox.Show(
    " 保存成功 " );
                            }                        
                            
    finally
                            {
                                Marshal.ReleaseComObject(oSpVoice);
                                Marshal.ReleaseComObject(oSpFileStream);
                            }

                            
                            

                        }

                    }
                }

            }
            
    private   void  btnSave_Click( object  sender, EventArgs e)
            {

                
    try
                {
                    btnSave.Enabled 
    =   false ;
                    Save();

                }
                
    catch  (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                
    finally
                {
                    btnSave.Enabled 
    =   true ;
                }

            }

  5. 调用com组件,功能函数

      自己写的一些帮助函数可以方便调用反射,要不太郁闷(如果是VB 就不用如此费尽了)


    #region  调用com组件,功能通用函数
            
    ///   <summary>
            
    ///  设置属性
            
    ///   </summary>
            
    ///   <param name="name"></param>
            
    ///   <param name="o"></param>
            
    ///   <param name="vlaue"></param>
             private   static   void  SetComProperty( string  name,  object  o,  object  vlaue)
            {
                Type t 
    =  o.GetType();
                t.InvokeMember(name, BindingFlags.Instance 
    |  BindingFlags.SetProperty,  null , o,  new   object [] { vlaue });
            }
            
    ///   <summary>
            
    ///  取得属性
            
    ///   </summary>
            
    ///   <param name="name"></param>
            
    ///   <param name="o"></param>
            
    ///   <returns></returns>
             private   static   object  GetComPropery( string  name,  object  o)
            {
                Type t 
    =  o.GetType();
                
    return  t.InvokeMember(name, BindingFlags.Instance  |  BindingFlags.GetProperty,  null , o,  null );
            }
            
    ///   <summary>
            
    ///  调用方法函授
            
    ///   </summary>
            
    ///   <param name="name"></param>
            
    ///   <param name="o"></param>
            
    ///   <param name="parms"></param>
            
    ///   <returns></returns>
             private   static   object  CallComMethod( string  name,  object  o,  params   object [] parms)
            {
                Type t 
    =  o.GetType();

                
    return  t.InvokeMember(name, BindingFlags.Instance  |  BindingFlags.InvokeMethod,  null , o, parms);
            }
            
    ///   <summary>
            
    ///  创建 com 对象
            
    ///   </summary>
            
    ///   <param name="FromProgID"></param>
            
    ///   <returns></returns>
             private   static   object  CreateComObject( string  FromProgID)
            {
                Type comType 
    =  Type.GetTypeFromProgID(FromProgID);
                
    object  rVar  =   null ;
                
    if  (comType  !=   null )
                    rVar 
    =  System.Activator.CreateInstance(comType);

                
    return  rVar;
            }
            
    #endregion

  6. 释放com对象
      很简单的就一行即可

    代码
    void  Form1_HandleDestroyed( object  sender, EventArgs e)
            {
                
    // 释放com对象
                Marshal.ReleaseComObject(_spVoiceCls);

            }


说明
关于 SAPI 对象的具体情参考,msdn Microsoft Speech SDK 部分是英文的帮助(VS2003 和 VS2005 的都有,ms 网站上好像也有),我英文也不好没法翻译抱歉,我用的这些函数有的是在 ms 网站上看到的有的是自己用对象浏览器慢慢找的....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值