Windows 系统调用.COM.微软语言引擎简单应用(C#)
本文主要讲述,如何调用微软的语言引擎...
应用场景
如看图识字软件等等....(我可不是作语言软件的、这个子是做着玩的)
涉及技术
动态调用Com对象(全反射、没有引用com ocx)
取得系统存在的各种语言引擎
使用引擎进行朗读
使用引擎进行保存声音
[代码下载/download]
应用场景
如看图识字软件等等....(我可不是作语言软件的、这个子是做着玩的)
涉及技术
动态调用Com对象(全反射、没有引用com ocx)
取得系统存在的各种语言引擎
使用引擎进行朗读
使用引擎进行保存声音
[代码下载/download]
程序图列:
主要功能描述
说明
- 实列变量等,构造函授等
取得所有的 识别对象模块集合,放入下拉框
代码
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();
}- 系统事件:程序加载
取得所有的 识别对象模块集合,放入下拉框
代码
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 ;
}
}
}
}- 用户事件:朗读
朗读输入的文本信息
代码
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);
}
}
}- 用户事件:保存声音
将输入的文本信息生成音频文件保存到文件
代码
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 ;
}
}- 调用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- 释放com对象
很简单的就一行即可
代码
void Form1_HandleDestroyed( object sender, EventArgs e)
{
// 释放com对象
Marshal.ReleaseComObject(_spVoiceCls);
}关于 SAPI 对象的具体情参考,msdn Microsoft Speech SDK 部分是英文的帮助(VS2003 和 VS2005 的都有,ms 网站上好像也有),我英文也不好没法翻译抱歉,我用的这些函数有的是在 ms 网站上看到的有的是自己用对象浏览器慢慢找的....