Exemple #1
0
        internal void Speak(QueuedSpeech utterance, string outputfile)
        {
            if (syn == null)
            {
                return;
            }

            // Got something to say.  Initialize temp file.
            StartSpeech(utterance.voice, outputfile);

            // Play the beep, if there is one.
            if (utterance.beep != BeepType.None)
            {
                pb.StartSentence();
                pb.AppendAudio(BeepNames[(int)utterance.beep]);
                pb.EndSentence();
            }

            // Say who is talking, if we know.
            if (utterance.speaker != null)
            {
                if (utterance.isAction)
                {
                    SayPrompt(utterance.speaker);
                }
                else
                {
                    // Speak the name of the person speaking.  This is done in a neutral,
                    // softer voice, speaking slightly rapidly.
                    SayPrompt(utterance.speaker + ".");
                }
            }

            // Then synthesize the main part of the message.
            SaySegment(utterance);

            // Close the temporary WAV file.
            FinishSpeech();
        }
Exemple #2
0
        /// <summary>
        /// Tell OSX Speech Synthesizer to speak some text.
        /// </summary>
        /// <param name="utterance"></param>
        /// <param name="outputfile"></param>
        internal void Speak(QueuedSpeech utterance, string outputfile)
        {
            string message;

            // Remove any embedded command delimiters.
            string sayThis = Regex.Replace(utterance.message, @"\[\[", "");

            if (utterance.isAction)
            {
                // Action statements are spoken all together.  Such as
                // "/me looks nervous."  The "/me" will have been substituted
                // with the correct name earlier.
                message = utterance.speaker + " " + sayThis;
            }
            else
            {
                // Normal speech has the name spoken quickly and slightly softer.
                message = "[[rate +1.0;volm -10.0]]" +
                          utterance.speaker +
                          "[[rate -1.0;volm +10.0;slnc 200]]" + // 200ms pause after name
                          sayThis;
            }

            syn.SetVoice(utterance.voice.root.Name);

            NSURL fileURL = new NSURL("file://" + outputfile);

            syn.StartSpeakingStringToURL(message, fileURL);

            // Wait for it to finish.  This proceeds at faster than
            // speaking speed because output is to a file.
            // TODO use a callback to detect this.
            while (syn.IsSpeaking)
            {
                Thread.Sleep(200);  // Check 5x per second.
            }
        }
Exemple #3
0
 public void Speak(
     QueuedSpeech utterance,
     string filename)
 {
     synth.Speak(utterance, filename);
 }
Exemple #4
0
        /// <summary>
        /// Synthesize a speech with Festival
        /// </summary>
        /// <param name="utterance"></param>
        /// <param name="outputfile"></param>
        internal void Speak(QueuedSpeech utterance, string outputfile)
        {
            string args;
            // Construct the exact sequence to say in SABLE notation.
            // SABLE is a simple XML syntax for describing how to speak something.
            // First set voice name.
            string message = "<?xml version=\"1.0\"?>\n" +
                             "<!DOCTYPE SABLE PUBLIC \"-//SABLE//DTD SABLE speech mark up//EN\"\n" +
                             "\"Sable.v0_2.dtd\" []>\n" +
                             "<SABLE><SPEAKER NAME=\"" + utterance.voice.root.Name + "\">\n";

            // Then pitch and rate variations on that for more variety.
            if (utterance.voice.pitchModification > 0)
            {
                message += "<PITCH BASE=\"+30%\">";
            }
            else if (utterance.voice.pitchModification < 0)
            {
                message += "<PITCH BASE=\"-30%\">";
            }

            int effectiveSpeed = utterance.voice.rateModification + rateBias;

            if (effectiveSpeed != 0)
            {
                message += "<RATE SPEED=\"" + effectiveSpeed.ToString("+#;-#;0") + "%\">";
            }

            // For an action it all comes out at a constant speed.
            // For chat, the name is said quickly, with a break after it.
            if (utterance.isAction)
            {
                message += utterance.speaker + " ";
            }
            else
            {
                message += "<RATE SPEED=\"+25%\">" + utterance.speaker + " </RATE><BREAK/>\n";
            }

            // Supress any embedded tags which would confuse SABLE.
            message += Regex.Replace(utterance.message, @"[<>]", "") + "\n";

            // Close any modifications, in reverse order.
            if (utterance.voice.rateModification != 0)
            {
                message += "</RATE>";
            }
            if (utterance.voice.pitchModification != 0)
            {
                message += "</PITCH>";
            }

            message += "</SPEAKER></SABLE>\n";

            // Write this to a temporary file.  Filename is the output
            // filename with ".wav" changed to ".sable".
            // TODO talk directly to Festival server.
            string textfilename = Regex.Replace(outputfile, @"\.wav$", ".sable");

            FileStream tstream =
                new FileStream(textfilename, FileMode.Create, FileAccess.Write);

            byte[] msgBytes = ToASCII.GetBytes(message);

            tstream.Write(msgBytes, 0, msgBytes.Length);
            tstream.Close();
//			args = Regex.Replace( ActualArgs, @"%T", textfilename );

            // Put the desired WAV file name in the command.
            args = Regex.Replace(ActualArgs, @"%F", outputfile);

            // Run synthesizer externally
            // TODO Talk directly to the Festival Server on port 1314.
            Process proc = new Process( );

            proc.StartInfo.FileName               = SynthCommand;
            proc.StartInfo.Arguments              = args;
            proc.StartInfo.UseShellExecute        = false;
            proc.StartInfo.RedirectStandardInput  = true;
            proc.StartInfo.RedirectStandardError  = false;
            proc.StartInfo.RedirectStandardOutput = false;

            try
            {
                if (proc.Start( ))
                {
                    // Send the SCHEME command to redirect output back here
                    proc.StandardInput.WriteLine("(tts_return_to_client)");
                    // Send the SCHEME command to voice the SABLE file.
                    proc.StandardInput.WriteLine("(tts \"" + textfilename + "\" 'sable)");
//					proc.StandardInput.WriteLine("(tts_textall \"" + saythis + "\" 'nil)");

                    proc.StandardInput.Close();
                    proc.WaitForExit( );
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine("Festival process error " + e.Message);
                return;
            }

            // All done with the intermediate file.
            File.Delete(textfilename);
        }