1. 程式人生 > >一個基於Windows Vista speech API5.3以及WPF技術的語音朗讀程式碼

一個基於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);        }

            //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,我給大家發