C#中调用SAPI实现语音合成的2种方法
作者:junjie 发布时间:2023-07-07 09:36:00
我们都知道现在的语音合成TTS是可以通过微软的SAPI实现的,好处我就不多说了,方便而已,因为在微软的操作系统里面就自带了这个玩意,主要的方式有两种:
1、使用COM组件技术,不管是C++,C#,Delphi都能玩的转,开发出来的东西在XP和WIN7都能跑。(要引入SpeechLib,好像在项目上点引用,然后选到系统COM吧,好久没弄,记不清楚了)
2、使用WIN7的windows api,其实最终还是调用了SAPI,所以开发出来的东西就只能在WIN7上面跑。
其实不管是哪一种,都是调用SAPI,可能后一种代码比较简单,使用已经安装的TTS引擎,现在一般用NeoSpeech,这个就不解释了,太强大了这个发音。。。
COM组件技术:
public class Speach
{
private static Speach _Instance = null ;
private SpeechLib.SpVoiceClass voice =null; //SAPI5.1
private SpeechLib.SpVoice voice = null;//SAPI 5.4
private Speach()
{
BuildSpeach() ;
}
public static Speach instance()
{
if (_Instance == null)
_Instance = new Speach() ;
return _Instance ;
}
private void SetChinaVoice()
{
voice.Voice = voice.GetVoices(string.Empty,string.Empty).Item(0) ;
}
private void SetEnglishVoice()
{
voice.Voice = voice.GetVoices(string.Empty,string.Empty).Item(1) ;
}
private void SpeakChina(string strSpeak)
{
SetChinaVoice() ;
Speak(strSpeak) ;
}
private void SpeakEnglishi(string strSpeak)
{
SetEnglishVoice() ;
Speak(strSpeak) ;
}
public void AnalyseSpeak(string strSpeak)
{
int iCbeg = 0 ;
int iEbeg = 0 ;
bool IsChina = true ;
for(int i=0;i<strSpeak.Length;i++)
{
char chr = strSpeak[i] ;
if (IsChina)
{
if (chr<=122&&chr>=65)
{
int iLen = i - iCbeg ;
string strValue = strSpeak.Substring(iCbeg,iLen) ;
SpeakChina(strValue) ;
iEbeg = i ;
IsChina = false ;
}
}
else
{
if (chr>122||chr<65)
{
int iLen = i - iEbeg ;
string strValue = strSpeak.Substring(iEbeg,iLen) ;
this.SpeakEnglishi(strValue) ;
iCbeg = i ;
IsChina = true ;
}
}
}//end for
if (IsChina)
{
int iLen = strSpeak.Length - iCbeg ;
string strValue = strSpeak.Substring(iCbeg,iLen) ;
SpeakChina(strValue) ;
}
else
{
int iLen = strSpeak.Length - iEbeg ;
string strValue = strSpeak.Substring(iEbeg,iLen) ;
SpeakEnglishi(strValue) ;
}
}
private void BuildSpeach()
{
if (voice == null)
voice = new SpVoiceClass() ;
}
public int Volume
{
get
{
return voice.Volume ;
}
set
{
voice.SetVolume((ushort)(value)) ;
}
}
public int Rate
{
get
{
return voice.Rate ;
}
set
{
voice.SetRate(value) ;
}
}
private void Speak(string strSpeack)
{
try
{
voice.Speak(strSpeack,SpeechVoiceSpeakFlags.SVSFlagsAsync) ;
}
catch(Exception err)
{
throw(new Exception("发生一个错误:"+err.Message)) ;
}
}
public void Stop()
{
voice.Speak(string.Empty,SpeechLib.SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak) ;
}
public void Pause()
{
voice.Pause() ;
}
public void Continue()
{
voice.Resume() ;
}
}//end class
在 private SpeechLib.SpVoiceClass voice =null;这里,我们定义个一个用来发音的类,并且在第一次调用该类时,对它用BuildSpeach方法进行了初始化。
我们还定义了两个属性Volume和Rate,能够设置音量和语速。
我们知道,SpVoiceClass 有一个Speak方法,我们发音主要就是给他传递一个字符串,它负责读出该字符串,如下所示。
private void Speak(string strSpeack)
{
try
{
voice.Speak(strSpeack,SpeechVoiceSpeakFlags.SVSFlagsAsync) ;
}
catch(Exception err)
{
throw(new Exception("发生一个错误:"+err.Message)) ;
}
}
第二种使用.NET类库和系统API的代码如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Speech.Synthesis;using System.Speech;namespace StudyBeta{ public class SRead { public SpeechSynthesizer synth; //语音合成对象 public SRead() { synth = new SpeechSynthesizer(); } public SRead(int m, int n) { //使用 synth 设置朗读音量 [范围 0 ~ 100] synth.Volume = m; //使用 synth 设置朗读频率 [范围 -10 ~ 10] synth.Rate = n; } public void SpeakChina(string ggg) { //SpVoice Voice = new SpVoice(); synth.SelectVoice("Microsoft Lili"); //Voice.Speak(ggg, SpFlags); synth.SpeakAsync(ggg); //String speechPeople = synth.Voice; //使用 synth 设置朗读音量 [范围 0 ~ 100] // synth.Volume = 80; //使用 synth 设置朗读频率 [范围 -10 ~ 10] // synth.Rate = 0; //使用synth 合成 wav 音频文件: //synth.SetOutputToWaveFile(string path); } public void SpeakEnglish(string ggg) { //SpVoice Voice = new SpVoice(); synth.SelectVoice("VW Julie"); synth.Speak(ggg); //ggg为要合成的内容 } public int m { get { return synth.Volume; } set { synth.Volume = value; } } public int n { get { return synth.Rate; } set { synth.Rate = value; } }}


猜你喜欢
- 本文实例讲述了C#可用于登录验证码的四位随机数生成方法。分享给大家供大家参考。具体实现方法如下:这里提供了两种方法,调用其一即可:using
- 前言现代化大型项目通常使用独立的数据库来存储数据,其中以采用关系型数据库居多。用于开发项目的高级语言(C#、Java等)是面向对象的,而关系
- 阿姆斯特朗数阿姆斯特朗数是一个数字,等于每个数字的幂乘以总位数。 例如,诸如0、1、153、370、371和407、1634、8208、94
- 一、项目简述功能: 系统分为三个角色。最高权限管理员,学生,教师,包括 学生管理,教师管理,课程管理,选课,退课,成绩查 询。,教学课程,查
- 本文实例讲述了C#实现顺序表(线性表)的方法。分享给大家供大家参考,具体如下:基本思想是使用数组作为盛放元素的容器,数组一开始的大小要实现确
- 编码问题,有两种方式可以解决,一是在您的程序中直接使用setlocale函数设置Windows的编码方式为中文(好像中文的值是.936);s
- 女朋友他们项目用了 spring-boot,以 spring-boot-parent 作为 parent:<parent> &l
- 这是一个演示如何使用java执行定时任务的实例,本实例开始运行后不会自动结束,请在运行本实例后手动结束程序。package com.hong
- 1 前言前文已经讲述了Spring BeanFactory 与 FactoryBean 的区别详情,
- 1.概述本文中,我将向你介绍Spring Cloud Netflix Turbine。它将多个Hystrix Metrics Streams
- 投影(Projection) 是一种可以将查询结果进行 塑性 的一种操作,你可以使用 投影 将一个 object 转成仅包含你需要属性的新对
- JAVA中获取文件MD5值的四种方法其实都很类似,因为核心都是通过JAVA自带的MessageDigest类来实现。获取文件MD5值主要分为
- Android安全加密专题文章索引Android安全加密:对称加密Android安全加密:非对称加密Android安全加密:消息摘要Mess
- 本文实例讲述了C#多线程学习之使用定时器进行多线程的自动管理。分享给大家供大家参考。具体分析如下:Timer类:设置一个定时器,定时执行用户
- 前言本文主要给大家介绍了关于java poi导入Excel通用工具类的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍
- Monkeyrunner 常用按键 &nbs
- ArrayList中存放引用数据类型ArrayList中存放引用类型时,存放的是一个引用,因此在放入ArrayList之后再进行改动会影响到
- 目录前言if-thenif-then-elseswitch使用 Stringwhiledo-whileforbreakcontinueret
- 本文实例为大家分享了Android实现聊天界面的具体代码,供大家参考,具体内容如下文件目录在app下的build.gradle中添加依赖库(
- 序列化(Serialize)是将对象转换成字节流,并将其用于存储或传输的过程,主要用途是保存对象的状态,以便在需要时重新创建该对象;反序列化