隐藏

C# Windows系统语音,发声程序 TTS

发布:2021/2/2 11:51:23作者:管理员 来源:本站 浏览次数:990

代码

C#项目中添加COM引用Microsoft Speech Object Library,然后在CS文件中写using SpeechLib;即可。

SpVoice voice = new SpVoice(); voice.Speak(txt.Text, SpeechVoiceSpeakFlags.SVSFDefault); //同步朗读 voice.Speak(txt.Text, SpeechVoiceSpeakFlags.SVSFlagsAsync); //异步朗读 voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(0);//设置中文语音 voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(1);设置英文语音 

错误修改:VS2010中 错误无法嵌入互操作类型“SpeechLib.SpVoiceClass”。请改用适用的接口
解决方案:选中项目中引入的dll,鼠标右键,选择属性,把“嵌入互操作类型”设置为False。

异常来自 HRESULT:0x8004503异常信息。一般是由Windows Audio服务没有开启造成的,尤其是win2003默认不开Windows Audio服务。
1)请确认Windows Audio(AudioSrv)服务启动。
进入cmd 输入net start AudioSrv
2)声卡驱动安装成功。”

功能强大之处在于TTS能识别XML标记,通过给文本加上XML标记,我们让TTS朗读出更加符合语言阅读习惯的句子。例如:

<volume level="60"></volume> 用于设置文本朗读的音量; <rate absspeed="1"/><rate speed="5"/> 分别用于设置文本朗读的绝对速度和相对速度; <pitch absmiddle="2"/><pitch middle="5"/> 分别用于设置文本朗读的绝对语调和相对语调; <emph></emph> 在他们之间的句子被视为强调; <spell></spell> 可以将单词逐个字母的拼写出来; <silence msec="500"/> 表示停止发声,并保持500微秒; <context id="date_mdy">02/03/07</context> 可以按要求朗读出日期 <voice required="Language=409"></voice> 

用于设置朗读所用的语言,其中409表示使用英语,804表示使用汉语,而411表示日语。
实例:

protected void speak_Click(object sender, EventArgs e) {  if (!string.IsNullOrWhiteSpace(txt.Text))  {  SpVoice voice = new SpVoice();  StreamReader objReader = new StreamReader(HttpContext.Current.Server.MapPath("~/upload/test.xml"));  string sLine =string.Empty ;  string sPreview = string.Empty;  while (sLine != null)  {  sLine = objReader.ReadLine();  if (sLine != null)  {  // 这里需要添加Environment.NewLine表示换行  sPreview += sLine + Environment.NewLine;  }  }  SpeakXml(sPreview);  // 关闭文件读取器  objReader.Close();  } } /// <summary> /// 读出Xml文件内容 /// </summary> /// <param name="xml">Xml文件内容</param> public void SpeakXml(string xml) {  new SpVoice().Speak(xml, SpeechVoiceSpeakFlags.SVSFIsXML | SpeechVoiceSpeakFlags.SVSFlagsAsync); } /// <summary> /// 保存音频到文件 /// </summary> /// <param name="xml">要读的Xml格式的内容</param> /// <param name="fileName">要保存的文件名</param> public void Save(string xml, string fileName) {  SpVoice voice = new SpVoice();  SpFileStream stream = new SpFileStream();  stream.Open(HttpContext.Current.Server.MapPath(fileName), SpeechStreamFileMode.SSFMCreateForWrite, false);  voice.AudioOutputStream = stream;  voice.Speak(xml, SpeechVoiceSpeakFlags.SVSFlagsAsync | SpeechVoiceSpeakFlags.SVSFIsXML);  voice.WaitUntilDone(3);  stream.Close(); } // <summary> /// 设置中文语音 /// </summary> public void SetChinaVoice() {  SpVoice voice = new SpVoice();  voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(0); } /// <summary> /// 设置英文语音 /// </summary> public void SetEnglishVoice() {  SpVoice voice = new SpVoice();  voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(1); } 

界面的实现

在打开文件时,可以选择打开文本文件(*.Txt)和XML文件(*.Xml),如果打开的是XML文件,将不对内容作任何修改,并且也不允许调节音量、语速、语调,因为这些都应该在XML文件中写好;如果打开的是文本文件,则在朗读前,会调用AddXmlLangTag方法给文本加上语言标记,调用AddXmlPitchTag方法给文本加上语调标记,同时也允许调节音量、语速、语调。

总结

通过为普通文本内容设置语音XML标记,并调用SpVoice接口的Speak方法,可以实现中英文文本的混合朗读。如果要使朗读的效果更佳,就必须手工为每一个句子设置相应的XML标记,这样可使朗读更接近人性化。


using SpeechLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;

namespace WSpeech
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected void speak_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(textBox1.Text))
            {
                SpVoice voice = new SpVoice();
                StreamReader objReader = new StreamReader(HttpContext.Current.Server.MapPath("~/upload/test.xml"));
                string sLine = string.Empty;
                string sPreview = string.Empty;
                while (sLine != null)
                {
                    sLine = objReader.ReadLine();
                    if (sLine != null)
                    {
                        // 这里需要添加Environment.NewLine表示换行
                        sPreview += sLine + Environment.NewLine;
                    }
                }
                SpeakXml(sPreview);
                // 关闭文件读取器
                objReader.Close();
            }
        }
        /// <summary>
        /// 读出Xml文件内容
        /// </summary>
        /// <param name="xml">Xml文件内容</param>
        public void SpeakXml(string xml)
        {
            new SpVoice().Speak(xml, SpeechVoiceSpeakFlags.SVSFIsXML | SpeechVoiceSpeakFlags.SVSFlagsAsync);
        }
        /// <summary>
        /// 保存音频到文件
        /// </summary>
        /// <param name="xml">要读的Xml格式的内容</param>
        /// <param name="fileName">要保存的文件名</param>
        public void Save(string xml, string fileName)
        {
            SpVoice voice = new SpVoice();
            SpFileStream stream = new SpFileStream();
            stream.Open(HttpContext.Current.Server.MapPath(fileName), SpeechStreamFileMode.SSFMCreateForWrite, false);
            voice.AudioOutputStream = stream;
            voice.Speak(xml, SpeechVoiceSpeakFlags.SVSFlagsAsync | SpeechVoiceSpeakFlags.SVSFIsXML);
            voice.WaitUntilDone(3);
            stream.Close();
        }
        // <summary>
        /// 设置中文语音
        /// </summary>
        public void SetChinaVoice()
        {
            SpVoice voice = new SpVoice();
            voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(0);
        }
        /// <summary>
        /// 设置英文语音
        /// </summary>
        public void SetEnglishVoice()
        {
            SpVoice voice = new SpVoice();
            voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(1);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SpVoice voice = new SpVoice();
            voice.Speak(textBox1.Text, SpeechVoiceSpeakFlags.SVSFDefault); //同步朗读
        }
    }

}