How do I use a lexicon with SpeechSynthesizer?

After a lot of research and pitfalls I can assure you that your assumption is just plain wrong. For some reason System.Speech.Synthesis.SpeechSynthesizer.AddLexicon() adds the lexicon to an internal list, but doesn't use it at all. Seems like nobody tried using it before and this bug went unnoticed.

Microsoft.Speech.Synthesis.SpeechSynthesizer.AddLexicon() (which belongs to the Microsoft Speech SDK) on the other hand works as expected (it passes the lexicon on to the COM object which interprets it as advertised).

Please refer to this guide on how to install the SDK: http://msdn.microsoft.com/en-us/library/hh362873%28v=office.14%29.aspx

Notes:

  • people reported the 64-bit version to cause COM exceptions (because the library does not get installed correctly), I confirmed this on a 64bit Windows 7 machine
    • using the x86 version circumvents the problem
  • be sure to install the runtime before the SDK
  • be sure to also install a runtime language (as adviced on the linked page) as the SDK does not use the default system speech engine

You can use System.Speech.Synthesis.SpeechSynthesizer.SpeakSsml() instead of a lexicon.

This code changes pronunciation of "blue" to "yellow" and "dog" to "fish".

SpeechSynthesizer synth = new SpeechSynthesizer();
string text = "This is a blue dog";
Dictionary<string, string> phonemeDictionary = new Dictionary<string, string> { { "blue", "jelow" }, { "dog", "fyʃ" } };
foreach (var element in phonemeDictionary)
{
   text = text.Replace(element.Key, "<phoneme ph=\"" + element.Value + "\">" + element.Key + "</phoneme>");
}
text = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\">" + text + "</speak>";
synth.SpeakSsml(text);