C#中调用SAPI实现语音合成的2种方法
我们都知道现在的语音合成TTS是可以通过微软的SAPI实现的,好处我就不多说了,方便而已,因为在微软的操作系统里面就自带了这个玩意,主要的方式有两种:
1、使用COM组件技术,不管是C++,C#,Delphi都能玩的转,开发出来的东西在XP和WIN7都能跑。(要引入SpeechLib,好像在项目上点引用,然后选到系统COM吧,好久没弄,记不清楚了)
2、使用WIN7的windowsapi,其实最终还是调用了SAPI,所以开发出来的东西就只能在WIN7上面跑。
其实不管是哪一种,都是调用SAPI,可能后一种代码比较简单,使用已经安装的TTS引擎,现在一般用NeoSpeech,这个就不解释了,太强大了这个发音。。。
COM组件技术:
publicclassSpeach { privatestaticSpeach_Instance=null; privateSpeechLib.SpVoiceClassvoice=null;//SAPI5.1 privateSpeechLib.SpVoicevoice=null;//SAPI5.4 privateSpeach() { BuildSpeach(); } publicstaticSpeachinstance() { if(_Instance==null) _Instance=newSpeach(); return_Instance; } privatevoidSetChinaVoice() { voice.Voice=voice.GetVoices(string.Empty,string.Empty).Item(0); } privatevoidSetEnglishVoice() { voice.Voice=voice.GetVoices(string.Empty,string.Empty).Item(1); } privatevoidSpeakChina(stringstrSpeak) { SetChinaVoice(); Speak(strSpeak); } privatevoidSpeakEnglishi(stringstrSpeak) { SetEnglishVoice(); Speak(strSpeak); } publicvoidAnalyseSpeak(stringstrSpeak) { intiCbeg=0; intiEbeg=0; boolIsChina=true; for(inti=0;i<strSpeak.Length;i++) { charchr=strSpeak[i]; if(IsChina) { if(chr<=122&&chr>=65) { intiLen=i-iCbeg; stringstrValue=strSpeak.Substring(iCbeg,iLen); SpeakChina(strValue); iEbeg=i; IsChina=false; } } else { if(chr>122||chr<65) { intiLen=i-iEbeg; stringstrValue=strSpeak.Substring(iEbeg,iLen); this.SpeakEnglishi(strValue); iCbeg=i; IsChina=true; } } }//endfor if(IsChina) { intiLen=strSpeak.Length-iCbeg; stringstrValue=strSpeak.Substring(iCbeg,iLen); SpeakChina(strValue); } else { intiLen=strSpeak.Length-iEbeg; stringstrValue=strSpeak.Substring(iEbeg,iLen); SpeakEnglishi(strValue); } } privatevoidBuildSpeach() { if(voice==null) voice=newSpVoiceClass(); } publicintVolume { get { returnvoice.Volume; } set { voice.SetVolume((ushort)(value)); } } publicintRate { get { returnvoice.Rate; } set { voice.SetRate(value); } } privatevoidSpeak(stringstrSpeack) { try { voice.Speak(strSpeack,SpeechVoiceSpeakFlags.SVSFlagsAsync); } catch(Exceptionerr) { throw(newException("发生一个错误:"+err.Message)); } } publicvoidStop() { voice.Speak(string.Empty,SpeechLib.SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak); } publicvoidPause() { voice.Pause(); } publicvoidContinue() { voice.Resume(); } }//endclass
在privateSpeechLib.SpVoiceClassvoice=null;这里,我们定义个一个用来发音的类,并且在第一次调用该类时,对它用BuildSpeach方法进行了初始化。
我们还定义了两个属性Volume和Rate,能够设置音量和语速。
我们知道,SpVoiceClass有一个Speak方法,我们发音主要就是给他传递一个字符串,它负责读出该字符串,如下所示。
privatevoidSpeak(stringstrSpeack) { try { voice.Speak(strSpeack,SpeechVoiceSpeakFlags.SVSFlagsAsync); } catch(Exceptionerr) { throw(newException("发生一个错误:"+err.Message)); } }
第二种使用.NET类库和系统API的代码如下:
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Speech.Synthesis; usingSystem.Speech; namespaceStudyBeta { publicclassSRead { publicSpeechSynthesizersynth;//语音合成对象 publicSRead() { synth=newSpeechSynthesizer(); } publicSRead(intm,intn) { //使用synth设置朗读音量[范围0~100] synth.Volume=m; //使用synth设置朗读频率[范围-10~10] synth.Rate=n; } publicvoidSpeakChina(stringggg) { //SpVoiceVoice=newSpVoice(); synth.SelectVoice("MicrosoftLili"); //Voice.Speak(ggg,SpFlags); synth.SpeakAsync(ggg); //StringspeechPeople=synth.Voice; //使用synth设置朗读音量[范围0~100] //synth.Volume=80; //使用synth设置朗读频率[范围-10~10] //synth.Rate=0; //使用synth合成wav音频文件: //synth.SetOutputToWaveFile(stringpath); } publicvoidSpeakEnglish(stringggg) { //SpVoiceVoice=newSpVoice(); synth.SelectVoice("VWJulie"); synth.Speak(ggg);//ggg为要合成的内容 } publicintm { get { returnsynth.Volume; } set { synth.Volume=value; } } publicintn { get { returnsynth.Rate; } set { synth.Rate=value; } } }