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

2021-06-18 10:05

阅读:664

 

闲暇无事,利用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
{
    ///


    /// Interaction logic for Window1.xaml
    ///

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

        public Window1()
        {
            InitializeComponent();

            synth = new SpeechSynthesizer();
            synth.StateChanged += new EventHandler(synth_StateChanged);
            synth.BookmarkReached += new EventHandler(synth_BookmarkReached);
            synth.PhonemeReached += new EventHandler(synth_PhonemeReached);
            synth.SpeakCompleted += new EventHandler(synth_SpeakCompleted);
            synth.SpeakProgress += new EventHandler(synth_SpeakProgress);
            synth.SpeakStarted += new EventHandler(synth_SpeakStarted);
            synth.VisemeReached += new EventHandler(synth_VisemeReached);
            synth.VoiceChange += new EventHandler(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(sliderRate_ValueChanged);
            this.sliderVolume.ValueChanged += new RoutedPropertyChangedEventHandler(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 e)
        {
            synth.Volume = (int)sliderVolume.Value;
        }

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

        void btnVoices_Click(object sender, RoutedEventArgs e)
        {
            ReadOnlyCollection 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,我给大家发


评论


亲,登录后才可以留言!