• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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 网站上看到的有的是自己用对象浏览器慢慢找的....

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#设置TextBox默认显示文字,点击后消失发布时间:2022-07-13
下一篇:
C#中Base64转换为byte[]再进行处理发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap