C#使用反射调用SpVoice实现播放文本

每次都要引用满麻烦的 修改下不用引用了

 

使用方法

          SPVoic S = new SPVoic();
         S.Rate = 0;
         S.SpeakSave("You have selected Microsoft Sam as the computer's default voice.", @"c:/1.wav");
         S.Speak("You have selected Microsoft Sam as the computer's default voice.");

 

 

 

全部的类

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Zgke.Media
{
    /// <summary>
    /// 调用WINDOWS的 语音
    /// zgke@sina.com
    /// qq:116149
    /// </summary>
    public class SPVoic
    {
        /*
         *  SPVoic S = new SPVoic();
         *  S.Rate = 0;
         *  S.SpeakSave("You have selected Microsoft Sam as the computer's default voice.", @"c:/1.wav");
         *  S.Speak("You have selected Microsoft Sam as the computer's default voice.");
         *
         */
        private object m_SpVoice = null;
        private Type m_SpVoiceType = null;
        private IList<object> m_Voices = new List<object>();
        private int m_VoiceIndex = 0;
        private int m_Rate = 0;
        private object m_AudioOutputStream = null;

        /// <summary>
        /// 可用语音数量
        /// </summary>
        public int VoicesCount { get { return m_Voices.Count; } }

        /// <summary>
        /// 获取中文字符集
        /// </summary>
        /// <param name="p_Index"></param>
        /// <returns></returns>
        public string this[int p_Index]
        {
            get
            {
                if (p_Index < 0 || p_Index >= m_Voices.Count) throw new Exception("下标越界");
                return (string)m_Voices[p_Index].GetType().InvokeMember("GetDescription", BindingFlags.Instance | BindingFlags.InvokeMethod, null, m_Voices[p_Index], new object[] { });
            }
        }

        /// <summary>
        /// 获取和设置 使用语音
        /// </summary>
        public int VoiceIndex
        {
            get { return m_VoiceIndex; }
            set { if (value < 0 || value >= m_Voices.Count) throw new Exception("下标越界"); m_VoiceIndex = value; }
        }

        /// <summary>
        /// 语音速度
        /// </summary>
        public int Rate
        {
            get { return m_Rate; }
            set { m_Rate = value; }
        }

        public SPVoic()
        {
            m_SpVoiceType = Type.GetTypeFromProgID("SAPI.SpVoice");
            if (m_SpVoiceType == null) throw new Exception("无法获取SPVOIC");
            m_SpVoice = Activator.CreateInstance(m_SpVoiceType);
            GetList();
            //获取默认播放类型
            m_AudioOutputStream = m_SpVoiceType.InvokeMember("AudioOutputStream", BindingFlags.Instance | BindingFlags.GetProperty, null, m_SpVoice, new object[] { });
        }

        /// <summary>
        /// 获取可用集合
        /// </summary>
        private void GetList()
        {
            object _Voices = m_SpVoiceType.InvokeMember("GetVoices", BindingFlags.Instance | BindingFlags.InvokeMethod, null, m_SpVoice, new object[] { });
            //获取集合数量
            int _Count = (int)_Voices.GetType().InvokeMember("Count", BindingFlags.Instance | BindingFlags.GetProperty, null, _Voices, new object[] { });
            m_Voices.Clear();
            for (int i = 0; i != _Count; i++)
            {
                //取出一种声音
                object _Voice = _Voices.GetType().InvokeMember("Item", BindingFlags.Instance | BindingFlags.InvokeMethod, null, _Voices, new object[] { i });
                m_Voices.Add(_Voice);
            }
        }

        /// <summary>
        /// 播放文字
        /// </summary>
        /// <param name="p_Text">播放文字</param>
        /// <param name="p_VoiceIndex">语音集索引</param>
        /// <param name="p_Rate">语音速度</param>
        public void Speak(string p_Text)
        {
            //设置默认播放类型
            m_SpVoiceType.InvokeMember("AudioOutputStream", BindingFlags.Instance | BindingFlags.SetProperty, null, m_SpVoice, new object[] { m_AudioOutputStream });
            //设置语音
            m_SpVoiceType.InvokeMember("Voice", BindingFlags.Instance | BindingFlags.SetProperty, null, m_SpVoice, new object[] { m_Voices[m_VoiceIndex] });
            //设置速度
            m_SpVoiceType.InvokeMember("Rate", BindingFlags.Instance | BindingFlags.SetProperty, null, m_SpVoice, new object[] { m_Rate });
            //开始播放
            m_SpVoiceType.InvokeMember("Speak", BindingFlags.Instance | BindingFlags.InvokeMethod, null, m_SpVoice, new object[] { p_Text, 1 });
        }

        public void SpeakSave(string p_Text, string p_File)
        {
            object _SpFileStream = Activator.CreateInstance(Type.GetTypeFromProgID("SAPI.SpFileStream"));
            try
            {
                //使用SP FileStream打开文件
                _SpFileStream.GetType().InvokeMember("Open", BindingFlags.Instance | BindingFlags.InvokeMethod, null, _SpFileStream, new object[] { p_File, 3, false });
                //设置语音
                m_SpVoiceType.InvokeMember("Voice", BindingFlags.Instance | BindingFlags.SetProperty, null, m_SpVoice, new object[] { m_Voices[m_VoiceIndex] });
                //设置速度
                m_SpVoiceType.InvokeMember("Rate", BindingFlags.Instance | BindingFlags.SetProperty, null, m_SpVoice, new object[] { m_Rate });
                //设置播放到那里
                m_SpVoiceType.InvokeMember("AudioOutputStream", BindingFlags.Instance | BindingFlags.SetProperty, null, m_SpVoice, new object[] { _SpFileStream });
                //开始播放
                m_SpVoiceType.InvokeMember("Speak", BindingFlags.Instance | BindingFlags.InvokeMethod, null, m_SpVoice, new object[] { p_Text, 1 });
                //等待播放结束
                m_SpVoiceType.InvokeMember("WaitUntilDone", BindingFlags.Instance | BindingFlags.InvokeMethod, null, m_SpVoice, new object[] { -1 });
                //关闭文件
                _SpFileStream.GetType().InvokeMember("Close", BindingFlags.Instance | BindingFlags.InvokeMethod, null, _SpFileStream, new object[] { });
            }
            finally
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(_SpFileStream);
            }
        }

    }
}

使用SpVoice进行文本到语音(TTS)转换时,可以通过事件处理机制来响应文本播放完成的事件。SpVoiceMicrosoft Speech API (SAPI) 5.3或更高版本中提供的一个类,用于控制语音合成器的文本播放。要使用SpVoice播放完成事件,通常需要使用如COM事件接口等机制。 1. 首先,你需要创建一个SpVoice对象。 2. 然后,你需要实现一个事件接收器,该接收器实现了ISpTTSEventSink接口,这个接口包含了语音合成器产生的事件,例如播放完成事件。 3. 通过调用SpVoice的SetEvents接口方法,将事件接收器与SpVoice对象关联起来。 4. 当SpVoice完成文本播放时,事件接收器的NotifyEvent方法会被调用,这时你可以在这个方法中处理播放完成后的逻辑。 这里给出一个简化的代码示例(不包含错误处理和COM初始化代码): ```cpp #include <sapi.h> #include <iostream> // 定义事件接收器类 class MyEvents : public ISpTTSEventSink { public: // 实现ISpTTSEventSink接口的NotifyEvent方法 HRESULT __stdcall NotifyEvent(SPEVENT const * pEvent) override { // 检查事件类型是否为播放完成 if (pEvent->eEventId == SPEI_ENDInputStream) { std::cout << "Text has been spoken!" << std::endl; } return S_OK; } // ISpTTSEventSink接口的其他方法实现... }; int main() { CoInitialize(NULL); // 初始化COM库 // 创建SpVoice对象 ISpVoice *pVoice = NULL; HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); if (SUCCEEDED(hr)) { // 创建事件接收器实例 MyEvents *pEvents = new MyEvents(); // 设置SpVoice对象的事件接收器 pVoice->SetEvents(pEvents, NULL); // 使用SpVoice对象进行文本播放等操作... // 不要忘记释放COM对象 pVoice->Release(); delete pEvents; } CoUninitialize(); // 清理COM库 return 0; } ``` 请注意,这个示例是为了展示基本概念而简化了的。实际使用时需要包含相应的头文件,并且要正确处理COM初始化和清理,以及可能的错误情况。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值