C#文本转语音并保存wav和MP3文件
回顾上次写博客至今都有4个多月了,最近工作比较的忙没时间写博文。以后会多坚持写博文,与大家分享下最近遇到的问题。最近因为项目需要,研究了下用C#开发TTS。下面把大体的思路给大家说说,希望对大家有所帮助。
首先需要了解下MS的SAPI,它是微软的语音API。它包括了语音识别SR引擎和语音合成SS引擎两种语音引擎。等下会给大家看下语音合成SS引擎。它由不同的版本,操作系统的不同使用的版本不同,不过我喜欢使用其他的合成语音包,比如:NeoSpeech公司的合成语音包。回过头来,MS 的SAPI的版本有:5.1、5.3和5.4。具体用途如下:
1. Windows Speech SDK 5.1版本支持xp系统和server 2003系统,需要下载安装。XP系统默认只带了个Microsoft Sam英文男声语音库,想要中文引擎就需要安装Windows Speech SDK 5.1。下载地址:http://www.microsoft.com/download/en/details.aspx?id=10121
2. Windows Speech SDK 5.3版本支持Vista系统和Server 2008系统,已经集成到系统里。Vista和Server 2003默认带Microsoft lili中文女声语音库和Microsoft Anna英文女声语音库。
3. Windows Speech SDK 5.4版本支持Windows7系统,也已经集成到系统里,不需要下载安装。Win7系统同样带了Microsoft lili中文女声语音库和Microsoft Anna英文女声语音库。Microsoft lili支持中英文混读。
到这里环境就准备好了,接下来讲诉下开发TTS要用到的类,我使用的是.net类库提供的语音类System.Speech.Synthesis.SpeechSynthesizer,使用前需要添加引用:System.Speech。该类的主要方法、属性、事件如下:
方法:
GetInstalledVoices():获取当前系统中安装的语音播放人,返回一个VoiceInfo对象集合,具体的对象有在控制面板中,语音项可以查看。Xp默认是Microsoft Sam。
SelectVoice(string):选择当前朗读的人员,参数是朗读者名称,如:Microsoft Sam
SpeakAsync(string):开始进行异步朗读,参数是朗读的文本。
Speak(string):开始进行朗读,参数是朗读的文本。这里我没有弄懂SpeakAsync和Speak的区别,我试了下效果都一样。
Pause():暂停正在播放朗读。
Resume():继续播放暂停的朗读。
SetOutputToWaveFile(string):保存语音文件,调用该方法后需要调用Speak方法。参数是保存文件的路径。如:d:/124.wav或d:/123.MP3
SetOutputToNull():保存文件结束语句,必须调用该语句,否则生产的语音文件无法播放。
属性:
Rate:播放语速,-10~10
Volume:音量调节:0~100
Voice:正在使用某个人员播放,返回:VoiceInfo对象。
事件:
SpeakCompleted:朗读完成事件,朗读完成后会触发该时间。可以在该事件中处理播放完成后的流程。
SpeakStarted:朗读开始事件。
SpeakProgress:朗读过程事件,可以继续一些进度条处理。
。。。。
其他属性、方法、事件用得少就不多讲了,自己看下API就知道了。有什么问题可以给我留言,我们共同探讨。界面如下:



还是把代码贴上来吧,主要代码如下:
private SpeechSynthesizer synth = null;//语音对象
/// <summary>
        /// 返回一个SpeechSynthesizer对象
        /// </summary>
        /// <returns></returns>
        private SpeechSynthesizer GetSpeechSynthesizerInstance()
        {
            if (synth == null)
            {
                synth = new SpeechSynthesizer();
            }
            return synth;
        }
/// <summary>
        /// 获得朗读设置对象
        /// </summary>
        /// <returns></returns>
        private VoiceClass GetVoiceClass()
        {
            VoiceClass setViceClass = new VoiceClass();
            setViceClass.VoiceName = cboTokens.Text;
            setViceClass.Rate = int.Parse(cboSpeed.Text);
            setViceClass.Volume = tbVoice.Value;
            setViceClass.VoiceText = txtInput.Text;
            return setViceClass;
        }
/// <summary>
        /// 播放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGo_Click(object sender, EventArgs e)
        {
            if (IsVaild())
            {
                VoiceClass setViceClass = GetVoiceClass();//VoiceClass 是自己建立的一个类,里面封转了语速 音量 播放人  播放文本
                Thread thread = new Thread(RingVoice);
                thread.Start(setViceClass);
            }
        }
        /// <summary>
        /// 开始朗读  放在线程中
        /// </summary>
        /// <param name="VoiceObject"></param>
        public void RingVoice(object VoiceObject)
        {
            try
            {
                VoiceClass voiceClass = (VoiceClass)VoiceObject;
                synth = GetSpeechSynthesizerInstance();
                synth.SelectVoice(voiceClass.VoiceName);
                synth.Rate = voiceClass.Rate;
                synth.Volume = voiceClass.Volume;
                synth.SpeakAsync(voiceClass.VoiceText);
            }
            catch (Exception er)
            {
                MessageBox.Show(er.ToString(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
/// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (IsVaild())
            {
                synth = GetSpeechSynthesizerInstance();
                VoiceClass voiceClass = GetVoiceClass();
                synth.SelectVoice(voiceClass.VoiceName);
                synth.Rate = voiceClass.Rate;
                synth.Volume = voiceClass.Volume;
SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Title = "保存文档";
                saveFileDialog.Filter = "*.wav|*.wav|*.mp3|*.mp3";
                saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                DialogResult saveDialog = saveFileDialog.ShowDialog();
                try
                {
if (saveDialog == System.Windows.Forms.DialogResult.OK)
                    {
                        synth.SetOutputToWaveFile(saveFileDialog.FileName);
                        synth.Speak(voiceClass.VoiceText);
                        synth.SetOutputToNull(); 
                        System.Diagnostics.Process.Start("Explorer.exe", string.Format(@"/select,{0}", saveFileDialog.FileName));//打开wav目录并选中文件
                    }
}
                catch (Exception er)
                {
                    MessageBox.Show(er.ToString(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
}
/// <summary>
        /// 继续
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnContinum_Click(object sender, EventArgs e)
        {
            synth.Resume();
        }
        /// <summary>
        /// 暂停
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStop_Click(object sender, EventArgs e)
        {
            synth.Pause();
        }
有个问题,不知道是什么原因,要播放的内容:欢迎致电12345客服服务系统,它把12345给我朗读成:1万2千3百4十五。这个问题还在解决中,谁知道麻烦给我留下言,谢谢。
C#文本转语音并保存wav和MP3文件的更多相关文章
- UIwebview   文件的下载与保存,以及mp3文件的播放
		这里只是说说异步 单线程下载与文件的保存 以下载一个mp3文件并保存为例: -(void)loading { //设置文件下载地址 NSString *urlString = [NSString st ... 
- WIN32下使用DirectSound接口的简单音频播放器(支持wav和mp3)
		刚好最近接触了一些DirectSound,就写了一个小程序练练手,可以用来添加播放基本的wav和mp3音频文件的播放器.界面只是简单的GDI,dxsdk只使用了DirectSound8相关的接口. D ... 
- AWS机器学习初探(2):文本翻译Translate、文本转语音Polly、语音转文本Transcribe
		AWS机器学习初探(1):Comprehend - 自然语言处理服务 这几个服务的功能和使用都很直接和简单,因此放在一篇文章中介绍. 1. 文本翻译服务 Translate 1.1 功能介绍 AWS ... 
- C# 文本转语音朗读
		1. 利用DONET框架自带的 SpeechSynthesizer ,缺点是没有感情色彩,抑扬顿挫等. using System; using System.Collections.Generic; ... 
- C#中的文本到语音
		本演示说明了如何使用c#.net Windows Forms应用程序中的system.speech库将文本转换为语音.Microsoft .NET框架提供System.Speech.Synthesis ... 
- c#文本转语音以及语音阅读小实例
		c#实现语音阅读以及文本转语音文件是基于c#的一个类库(SpeechSynthesizer )实现的,使用该类必须要添加引用using System.Speech.Synthesis;直接是无法添加引 ... 
- 用TTS实现文本转语音
		最近被toefl单词虐成狗::>_<:: 想做一个可以自动把单词转成语音的软件,这样就可以在路上戴耳机边走边听啦~ 用微软的TTS语音库可以很容易地实现.早期的TTS要想实现中英文混合朗读 ... 
- 15.Python文本转化语音方法
		1.用pywin32模块来将文本转化为语音 通过pip install pywin32安装模块,pywin32是个万金油的模块,太多的场景使用到它,但在文本转语音上,它却是个青铜玩家,简单无脑但效果不 ... 
- 在线教学、视频会议 Webus Fox(1)文本、语音、视频聊天及电子白板基本用法
		Webus Fox是基于网页的在线教学.视频会议软件,不用安装,直接使用.它提供文本.语音.视频聊天,文件共享.电子白板等功能. 1. 登录 访问 http://flash.webus.cn/#,用自 ... 
随机推荐
- Windows下配置Nginx使之支持PHP(转)
			平台描述:Windows下,使用PHP套件 xampp,因为是测试玩,所以没在服务器 Linux 环境中配置. 1. 首先,将 nginx.conf 中的 PHP 配置注释去掉. 01 # pass ... 
- 根据IP地址获取IP的详细信息
			<?php header('Content-Type:text/html; charset=utf-8'); function ip_data() { $ip = GetIP(); $url = ... 
- Java 7之多线程- Semaphore--转载
			Semaphore用于保存当前可用许可的数量.是通过共享锁实现的.根据共享锁的获取原则,Semaphore分为"公平信号量"和"非公平信号量". "公 ... 
- 使用 Java 配置进行 Spring bean 管理--转
			概述 众所周知,Spring 框架是控制反转 (IOC) 或依赖性注入 (DI) 模式的推动因素,而这种推动是通过基于容器的配置实现的.过去,Spring 允许开发人员使用基于 XML 的配置,通过利 ... 
- Preloading an Image with jQuery--reference
			Preloading images will make your application a bit faster by making it lightweight. It is very simpl ... 
- iOS开发UI篇-懒加载、重写setter方法赋值
			一.懒加载 1.懒加载定义 懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,写的是其get方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再 ... 
- Ubuntu常见问题
			1. Ubuntu16.04安装完国际版QQ后发现用不了搜狗输入法 sudo mv /usr/bin/ibus-daemon /usr/bin/ibus-daemon.bak 
- python摇骰子猜大小的小游戏
			#小游戏,摇筛子押大小的小游戏玩家初始有1000块钱,可以压大压小作为赌注 import random #定义摇筛子的函数: def roll_dice(number = 3,points = Non ... 
- Java 图片与byte数组互相转换
			//图片到byte数组 public byte[] image2byte(String path){ byte[] data = null; FileImageInputStream input = ... 
- 当ViewPager嵌套在ScrollView/ListView里时,手势冲突如何处理?
			有时我们需要将ViewPager嵌套在其他已经含有手势动作的ViewGroup里,如ScrollView,ListView时,会造成手势冲突,如表现为ViewPager向左划时,不小心向上移动了一点距 ... 
