`

一个基于Windows Vista speech API5.3以及WPF技术的语音朗读代码

 
阅读更多

闲暇无事,利用window SDK 与vs2008,基于Windows Vista speech API5.3以及WPF技术开发了一套语音朗读的代码,

牛刀小试,

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using System.Collections.ObjectModel;
using System.Xml;

using System.Speech.Synthesis;

namespace speechSynth
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>

public partial class Window1 : System.Windows.Window
{
private SpeechSynthesizer synth;

public Window1()
{
InitializeComponent();

synth = new SpeechSynthesizer();
synth.StateChanged += new EventHandler<StateChangedEventArgs>(synth_StateChanged);
synth.BookmarkReached += new EventHandler<BookmarkReachedEventArgs>(synth_BookmarkReached);
synth.PhonemeReached += new EventHandler<PhonemeReachedEventArgs>(synth_PhonemeReached);
synth.SpeakCompleted += new EventHandler<SpeakCompletedEventArgs>(synth_SpeakCompleted);
synth.SpeakProgress += new EventHandler<SpeakProgressEventArgs>(synth_SpeakProgress);
synth.SpeakStarted += new EventHandler<SpeakStartedEventArgs>(synth_SpeakStarted);
synth.VisemeReached += new EventHandler<VisemeReachedEventArgs>(synth_VisemeReached);
synth.VoiceChange += new EventHandler<VoiceChangeEventArgs>(synth_VoiceChange);

this.btnSpeakText.Click += new RoutedEventHandler(btnSpeakText_Click);
this.btnWavFile.Click += new RoutedEventHandler(btnWavFile_Click);
this.btnVoices.Click += new RoutedEventHandler(btnVoices_Click);
this.btnSpeakSsml.Click += new RoutedEventHandler(btnSpeakSsml_Click);
this.btnPause.Click += new RoutedEventHandler(btnPause_Click);
this.btnResume.Click += new RoutedEventHandler(btnResume_Click);
this.btnPromptBuilder.Click += new RoutedEventHandler(btnPromptBuilder_Click);
this.btnToXml.Click += new RoutedEventHandler(btnToXml_Click);
this.btnSsmlPitch.Click += new RoutedEventHandler(btnSsmlPitch_Click);
this.btnCutIn.Click += new RoutedEventHandler(btnCutIn_Click);

this.sliderRate.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sliderRate_ValueChanged);
this.sliderVolume.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sliderVolume_ValueChanged);
}

void btnCutIn_Click(object sender, RoutedEventArgs e)
{
synth.SpeakAsyncCancelAll(); //stops current async call
synth.SpeakAsync("this is some interrupting text"); //just appends, unless AsyncCancelAll() called first
//synth.Speak("this is some interrupting text"); //does not interrupt async call
}

void btnSsmlPitch_Click(object sender, RoutedEventArgs e)
{
XmlDocument xd = new XmlDocument();
xd.Load("ssmlPitch.xml");
synth.SpeakSsmlAsync(xd.OuterXml);
}

#region SYNTHESIZER_EVENTS
void synth_VoiceChange(object sender, VoiceChangeEventArgs e)
{
System.Diagnostics.Debug.WriteLine("VoiceChange : " + e.Voice.Name);
}

void synth_VisemeReached(object sender, VisemeReachedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("VisemeReached : " + e.Viseme.ToString());
}

void synth_SpeakStarted(object sender, SpeakStartedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("SpeakStarted");
}

void synth_SpeakProgress(object sender, SpeakProgressEventArgs e)
{
System.Diagnostics.Debug.WriteLine("SpeakProgress : " + e.AudioPosition.TotalSeconds.ToString());
}

void synth_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("SpeakCompleted");
}

void synth_PhonemeReached(object sender, PhonemeReachedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("PhonemeReached : " + e.Phoneme.ToString());
}

void synth_BookmarkReached(object sender, BookmarkReachedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("BookmarkReached : " + e.Bookmark);
}

void synth_StateChanged(object sender, StateChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("StateChanged : " + e.State.ToString());
lblState.Content = e.State.ToString();
}
#endregion

void btnToXml_Click(object sender, RoutedEventArgs e)
{
PromptBuilder myPrompt = GetBuiltPrompt();
MessageBox.Show(myPrompt.ToXml());
}

void btnPromptBuilder_Click(object sender, RoutedEventArgs e)
{
PromptBuilder pb = GetBuiltPrompt();

//Now let's get the synthesizer to render this message
//SpeechSynthesizer synth = new SpeechSynthesizer();
synth.SetOutputToDefaultAudioDevice();
synth.SpeakAsync(pb);
}

private PromptBuilder GetBuiltPrompt()
{
//from http://msdn.microsoft.com/msdnmag/issues/06/01/speechinWindowsVista/

//This prompt is quite complicated
//So I'm going to build it first, and then render it.
PromptBuilder myPrompt = new PromptBuilder();

//Start the main speaking style
PromptStyle mainStyle = new PromptStyle();
mainStyle.Rate = PromptRate.Medium;
mainStyle.Volume = PromptVolume.Loud;
myPrompt.StartStyle(mainStyle);

//Alert the listener
myPrompt.AppendAudio(new Uri("file://c://windows//media//notify.wav"), "Attention!");
myPrompt.AppendText("Here are some important messages.");

//Here's the first important message
myPrompt.AppendTextWithPronunciation("WinFX", "wɪnɛfɛks");
myPrompt.AppendText("is a great platform.");

//And the second one
myPrompt.AppendTextWithHint("ASP", SayAs.SpellOut);
myPrompt.AppendText("is an acronym for Active Server Pages. Whereas an ASP is a snake.");

myPrompt.AppendBreak();

//Let's emphasise how important these messages are
PromptStyle interimStyle = new PromptStyle();
interimStyle.Emphasis = PromptEmphasis.Strong;
myPrompt.StartStyle(interimStyle);
myPrompt.AppendText("Please remember these two things.");
myPrompt.EndStyle();

//Then we can revert to the main speaking style
myPrompt.AppendBreak();
myPrompt.AppendText("Thank you");

myPrompt.EndStyle();
return myPrompt;
}

void btnResume_Click(object sender, RoutedEventArgs e)
{
synth.Resume();
}

void btnPause_Click(object sender, RoutedEventArgs e)
{
synth.Pause();
}

void btnSpeakSsml_Click(object sender, RoutedEventArgs e)
{
//http://www.w3.org/TR/speech-synthesis/
synth.SetOutputToDefaultAudioDevice();

//XmlDocument xd = new XmlDocument();
////xd.Load("sampleSSML.xml"); //works
//xd.Load("ssmlPitch.xml"); //works
//synth.SpeakSsmlAsync(xd.OuterXml);

//XmlDocument xd = new XmlDocument();
////xd.Load("sampleSSML.xml"); //TODO doesn't work?
//xd.Load("ssmlPitch.xml"); //TODO doesn't work?
//PromptBuilder pb = new PromptBuilder();
//pb.AppendSsmlMarkup(xd.DocumentElement.OuterXml);
//synth.SpeakAsync(pb);

PromptBuilder pb = new PromptBuilder();
pb.AppendText("blah");
pb.AppendSsml("sampleSSML.xml"); //works
//pb.AppendSsml("ssmlPitch.xml"); //TODO doesn't work
synth.SpeakAsync(pb);
}

void sliderVolume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
synth.Volume = (int)sliderVolume.Value;
}

void sliderRate_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
synth.Rate = (int)sliderRate.Value;
}

void btnVoices_Click(object sender, RoutedEventArgs e)
{
ReadOnlyCollection<InstalledVoice> voices = synth.GetInstalledVoices();
string retVal = String.Empty;
foreach (InstalledVoice iv in voices)
{
retVal += iv.VoiceInfo.Name + "/r/n";
}
MessageBox.Show(retVal);
}

void btnWavFile_Click(object sender, RoutedEventArgs e)
{
synth.SetOutputToWaveFile("spoken.wav");
synth.Speak(GetText());
synth.SetOutputToNull();
MessageBox.Show("done");
}

void btnSpeakText_Click(object sender, RoutedEventArgs e)
{
synth.SetOutputToDefaultAudioDevice();
synth.SpeakAsync(GetText());
}

private string GetText()
{
return txtToSpeak.Text.Trim();
}

}
}

需要的留下Email,我给大家发

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics