SpeakProgressEventArgs.CharacterPosition Property

Gets the number of characters and spaces from the beginning of the prompt to the position before the first letter of the word that was just spoken.

Namespace:  Microsoft.Speech.Synthesis
Assembly:  Microsoft.Speech (in Microsoft.Speech.dll)

public int CharacterPosition { get; internal set; }

Property Value

Type: System.Int32
Returns the number of characters and spaces from the beginning of the prompt to the position before the first letter of the word that was just spoken.

The CharacterPosition includes the count for characters in XML tags, including their enclosing brackets. When using any of the AppendText(), AppendTextWithAlias(String, String), AppendTextWithHint(), AppendSsmlMarkup(String), or AppendTextWithPronunciation(String, String) methods, the contents are added to an SSML prompt that includes the opening and closing speak elements. The opening speak element adds an offset of 82 characters and spaces to the CharacterPosition of the all the words and letters in the prompt. For example, in the following snippet, the CharacterPosition of the first word, “this”, is 82.

builder.AppendText("This is a test");
Synthesizer.Speak(builder);

In the above example the CharacterPosition of the word “test” is 92. In the following snippet the CharacterPosition of the word “test” is ten characters higher (102) because the opening <emphasis> tag that precedes it contains ten characters.

builder.AppendSsmlMarkup("This is a <emphasis>test</emphasis>");
Synthesizer.Speak(builder);

When you use the AppendSsml(XmlReader) method to add content to a prompt by specifying a file, the opening xml declaration and speak elements in the file are not used or counted. The first character in the file after the opening speak tag will be at position 82 if it is the first content in the prompt.

By contrast, the string parameter of a Speak(String) method does not get added to an SSML prompt before being spoken. Therefore, the CharacterPosition of the first word, “this”, in the following snippet is zero.

Synthesizer.Speak(“This is a test.”);

The SpeechSynthesizer normalizes numbers to the words that correspond to how the number will be spoken. For example, the synthesizer speaks the number “4003” as “four thousand three”. It raises a SpeakProgress event for each of the three spoken words. However, the CharacterPosition property for each of the three words is the same. It is the position before the first character of the number “4003” in the text of the prompt.

The following example creates a PromptBuilder and appends the SSML contents of an XML file using XmlReader. The example outputs speech to a WAV file for playback. The contents of the XML file containing the SSML appear below the code example.

using System;
using System.Xml;
using System.IO;
using Microsoft.Speech.Synthesis;

namespace SampleSynthesis
{
  class Program
  {
    static void Main(string[] args)
    {

      // Initialize a new instance of the SpeechSynthesizer.
      using (SpeechSynthesizer synth = new SpeechSynthesizer())
      {

        // Configure the audio output. 
        synth.SetOutputToWaveFile(@"C:\test\weather.wav");

        // Create a SoundPlayer instance to play the output audio file.
        System.Media.SoundPlayer m_SoundPlayer =
          new System.Media.SoundPlayer(@"C:\test\weather.wav");

        // Create a path to the file that contains SSML.
        string weatherFile = Path.GetFullPath("c:\\test\\Weather.xml");
        
        // Create an XML Reader from the file, create a PromptBuilder and 
        // append the XmlReader.
        PromptBuilder builder = null;

        if (File.Exists(weatherFile))
        {
          XmlReader reader = XmlReader.Create(weatherFile);
          builder = new PromptBuilder();
          builder.AppendSsml(reader);
          reader.Close();
        }

        // Add a handler for the SpeakProgress event.
        synth.SpeakProgress += 
          new EventHandler<SpeakProgressEventArgs>(synth_SpeakProgress);

        // Speak the prompt and play back the output file.
        synth.Speak(builder);
        m_SoundPlayer.Play();
      }

      Console.WriteLine();
      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
    }

    // Write each word and its character position to the console.
    static void synth_SpeakProgress(object sender, SpeakProgressEventArgs e)
    {
      Console.WriteLine("Speak progress: {0} {1}",
        e.CharacterPosition, e.Text);
    }
  }
}

<!-- The following are the contents of the file Weather.xml. 
Note that because of the <p> tag and the space that follows it, 
that the character position of the first word "The" will be 86. -->

<?xml version="1.0" encoding="ISO-8859-1"?>
<speak version="1.0"
 xmlns="http://www.w3.org/2001/10/synthesis"
 xml:lang="en-US">

  <p> The weather forecast for today is partly cloudy with 
some sun breaks. </p>

  <break strength="medium" />

  <p> Tonight's weather will be cloudy with a 30% chance of 
showers. </p>

</speak>

Show: