欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#中调用SAPI实现语音合成的2种方法

程序员文章站 2022-06-14 17:22:38
我们都知道现在的语音合成tts是可以通过微软的sapi实现的,好处我就不多说了,方便而已,因为在微软的操作系统里面就自带了这个玩意,主要的方式有两种: 1、使用com组件...

我们都知道现在的语音合成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;
      }
    }
}