zoukankan      html  css  js  c++  java
  • C# 利用TTS实现文本转语音

    TSS(Text To Speech),语音朗读文本的技术,在Windows下台下,微软给我们提供了一套API接口(Speech API)。金山词霸的朗读功能就是用的这个接口。

    WindowsXP自带的是Speech API 5.1版本,默认只支持英文,如果要支持中文需要安装语音库。

    Speech API 5.1 官方下载地址

    Speech API 5.1 中文语音库官方下载地址

    Vista版本开始,系统自带的Speech API就换成了5.3版本,比较奇怪的是这个API并没有做到向下兼容,5.3版本在Vista以下的版本是不可用的。

    有一些非官方的Windows优化版本去掉了语音功能,需要对系统进行修复。
    TTS修复工具及一些其他的语音库下载
    http://www.dacidian.net/tts/

    下面我说一下如何实现,使用.NET 4.0新增的dynamic类型,可以很方便的使用COM类库。

    Type type = Type.GetTypeFromProgID("SAPI.SpVoice");
    dynamic spVoice = Activator.CreateInstance(type); 
    spVoice.Speak("Text To Speech 语音朗读文本技术");

    当然,直接使用dynamic还是很不方便的,可以对SAPI.SpVoice进行封装

    using System;  
    using System.Collections.Generic;  
    using System.Text;  
    using System.Reflection;  
    using System.Diagnostics;  
    using System.Runtime.InteropServices;  
      
    namespace COM  
    {  
        [Guid("ED5DCE10-F40B-4655-9E7B-903779C77AF2")]  
        public partial class SpVoice : Object  
        {  
            public enum Flags  
            {  
                SVSFDefault = 0,  
                SVSFlagsAsync = 1,  
                SVSFPurgeBeforeSpeak = 2,   
                SVSFIsFilename = 4,   
                SVSFIsXML = 8,   
                SVSFIsNotXML = 16,  
                SVSFPersistXML = 32,  
                SVSFNLPSpeakPunc = 64,  
                SVSFParseSapi = 128,  
                SVSFParseSsml = 256,  
                SVSFParseAutodetect = 0,  
                SVSFNLPMask = 64,  
                SVSFParseMask = 384,  
                SVSFVoiceMask = 511,  
                SVSFUnusedFlags = -512  
            }  
      
            public enum Priority  
            {  
                SVPNormal = 0,   
                SVPAlert = 1,   
                SVPOver = 2  
            }  
        }  
        public partial class SpVoice : Object  
        {  
            private Type _ComType = null;  
            private object _ComObject = null;  
      
            public SpVoice()  
            {  
                this.Init();  
            }  
      
            public bool Init()  
            {  
                this._ComType = Type.GetTypeFromProgID("SAPI.SpVoice", true); // CLSID {269316D8-57BD-11D2-9EEE-00C04F797396}  
                if (this._ComType == null) {  
                    throw new Exception("COM调用失败");  
                }  
                this._ComObject = Activator.CreateInstance(this._ComType, true);  
                return this._ComObject != null;  
            }  
      
            public int Release()  
            {  
                return Marshal.ReleaseComObject(this._ComObject);  
            }  
      
            public int Rate  
            {  
                get {  
                    return (int)this._ComType.InvokeMember("Rate", BindingFlags.GetProperty, null, this._ComObject, null);   
                }  
                set {  
                    this._ComType.InvokeMember("Rate", BindingFlags.SetProperty, null, this._ComObject, new object[] { value });   
                }  
            }  
      
            public void Pause()  
            {  
                this._ComType.InvokeMember("Pause", BindingFlags.InvokeMethod, null, this._ComObject, null);  
            }  
      
            public void Resume()  
            {  
                this._ComType.InvokeMember("Resume", BindingFlags.InvokeMethod, null, this._ComObject, null);  
            }  
      
            public int Volume  
            {  
                get  
                {  
                    return (int)this._ComType.InvokeMember("Volume", BindingFlags.GetProperty, null, this._ComObject, null);  
                }  
                set  
                {  
                    this._ComType.InvokeMember("Volume", BindingFlags.SetProperty, null, this._ComObject, new object[] { value });  
                }  
            }  
      
            public int Skip(int Type, int NumItems)  
            {  
                return (int)this._ComType.InvokeMember("Skip", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { Type, NumItems });   
            }  
      
            public bool IsUISupported(string TypeOfUI, object ExtraData)  
            {  
                return (bool)this._ComType.InvokeMember("IsUISupported", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { TypeOfUI, ExtraData });  
            }  
      
            public bool WaitUntilDone(int msTimeout) {  
                return (bool)this._ComType.InvokeMember("WaitUntilDone", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { msTimeout });  
            }  
      
            public void DisplayUI(int hWndParent, string Title, string TypeOfUI, object ExtraData)  
            {  
                this._ComType.InvokeMember("DisplayUI", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { hWndParent, Title, TypeOfUI, ExtraData });  
            }  
      
            public void Speak(string Text, Flags Flags)  
            {  
                this._ComType.InvokeMember("Speak", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { Text, Flags });  
            }  
      
            public Priority Property  
            {  
                get {  
                    return (Priority)this._ComType.InvokeMember("Priority", BindingFlags.GetProperty, null, this._ComObject, null);   
                }  
                set {  
                    this._ComType.InvokeMember("Priority", BindingFlags.SetProperty, null, this._ComType, new object[] { value });  
                }  
            }  
      
            public List<string> GetVoices()  
            {  
                List<string> _ret = null;  
                object Item = null, _Voices = this._ComType.InvokeMember("GetVoices", BindingFlags.InvokeMethod, null, this._ComObject, null);  
                int Count = (int)_Voices.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, _Voices, null);  
                if (Count != 0) {  
                    _ret = new List<string>();  
                }  
                for (int i = 0; i < Count; i++) {  
                    Item = _Voices.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, _Voices, new object[]{ i });  
                    if (Item != null) {  
                        _ret.Add(Item.GetType().InvokeMember("GetDescription", BindingFlags.InvokeMethod, null, Item, null).ToString());  
                    }  
                }  
                return _ret;  
            }  
      
            public bool SetVoices(string Name)  
            {  
                bool _ret = false;  
                object Item = null, _Voices = this._ComType.InvokeMember("GetVoices", BindingFlags.InvokeMethod, null, this._ComObject, null);  
                int Count = (int)_Voices.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, _Voices, null);  
                for (int i = 0; i < Count; i++) {  
                    Item = _Voices.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, _Voices, new object[] { i });  
                    if (Item != null) {  
                        var _str = Item.GetType().InvokeMember("GetDescription", BindingFlags.InvokeMethod, null, Item, null).ToString();  
                        if (_str == Name) {  
                            this._ComType.InvokeMember("Voice", BindingFlags.SetProperty, null, this._ComObject, new object[] { Item });  
                        }  
                    }  
                }  
                return _ret;  
            }  
        }  
    }
    转载于http://blog.csdn.net/windowsvipcuvs/article/details/30751707

    这样使用起来就比较方便

    var spVoices = new SpVoice()
    {
        Rate = -2,
        Volume = 100
    };
    spVoices.SetVoices(spVoices.GetVoices()[0]);
    spVoices.Speak(speak, SpVoice.Flags.SVSFlagsAsync);
  • 相关阅读:
    Oracle函数题
    多态
    继承
    封装
    属性和修饰符
    方法重载
    构造方法
    类与实例
    SQL Server 2005 To Oracle
    Toad for Oracle 使用文档
  • 原文地址:https://www.cnblogs.com/TanSea/p/TTS-Text-To-Speech.html
Copyright © 2011-2022 走看看