Unlocking Cortana's Voice (Eva) for use in a UWP app

Microsoft first introduced the world to Cortana, an intelligent virtual personal assistant, with Windows Phone 8.1. A year later, Cortana's now on Windows 10 but only in a select number of countries. Why? Likely cause Cortana's text-to-speech (TTS) is region specific and maps to the speech patterns, idioms, and expressive style of each country. As a result, each of these voice fonts are specific to each region. The United Kingdom (en-gb) has Sarah as Cortana's voice, Germany (de-de) has Katja, and here in the United States (en-us) we have Eva. This blog post will go into details of how we can unlock Eva's voice for the Narrator and for a Universal Windows Platform (UWP) app.

Eva

In the US English version of Windows 10, only Mark and Zira voices are accessible; no Eva :(

Don't fret! We can unlock Eva through a couple tweaks:

  1. Download and run the following registry tweaks: https://gist.github.com/jpoon/d926243f19642b04f1a6.
  2. Under C:\Windows\SysWOW64\Speech_OneCore\Common\en-US\tokens_TTS_en-US.xml add a new voice by appending the following XML node, the final version should look like this.
  <Category name="Voices" categoryBase="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore">
    <Token name="MSTTS_V110_enUS_EvaM">
      <String name="" value="Microsoft Eva Mobile - English (United States)" />
      <String name="LangDataPath" value="%windir%\Speech_OneCore\Engines\TTS\en-US\MSTTSLocenUS.dat" />
      <String name="VoicePath" value="%windir%\Speech_OneCore\Engines\TTS\en-US\M1033Eva" />
      <String name="409" value="Microsoft Eva Mobile - English (United States)" />
      <String name="CLSID" value="{179F3D56-1B0B-42B2-A962-59B7EF59FE1B}" />
      <Attribute name="Version" value="11.0" />
      <Attribute name="Language" value="409" />
      <Attribute name="Gender" value="Female" />
      <Attribute name="Age" value="Adult" />
      <Attribute name="DataVersion" value="11.0.2013.1022" />
      <Attribute name="SharedPronunciation" value="" />
      <Attribute name="Name" value="Microsoft Eva Mobile" />
      <Attribute name="Vendor" value="Microsoft" />
      <Attribute name="SampleText" value="You have selected %1 as the default voice." />
    </Token>
  </Category>

That's it. Now, you can use Eva as a system-wide default voice font or select her voice to use in your UWP application.

But how?!

How did I figure out the exact registry entries and the files to be modified?

Cue Process Monitor, a tool in the SysInternals suite made by one of my tech idols, Mark Russinovich (props to a colleague for introducing me to the tool). Process Monitor shows "real-time file system, Registry and process/thread activity".

The plan is to build a simple UWP app that would iterate through the installed voices.

public MainPage()  
{
    foreach (var voice in SpeechSynthesizer.AllVoices)
    {
        Debug.WriteLine(voice.DisplayName);
    }
}

While running the app, use Process Monitor to record all the registry and file access by the process and sift through all the operations to find the needle in the haystack.

After filtering to display information only for the UWP process, and analyzing each registry/file access, I came upon an operation

ReadFile: C:\Windows\SysWOW64\Speech_OneCore\Common\en-US\tokens_TTS_en-US.xml

which looked promising considering:

  • TTS means text-to-speech
  • XML file extension generally indicates a manifest of some sort
  • It's under a folder named "Speech_OneCore" which looks highly relevant
  • en-US is the local machines current locale

Modified the file, tested it by re-running the basic UWP app, and BOOM! We are in business!