Example #1
0
        /// <summary>
        /// Queue up an action to say.
        /// </summary>
        /// <param name="who"></param>
        /// <param name="what"></param>
        /// <param name="where"></param>
        /// <param name="v"></param>
        internal void SayAction(
            string who,
            string what,
            Vector3 where,
            AssignedVoice v,
            bool spatial)
        {
            if (queue == null)
            {
                return;
            }

            QueuedSpeech e = new QueuedSpeech(
                subs.FixExpressions(who),
                subs.FixExpressions(what),
                where, v, true, spatial, BeepType.None);

            lock (queue)
            {
                queue.Enqueue(e);
                Monitor.Pulse(queue);
            }
        }
Example #2
0
        /// <summary>
        /// Say the main part of the message.
        /// </summary>
        /// <param name="utterance"></param>
        private void SaySegment(QueuedSpeech utterance)
        {
            PromptStyle body = new PromptStyle();
            switch (utterance.voice.rateModification)
            {
                case 00: body.Rate = PromptRate.Medium; break;
                case +1: body.Rate = PromptRate.Fast; break;
                case -1: body.Rate = PromptRate.Slow; break;
            }
            switch (utterance.voice.pitchModification)
            {
                case 00: body.Emphasis = PromptEmphasis.Moderate; break;
                case +1: body.Emphasis = PromptEmphasis.Strong; break;
                case -1: body.Emphasis = PromptEmphasis.Reduced; break;
            }

            pb.StartStyle(body);
            pb.StartSentence();
            pb.AppendText(utterance.message);
            pb.EndSentence();
            pb.EndStyle();
        }
Example #3
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();
        }
Example #4
0
 internal void Speak(QueuedSpeech q, string outputfile)
 {
     control.osLayer?.Speak(q, outputfile);
 }
Example #5
0
 public void Speak(
     RadegastSpeech.Talk.QueuedSpeech utterance,
     string filename)
 {
     synth.Speak(utterance, filename);
 }
Example #6
0
 internal void Speak(QueuedSpeech q, string outputfile)
 {
     if (control.osLayer == null) return;
     control.osLayer.Speak(q, outputfile);
 }
Example #7
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);
        }
Example #8
0
        /// <summary>
        /// Queue up an action to say.
        /// </summary>
        /// <param name="who"></param>
        /// <param name="what"></param>
        /// <param name="where"></param>
        /// <param name="v"></param>
        internal void SayAction(
            string who,
            string what,
            Vector3 where,
            AssignedVoice v,
            bool spatial)
        {
            if (queue == null) return;

            QueuedSpeech e = new QueuedSpeech(
                subs.FixExpressions(who),
                subs.FixExpressions(what),
                where, v, true, spatial, BeepType.None);
            lock (queue)
            {
                queue.Enqueue(e);
                Monitor.Pulse(queue);
            }
        }
Example #9
0
        internal void Say(
            string who,
            string what,
            Vector3 where,
            AssignedVoice v,
            bool doRotate,
            BeepType beep)
        {
            if (queue == null) return;

            QueuedSpeech e = new QueuedSpeech(
                subs.FixExpressions(who),
                subs.FixExpressions(what),
                where, v, false, doRotate, beep);

            // Put that on the queue and wake up the background thread.
            lock (queue)
            {
                queue.Enqueue(e);
                Monitor.Pulse(queue);
            }
        }
Example #10
0
        /// <summary>
        /// Say something as a named person or object at a location.
        /// </summary>
        /// <param name="who">Name of person speaking</param>
        /// <param name="what">What they said</param>
        /// <param name="where">Where they were standing when they said it</param>
        /// <param name="v">The voice they use</param>
        internal void Say(
            string who,
            string what,
            Vector3 where,
            AssignedVoice v)
        {
            if (queue == null) return;

            // Create queue entry from the information.
            QueuedSpeech e = new QueuedSpeech(
                subs.FixExpressions(who),
                subs.FixExpressions(what),
                where,
                v,
                false);

            // Put that on the queue and wake up the background thread.
            lock (queue)
            {
                queue.Enqueue(e);
                Monitor.Pulse(queue);
            }
        }
Example #11
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.
            }
        }