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);
  • 相关阅读:
    用wamp配置的环境,想用CMD连接mysql怎么连
    Mysql删除表
    MySQL创建表
    Leetcode 130. Surrounded Regions
    Leetcode 111. Minimum Depth of Binary Tree
    Leetcode 110. Balanced Binary Tree
    Leetcode 98. Validate Binary Search Tree
    Leetcode 99. Recover Binary Search Tree
    Leetcode 108. Convert Sorted Array to Binary Search Tree
    Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
  • 原文地址:https://www.cnblogs.com/TanSea/p/TTS-Text-To-Speech.html
Copyright © 2011-2022 走看看