<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Rob's Rhapsody : Development</title><link>http://blogs.msdn.com/robch/archive/tags/Development/default.aspx</link><description>Tags: Development</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Speech Server 2007 Resources</title><link>http://blogs.msdn.com/robch/archive/2008/10/08/speech-server-2007-resources.aspx</link><pubDate>Wed, 08 Oct 2008 17:30:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8991394</guid><dc:creator>robch</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/robch/comments/8991394.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=8991394</wfw:commentRss><description>&lt;p&gt;If you want to start developing on Speech Server 2007, you should probably start off using the Speech Server 2007 Developer Edition &amp;#8211; a free, yet fully functional version of the retail product. You can download it &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=BB183640-4B8F-4828-80C9-E83C3B2E7A2C&amp;amp;displaylang=en"&gt;here&lt;/a&gt;. Please be sure to follow the steps in the &lt;a href="http://download.microsoft.com/download/5/2/3/523a4587-f065-47a4-8df9-dd6f429f3497/Release%20Notes.htm"&gt;Installation Notes&lt;/a&gt; exactly, otherwise the installation may fail.&lt;/p&gt;  &lt;p&gt;The Developer Edition is &lt;em&gt;only &lt;/em&gt;free for &lt;em&gt;developing &lt;/em&gt;your application. You'll still need to purchase Office Communications Server 2007 licenses once&amp;#160; you're ready to &lt;em&gt;deploy &lt;/em&gt;your application in a non-test deployment. You can read more about&amp;#160; Speech Server Licensing &lt;a href="http://gotspeech.net/blogs/michaeldunn/archive/2007/08/20/speech-server-2007-pricing-revealed.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Speech Server 2007 works with Visual Studio 2005 &lt;u&gt;not&lt;/u&gt; Visual Studio 2008. After installing Speech Server 2007, you'll also need to install a patch for a bug that occurs when you have .NET 3.0 SP1 or Vista SP1. You can download that patch &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=4D8B068B-3C45-4EEA-BBC8-C4A4C4201F60&amp;amp;displaylang=en"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;For support, you can use the Speech Server 2007 Community Support forums &lt;a href="http://forums.microsoft.com/unifiedcommunications/default.aspx?siteid=57"&gt;here&lt;/a&gt;. For bugs, please file the bug in the ECS-UC-Dev queue, or under OCS 2007.&lt;/p&gt;  &lt;p&gt;Documentation is found &lt;a href="http://go.microsoft.com/fwlink/?LinkId=103827 "&gt;here&lt;/a&gt;. White papers can be found &lt;a href="http://msdn.microsoft.com/ocdev"&gt;here&lt;/a&gt; under the technical articles section. For example, &lt;a href="http://download.microsoft.com/download/a/4/4/a441d741-ff76-40b2-8f7c-c1b799fd94f0/Capacity%20planning%20for%20OCS%20Speech%20Server%202007%20Deployments.docx"&gt;here&lt;/a&gt; is a white paper on capacity planning.&lt;/p&gt;  &lt;p&gt;The Speech Server (2007) MOM pack can be found &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=55d30337-8e50-4d63-9410-870be4839183&amp;amp;DisplayLang=en"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Books:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.amazon.com/Pro-Microsoft-Speech-Server-2007/dp/1590599020"&gt;Pro Microsoft Speech Server 2007: Developing Speech Enabled Applications with .NET&lt;/a&gt; - walks intermediate to advanced developers through the basics of speech and telephony technology&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/mspress/books/10482.aspx"&gt;Office Communication Server 2007 Resource Kit&lt;/a&gt; - reference for deploying, configuring, and supporting Office Communications Server 2007&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Additional web resources: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://gotspeech.net"&gt;http://gotspeech.net&lt;/a&gt; - useful site for Speech Server application development&lt;/li&gt;    &lt;li&gt;&lt;a href="http://gotspeech.net/elearning"&gt;http://gotspeech.net/elearning&lt;/a&gt; - The official Speech Server training&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8991394" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Applications/default.aspx">Speech Applications</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category></item><item><title>Speech Macro of the Day: Speech Dictionary</title><link>http://blogs.msdn.com/robch/archive/2008/08/02/speech-macro-of-the-day-speech-dictionary.aspx</link><pubDate>Sun, 03 Aug 2008 01:06:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8808773</guid><dc:creator>robch</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robch/comments/8808773.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=8808773</wfw:commentRss><description>&lt;p&gt;I get feedback from people, from time to time, that they'd like a more efficient way to add items to their speech dictionary. Although, there is a facility in Windows Speech Recognition already to do this, it's one word at a time, and it only allows you to record the pronunciation, not specify it yourself. &lt;/p&gt;  &lt;p&gt;So ... What do I do when I have request like this? I make a new macro of the day. Thus, today's speech macro of the day: Speech Dictionary.wsrMac&lt;/p&gt;  &lt;p&gt;First, if we're going to be messing around with the speech dictionary, it might be nice to see what's already in it... To do that, I made a command where I can say &amp;quot;Export the speech dictionary&amp;quot;, and it'll export all the words/phrases that have been customized into a text file, and then launch that text file for me to take a look at. Here's the command:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;Export ?the speech dictionary&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fileName = &amp;quot;dictionary.txt&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set lexToken = CreateObject(&amp;quot;SAPI.SpObjectToken&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lexToken.SetId(&amp;quot;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Speech\CurrentUserLexicon&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set lex = lexToken.CreateInstance()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set words = lex.GetWords(1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set file = fso.CreateTextFile(fileName, 1) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For Each word in words     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (word.LangId = 1033) Then &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set prons = word.Pronunciations     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If prons.Count = 0 Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Write word.Word &amp;amp; vbCrLf&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For Each pron in prons      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Write word.Word &amp;amp; &amp;quot;/&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If pron.PartOfSpeech = 61440 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Write &amp;quot;BLOCKED&amp;quot; &amp;amp; vbCrLf      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Write pron.Symbolic &amp;amp; vbCrLf      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Close      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.Run(fileName)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/script&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/command&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As you can see, it uses a bunch of speech APIs that are already in Vista, that any application can take advantage of. The first 7 lines opens up the speech dictionary (aka User Lexicon), and also opens up a file (dictionary.txt) to stick the words in in a more human readable format. &lt;/p&gt;  &lt;p&gt;Then, for each word that it finds, it checks the language, and if it's 1033 (which means US English), it'll output the word into the file. But to do that, it needs to see how many pronunciations are available for each word. If there are zero, it'll just output the word. If there are more than one, it'll output one line per pronunciation. &lt;/p&gt;  &lt;p&gt;There's also a special case, where if the part of speech is &amp;quot;61440&amp;quot;, it outputs the word &amp;quot;BLOCKED&amp;quot;. &amp;quot;61440&amp;quot; is a special kind of part of speech that the underlying speech platform uses to tell the underlying speech engine, this word should be blocked and not recognized at any time. The &amp;quot;BLOCKED&amp;quot; convention is just one I made up for this macro. &lt;/p&gt;  &lt;p&gt;After looping thru all the words, it'll close the file, and launch the text file that was created. &lt;/p&gt;  &lt;p&gt;Here's a sample of what my speech dictionary looks like when I say &amp;quot;Export the speech dictionary&amp;quot;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Ima/BLOCKED     &lt;br /&gt;im/BLOCKED      &lt;br /&gt;Visual Studio/v ih zh uw l s t uw d iy ow      &lt;br /&gt;antidisestablishmentarianism/ae n t ay d ih s ih s t ae b l ih sh m ax n t eh r iy ax n ih z ax m      &lt;br /&gt;Rob Chambers      &lt;br /&gt;Itamar/ih d ae m aa r      &lt;br /&gt;Itamar/ih t ae m aa r      &lt;br /&gt;Zac Chambers      &lt;br /&gt;Nic Chambers      &lt;br /&gt;Bec Chambers      &lt;br /&gt;Jac Chambers&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The first few I've pasted here are words that the system has learned thru adaptation that I don't actually want it to use. Sometimes when I say &amp;quot;I am a GPM at Microsoft&amp;quot;, it thinks I'm saying Ima or im. Thus... The first time I saw that happen, I selected Ima, and blocked it from my dictionary. More on that in a second...&lt;/p&gt;  &lt;p&gt;Then, you can see for Visual Studio, I've actually got a full pronunciation listed. I probably don't have to, but it's here to show you that you can either have pronunciations listed, or not. Having it added as a single unit, ensures that when I say it, it'll always be cased properly. &lt;/p&gt;  &lt;p&gt;The next word, &amp;quot;antidisestablishmentarianism&amp;quot;, is one of the longest words in the English language, but it's not included in the speech dictionary by default. My son, Zac, loves this word, so of course I have to have it in my speech dictionary. &lt;/p&gt;  &lt;p&gt;Next, you can see my name is listed with no pronunciation. Since both my first and last name are also common words, I've added my name here as a single unit, so when I say &amp;quot;Rob Chambers&amp;quot;, I again get the proper casing. &lt;/p&gt;  &lt;p&gt;Next up, is Itamar, pronounced two different ways. One with a &amp;quot;d&amp;quot; sound and one with a &amp;quot;t&amp;quot; sound. This way, no matter how I end up saying it in a hurry, I can speak Itamar's name properly in email communication with Itamar. BTW ... If you don't know Itamar, you should check out his ms-speech forum on Yahoo! Groups. It's a great place to learn more about Microsoft Speech and speech recognition in general. &lt;/p&gt;  &lt;p&gt;Next up are the names of my kids. I have 4 boys, and they have short forms of more traditional names for their first names, so that their initials actually are the same as their first names. I played a bit too many video games as a kid, and RLC wasn't that cool for initials, compared with other kids in my neighborhood. My kids initials are the same as their names. It throws their teachers for a loop at first, but ... Well ... What can I say... I like it. So do they.&lt;/p&gt;  &lt;p&gt;OK, now that I've described the lines, let's talk about the format of the pronunciations for a minute. These pronunciations are an attempt at human readable form, but using the exact same form as the underlying speech platform. That brings me to the next command, &amp;quot;Show phonemes&amp;quot;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;listenFor&amp;gt;Show phonemes&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;run command=&amp;quot;&lt;a href="http://msdn.microsoft.com/en-us/library/ms717239(VS.85).aspx"/"&gt;http://msdn.microsoft.com/en-us/library/ms717239(VS.85).aspx&amp;quot;/&lt;/a&gt;&amp;gt;      &lt;br /&gt;&amp;lt;/command&amp;gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Say it, and it'll take you to the page on MSDN that describes what the American English Phoneme Representation is for the Speech API.&lt;/p&gt;  &lt;p&gt;OK, now we're getting to the fun part. Now, let's say you wanted to add a new word. The command I'm about to show you, will let you say &amp;quot;Add that to the speech dictionary&amp;quot;, and it'll copy whatever word is selected in your document (using the Windows clipboard), and add it to the speech dictionary with no specific pronunciation. &lt;/p&gt;  &lt;p&gt;When I originally wrote this set of commands, I had 4 different commands. One for adding words, one for removing words, one for blocking them, and one for unblocking them. I quickly saw that they were all identical, so I made one command that can do any one of those 4 operations. Here's what it looks like with it's helper listenForList:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;listenFor&amp;gt;[operationPhrase] ?for that ?from ?to the speech dictionary&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;setTextFeedback&amp;gt;Speech Dictionary: {[operationPhrase]}&amp;lt;/setTextFeedback&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Get the &amp;quot;that&amp;quot; text from the curent application...      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.SendKeys(&amp;quot;{250 WAIT}{{CTRL}}c{250 WAIT}&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; that = Application.clipboardData.GetData(&amp;quot;text&amp;quot;) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Determine if we're adding prons, adding phrases, remove phrases, or blocking phrases     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; operation = &amp;quot;{[operation]}&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' If we're adding a pron, we'll need to use the recognizer, otherwise we'll just need the lexicon&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set recognizer = CreateObject(&amp;quot;SAPI.SpSharedRecognizer&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set lexToken = CreateObject(&amp;quot;SAPI.SpObjectToken&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lexToken.SetId(&amp;quot;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Speech\CurrentUserLexicon&amp;quot;) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set lex = lexToken.CreateInstance()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Keep track of how many words/phrases we added, and loop thru the lines in the &amp;quot;that&amp;quot;...      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cWords = 0      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lineStartPos = 1      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Do &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Find the next line break     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lineSeperatorPos = InStr(lineStartPos, that, Chr(10))      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (lineSeperatorPos = 0) Then lineSeperatorPos = Len(that) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Find the text for that line     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; thisLine = Mid(that, lineStartPos, lineSeperatorPos - lineStartPos + 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lineStartPos = lineStartPos + Len(thisLine) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Trim off the CR/LF     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Right(thisLine, 1) = Chr(10)) Then thisLine = Left(thisLine, Len(thisLine) - 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Right(thisLine, 1) = Chr(13)) Then thisLine = Left(thisLine, Len(thisLine) - 1) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' If we have something to operate on     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (Len(Trim(thisLine)) &amp;gt; 0) Then &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Determine if there's a pronuncation included     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pronSeperatorPos = InStr(thisLine, &amp;quot;/&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (pronSeperatorPos = 0) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Perform the operation with no pronuncation      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then Call recognizer.DisplayUI(65552, thisLine, &amp;quot;AddRemoveWord&amp;quot;, thisLine)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;add&amp;quot; Then Call lex.AddPronunciation(thisLine, 1033, 0)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;remove&amp;quot; Then Call lex.RemovePronunciation(thisLine, 1033, 0)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;block&amp;quot; Then Call lex.AddPronunciation(thisLine, 1033, 61440)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Find the pronuncation and collapse it      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; word = Left(thisLine, pronSeperatorPos - 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = Right(thisLine, Len(thisLine) - pronSeperatorPos)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = CollapsePron(pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Special case the &amp;quot;BLOCKED&amp;quot; pronuncation      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; partOfSpeech = 0      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If pron=&amp;quot;BLOCKED&amp;quot; Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; partOfSpeech = 61440      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = &amp;quot;&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Perform the operation with the pronuncation (and just continue if there's an error)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; On Error Resume Next&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then Call recognizer.DisplayUI(65552, word, &amp;quot;AddRemoveWord&amp;quot;, word)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;add&amp;quot; Then Call lex.AddPronunciation(word, 1033, partOfSpeech, pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;remove&amp;quot; Then Call lex.RemovePronunciation(word, 1033, partOfSpeech, pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;block&amp;quot; Then Call lex.AddPronunciation(word, 1033, 61440, pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; On Error Goto 0&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cWords = cWords + 1 &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Loop while lineStartPos &amp;lt; Len(that) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Tell the user what we did...     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (cWords = 1) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then Call Application.Alert(&amp;quot;Added pronunciation for &amp;quot; &amp;amp; Chr(34) &amp;amp; thisLine &amp;amp; Chr(34) &amp;amp; &amp;quot;!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 2)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;add&amp;quot; Then Call Application.Alert(&amp;quot;Added &amp;quot; &amp;amp; Chr(34) &amp;amp; thisLine &amp;amp; Chr(34) &amp;amp; &amp;quot;!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 2)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;remove&amp;quot; Then Call Application.Alert(&amp;quot;Removed &amp;quot; &amp;amp; Chr(34) &amp;amp; thisLine &amp;amp; Chr(34) &amp;amp; &amp;quot;!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 2)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;block&amp;quot; Then Call Application.Alert(&amp;quot;Blocked &amp;quot; &amp;amp; Chr(34) &amp;amp; thisLine &amp;amp; Chr(34) &amp;amp; &amp;quot;!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 2)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then Call Application.Alert(&amp;quot;Added pronunciations for &amp;quot; &amp;amp; cWords &amp;amp; &amp;quot; words/phrases!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;add&amp;quot; Then Call Application.Alert(&amp;quot;Added &amp;quot; &amp;amp; cWords &amp;amp; &amp;quot; words/phrases!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;remove&amp;quot; Then Call Application.Alert(&amp;quot;Removed &amp;quot; &amp;amp; cWords &amp;amp; &amp;quot; words/phrases!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;block&amp;quot; Then Call Application.Alert(&amp;quot;Blocked &amp;quot; &amp;amp; cWords &amp;amp; &amp;quot; words/phrases!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Function CollapsePron(pron) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ret = &amp;quot;&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; insideBrackets = vbFalse      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For i = 1 to Len(pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (Not insideBrackets) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (Mid(pron, i, 1) = &amp;quot;[&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; insideBrackets = vbTrue      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ElseIf (Mid(pron, i, 1) &amp;lt;&amp;gt; &amp;quot;/&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ret = ret &amp;amp; Mid(pron, i, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ElseIf (Mid(pron, i, 1) = &amp;quot;]&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; insideBrackets = vbFalse      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CollapsePron = ret      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Function      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/script&amp;gt;      &lt;br /&gt;&amp;lt;/command&amp;gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;listenForList name=&amp;quot;operationPhrase&amp;quot; propname=&amp;quot;operation&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;item propval=&amp;quot;addpron&amp;quot;&amp;gt;Add ?a pronunciation&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;item propval=&amp;quot;addpron&amp;quot;&amp;gt;Add ?a pron&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;item propval=&amp;quot;add&amp;quot;&amp;gt;Add&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;item propval=&amp;quot;remove&amp;quot;&amp;gt;Remove&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;item propval=&amp;quot;block&amp;quot;&amp;gt;Block&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;item propval=&amp;quot;remove&amp;quot;&amp;gt;Unblock&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;lt;/listenForList&amp;gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I'll leave the details on the specifics for an exercise for the readers. As a user of the macro, though, you can now say things like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;Add a pronunciation for that from the speech dictionary&amp;quot;,     &lt;br /&gt;&amp;quot;Add that to the speech dictionary&amp;quot;,      &lt;br /&gt;&amp;quot;Remove that from the speech dictionary&amp;quot;,      &lt;br /&gt;&amp;quot;Block that from the speech dictionary&amp;quot;, and      &lt;br /&gt;&amp;quot;Unblock that from the speech dictionary&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Your selection will have to be a single word/phrase, or multiple&amp;#160; words/phrases separated by line breaks. The word/phrases can also have a trailing pronunciation, similar in form to what you see in the output from &amp;quot;Export the speech dictionary&amp;quot;.&lt;/p&gt;  &lt;p&gt;&amp;quot;OK, but how can I generate those pronunciations myself?&amp;quot; Good question!&lt;/p&gt;  &lt;p&gt;Use this command:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;listenFor&amp;gt;Sounds like [...]&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;listenFor&amp;gt;Insert sounds like [...]&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[ &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.SetTextFeedback(&amp;quot;Sounds like...&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set pc = CreateObject(&amp;quot;SAPI.SpPhoneConverter&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pc.LanguageId = 1033 &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = &amp;quot;/&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; firstElement = Result.PhraseInfo.Properties.Item(0).FirstElement      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; numberOfElements = Result.PhraseInfo.Properties.Item(0).NumberOfElements &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For i = 1 To numberOfElements     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set elem = Result.PhraseInfo.Elements.Item(firstElement + i - 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = pron &amp;amp; &amp;quot;[&amp;quot; &amp;amp; elem.LexicalForm &amp;amp; &amp;quot;]&amp;quot; &amp;amp; &amp;quot;/&amp;quot; &amp;amp; pc.IdToPhone(elem.Pronunciation) &amp;amp; &amp;quot; &amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.Wait(0.25)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.SetTextFeedback(&amp;quot;Sounds like: &amp;quot; &amp;amp; pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.InsertText(pron) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;/script&amp;gt;      &lt;br /&gt;&amp;lt;/command&amp;gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will use dictation to allow you to say &amp;quot;Sounds like Visual Studio&amp;quot;, and it'll output /[visual]/v ih zh uw l /[studio]/s t uw d iy ow. So, if you have a word that you're trying to add, you can use the built in pronunciations of other words that WSR already knows about, to cut and paste together your own pronunciation. &lt;/p&gt;  &lt;p&gt;Another way to do it would be to select the word of phrase you wanted to build a pronunciation for, and saying &amp;quot;What's that sound like?&amp;quot;, which is the final command we'll put into this macro:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;listenFor&amp;gt;What's that sound like&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;listenFor&amp;gt;What does that sound like&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[ &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.SendKeys(&amp;quot;{250 WAIT}{{CTRL}}c{250 WAIT}&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; that = Application.clipboardData.GetData(&amp;quot;text&amp;quot;) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.EmulateRecognition(&amp;quot;Go after that&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.EmulateRecognition(&amp;quot;Insert sounds like &amp;quot; &amp;amp; that) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;/script&amp;gt;      &lt;br /&gt;&amp;lt;/command&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That will copy the selection, move right after it, and then pretend you actually said it. For many words/phrases, this will work even if Windows Speech Recognition doesn't really know how to pronounce the word/phrase, because the system will make it's best guess on how to pronounce it just like it would if you were trying to click on that word on a web page with your voice. &lt;/p&gt;  &lt;p&gt;OK ... Now here's another command that will make your phrases a little shorter if you're actually using the commands inside Notepad.exe with the dictionary.txt file open:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;appIsInForeground processName=&amp;quot;notepad.exe&amp;quot; windowTitleContains=&amp;quot;dictionary.txt&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;listenFor&amp;gt;[operationPhrase] ?for that&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;emulateRecognition&amp;gt;{[operationPhrase]} that the speech dictionary&amp;lt;/emulateRecognition&amp;gt;      &lt;br /&gt;&amp;lt;/command&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This basically only works when notepad is in focus, and it's editing dictionary.txt (as it would be when you've just said &amp;quot;Export the speech dictionary&amp;quot;. This will enable you to say simpler commands like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;Add a pronunciation for that&amp;quot;,     &lt;br /&gt;&amp;quot;Add that&amp;quot;,      &lt;br /&gt;&amp;quot;Remove that&amp;quot;,      &lt;br /&gt;&amp;quot;Block that&amp;quot;, and      &lt;br /&gt;&amp;quot;Unblock that&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Here's the macro in complete form:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;speechMacros&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;lt;!-- &lt;/p&gt;    &lt;p&gt;NOTE #1: The magic number 1033 represent en-us      &lt;br /&gt;NOTE #2: The magic number 6552 is a special hack to represent the desktop window handle (Validated on XP, and Vista)      &lt;br /&gt;NOTE #3: The magic number 61440 means that this &amp;quot;word/phrase&amp;quot; should be blocked &lt;/p&gt;    &lt;p&gt;--&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;command&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;[operationPhrase] ?for that ?from ?to the speech dictionary&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;setTextFeedback&amp;gt;Speech Dictionary: {[operationPhrase]}&amp;lt;/setTextFeedback&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Get the &amp;quot;that&amp;quot; text from the curent application...      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.SendKeys(&amp;quot;{250 WAIT}{{CTRL}}c{250 WAIT}&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; that = Application.clipboardData.GetData(&amp;quot;text&amp;quot;) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Determine if we're adding prons, adding phrases, remove phrases, or blocking phrases     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; operation = &amp;quot;{[operation]}&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' If we're adding a pron, we'll need to use the recognizer, otherwise we'll just need the lexicon&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set recognizer = CreateObject(&amp;quot;SAPI.SpSharedRecognizer&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set lexToken = CreateObject(&amp;quot;SAPI.SpObjectToken&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lexToken.SetId(&amp;quot;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Speech\CurrentUserLexicon&amp;quot;) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set lex = lexToken.CreateInstance()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Keep track of how many words/phrases we added, and loop thru the lines in the &amp;quot;that&amp;quot;...      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cWords = 0      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lineStartPos = 1      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Do &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Find the next line break     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lineSeperatorPos = InStr(lineStartPos, that, Chr(10))      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (lineSeperatorPos = 0) Then lineSeperatorPos = Len(that) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Find the text for that line     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; thisLine = Mid(that, lineStartPos, lineSeperatorPos - lineStartPos + 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lineStartPos = lineStartPos + Len(thisLine) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Trim off the CR/LF     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Right(thisLine, 1) = Chr(10)) Then thisLine = Left(thisLine, Len(thisLine) - 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Right(thisLine, 1) = Chr(13)) Then thisLine = Left(thisLine, Len(thisLine) - 1) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' If we have something to operate on     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (Len(Trim(thisLine)) &amp;gt; 0) Then &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Determine if there's a pronuncation included     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pronSeperatorPos = InStr(thisLine, &amp;quot;/&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (pronSeperatorPos = 0) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Perform the operation with no pronuncation      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then Call recognizer.DisplayUI(65552, thisLine, &amp;quot;AddRemoveWord&amp;quot;, thisLine)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;add&amp;quot; Then Call lex.AddPronunciation(thisLine, 1033, 0)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;remove&amp;quot; Then Call lex.RemovePronunciation(thisLine, 1033, 0)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;block&amp;quot; Then Call lex.AddPronunciation(thisLine, 1033, 61440)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Find the pronuncation and collapse it      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; word = Left(thisLine, pronSeperatorPos - 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = Right(thisLine, Len(thisLine) - pronSeperatorPos)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = CollapsePron(pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Special case the &amp;quot;BLOCKED&amp;quot; pronuncation      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; partOfSpeech = 0      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If pron=&amp;quot;BLOCKED&amp;quot; Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; partOfSpeech = 61440      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = &amp;quot;&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Perform the operation with the pronuncation (and just continue if there's an error)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; On Error Resume Next&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then Call recognizer.DisplayUI(65552, word, &amp;quot;AddRemoveWord&amp;quot;, word)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;add&amp;quot; Then Call lex.AddPronunciation(word, 1033, partOfSpeech, pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;remove&amp;quot; Then Call lex.RemovePronunciation(word, 1033, partOfSpeech, pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;block&amp;quot; Then Call lex.AddPronunciation(word, 1033, 61440, pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; On Error Goto 0&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cWords = cWords + 1 &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Loop while lineStartPos &amp;lt; Len(that) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' Tell the user what we did...     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (cWords = 1) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then Call Application.Alert(&amp;quot;Added pronunciation for &amp;quot; &amp;amp; Chr(34) &amp;amp; thisLine &amp;amp; Chr(34) &amp;amp; &amp;quot;!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 2)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;add&amp;quot; Then Call Application.Alert(&amp;quot;Added &amp;quot; &amp;amp; Chr(34) &amp;amp; thisLine &amp;amp; Chr(34) &amp;amp; &amp;quot;!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 2)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;remove&amp;quot; Then Call Application.Alert(&amp;quot;Removed &amp;quot; &amp;amp; Chr(34) &amp;amp; thisLine &amp;amp; Chr(34) &amp;amp; &amp;quot;!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 2)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;block&amp;quot; Then Call Application.Alert(&amp;quot;Blocked &amp;quot; &amp;amp; Chr(34) &amp;amp; thisLine &amp;amp; Chr(34) &amp;amp; &amp;quot;!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 2)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;addpron&amp;quot; Then Call Application.Alert(&amp;quot;Added pronunciations for &amp;quot; &amp;amp; cWords &amp;amp; &amp;quot; words/phrases!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;add&amp;quot; Then Call Application.Alert(&amp;quot;Added &amp;quot; &amp;amp; cWords &amp;amp; &amp;quot; words/phrases!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;remove&amp;quot; Then Call Application.Alert(&amp;quot;Removed &amp;quot; &amp;amp; cWords &amp;amp; &amp;quot; words/phrases!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If operation = &amp;quot;block&amp;quot; Then Call Application.Alert(&amp;quot;Blocked &amp;quot; &amp;amp; cWords &amp;amp; &amp;quot; words/phrases!&amp;quot;, &amp;quot;Speech Dictionary&amp;quot;, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Function CollapsePron(pron) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ret = &amp;quot;&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; insideBrackets = vbFalse      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For i = 1 to Len(pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (Not insideBrackets) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (Mid(pron, i, 1) = &amp;quot;[&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; insideBrackets = vbTrue      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ElseIf (Mid(pron, i, 1) &amp;lt;&amp;gt; &amp;quot;/&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ret = ret &amp;amp; Mid(pron, i, 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ElseIf (Mid(pron, i, 1) = &amp;quot;]&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; insideBrackets = vbFalse      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CollapsePron = ret      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Function      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/script&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/command&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;#160; &amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;Export ?the speech dictionary&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fileName = &amp;quot;dictionary.txt&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set lexToken = CreateObject(&amp;quot;SAPI.SpObjectToken&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lexToken.SetId(&amp;quot;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Speech\CurrentUserLexicon&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set lex = lexToken.CreateInstance()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set words = lex.GetWords(1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set file = fso.CreateTextFile(fileName, 1) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For Each word in words     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If (word.LangId = 1033) Then &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set prons = word.Pronunciations     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If prons.Count = 0 Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Write word.Word &amp;amp; vbCrLf&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For Each pron in prons      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Write word.Word &amp;amp; &amp;quot;/&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If pron.PartOfSpeech = 61440 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Write &amp;quot;BLOCKED&amp;quot; &amp;amp; vbCrLf      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Write pron.Symbolic &amp;amp; vbCrLf      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.Close      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.Run(fileName)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/script&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/command&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;#160; &amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;Sounds like [...]&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;Insert sounds like [...]&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[ &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.SetTextFeedback(&amp;quot;Sounds like...&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set pc = CreateObject(&amp;quot;SAPI.SpPhoneConverter&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pc.LanguageId = 1033 &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = &amp;quot;/&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; firstElement = Result.PhraseInfo.Properties.Item(0).FirstElement      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; numberOfElements = Result.PhraseInfo.Properties.Item(0).NumberOfElements &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For i = 1 To numberOfElements     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set elem = Result.PhraseInfo.Elements.Item(firstElement + i - 1)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pron = pron &amp;amp; &amp;quot;[&amp;quot; &amp;amp; elem.LexicalForm &amp;amp; &amp;quot;]&amp;quot; &amp;amp; &amp;quot;/&amp;quot; &amp;amp; pc.IdToPhone(elem.Pronunciation) &amp;amp; &amp;quot; &amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.Wait(0.25)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.SetTextFeedback(&amp;quot;Sounds like: &amp;quot; &amp;amp; pron)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.InsertText(pron) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/script&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/command&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;#160; &amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;What's that sound like&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;What does that sound like&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;![CDATA[ &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.SendKeys(&amp;quot;{250 WAIT}{{CTRL}}c{250 WAIT}&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; that = Application.clipboardData.GetData(&amp;quot;text&amp;quot;) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.EmulateRecognition(&amp;quot;Go after that&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Application.EmulateRecognition(&amp;quot;Insert sounds like &amp;quot; &amp;amp; that) &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ]]&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/script&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/command&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;#160; &amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;Show phonemes&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;run command=&amp;quot;&lt;a href="http://msdn.microsoft.com/en-us/library/ms717239(VS.85).aspx"/"&gt;http://msdn.microsoft.com/en-us/library/ms717239(VS.85).aspx&amp;quot;/&lt;/a&gt;&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/command&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;#160; &amp;lt;command&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;appIsInForeground processName=&amp;quot;notepad.exe&amp;quot; windowTitleContains=&amp;quot;dictionary.txt&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;listenFor&amp;gt;[operationPhrase] ?for that&amp;lt;/listenFor&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;emulateRecognition&amp;gt;{[operationPhrase]} that the speech dictionary&amp;lt;/emulateRecognition&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/command&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;#160; &amp;lt;listenForList name=&amp;quot;operationPhrase&amp;quot; propname=&amp;quot;operation&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;item propval=&amp;quot;addpron&amp;quot;&amp;gt;Add ?a pronunciation&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;item propval=&amp;quot;addpron&amp;quot;&amp;gt;Add ?a pron&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;item propval=&amp;quot;add&amp;quot;&amp;gt;Add&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;item propval=&amp;quot;remove&amp;quot;&amp;gt;Remove&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;item propval=&amp;quot;block&amp;quot;&amp;gt;Block&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;item propval=&amp;quot;remove&amp;quot;&amp;gt;Unblock&amp;lt;/item&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/listenForList&amp;gt; &lt;/p&gt;    &lt;p&gt;&amp;lt;/speechMacros&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That's it! I know this is a lot of script to digest, but if you don't really want to, don't! Just use the macro as is. Questions? Comments? &lt;a href="mailto:listen@microsoft.com?subject=Macro of the day: Speech Dictionary"&gt;Let us know&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8808773" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/robch/archive/tags/Macros/default.aspx">Macros</category></item><item><title>Windows Speech Recognition - ExactMatchOverPartialMatch</title><link>http://blogs.msdn.com/robch/archive/2007/05/07/windows-speech-recognition-exactmatchoverpartialmatch.aspx</link><pubDate>Mon, 07 May 2007 17:57:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2464291</guid><dc:creator>robch</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/robch/comments/2464291.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=2464291</wfw:commentRss><description>&lt;p&gt;A user wrote in over the weekend with a question about how to automatically choose an item when prompted with our clarification user interface in Windows Speech Recognition (WSR). But ... Before I answer that question, I have to give a little background.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;What is our clarification user interface?&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;When the recognizer hears the user say something ambiguous and we're not sure what to do, the system will ask the user for clarification (or confirmation). For example, if the user says "File" in an application that both has a "File" menu and a button somewhere that has the word "File" in it (like a toolbar button that is for creating&amp;nbsp;a "New File"), little numbers will fly out and hover over the two items on the screen. The user can then choose, "1", or "2", and then the user can say "OK". &lt;/p&gt; &lt;p&gt;This is related to the feature that David Pogue &lt;a href="http://blogs.msdn.com/robch/archive/2007/01/02/wsr-s-in-david-pogue-s-top-10-list.aspx"&gt;wrote up&lt;/a&gt; as one of 2006's top 10 features of the year. That feature treats everything as ambiguous when the user says "Show Numbers". &lt;/p&gt; &lt;p&gt;There is another form of the clarification user interface, as well, that we use for items that don't have an on screen representation, like applications to start. In this example, if the user says "Start Internet Explorer", the system sees that there are two possible matches, "Internet Explorer" and "Internet Explorer (no add-ins)". Since we're not 100% sure which one the user wanted, we'll ask the user to clarify. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;How do I make it automatically pick?&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Well, in general, we can't automatically pick the right one because we still haven't perfected "brain wave recognition" yet. :-) But ... Seriously, though ... You can make it better.&lt;/p&gt; &lt;p&gt;There's a feature called ExactMatchOverPartialMatch. It's turned off by default, but you can turn it on by changing a value in the registry. If you're not comfortable changing the registry, don't do this. But if you are, here you go:&lt;/p&gt; &lt;p&gt;key = HKEY_CURRENT_USER\Software\Microsoft\Speech\Preferences&lt;br&gt;value name = ExactMatchOverPartialMatch&lt;br&gt;value type = DWORD&lt;br&gt;value = 1 (default is 0)&lt;/p&gt; &lt;p&gt;After changing this registry setting, you'll have to restart speech. Once that's done, now in the two examples I gave earlier ("File", and "Start Internet Explorer") no clarification user interface will be displayed, because there will be one and only one exact match. "File" == "File", and "Internet Explorer"=="Internet Explorer". &lt;/p&gt; &lt;p&gt;ExactMatchOverPartialMatch wont' solve all your problems, but it will make the system better for a lot of people. Try it out. &lt;a href="mailto:listen@microsoft.com?subject=ExactMatchOverPartialMatch"&gt;Let us know&lt;/a&gt; what you think. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2464291" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Features/default.aspx">Features</category><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/robch/archive/tags/Q_2600_amp_3B00_A/default.aspx">Q&amp;amp;A</category></item><item><title>Introducing a new speech recognition blogger</title><link>http://blogs.msdn.com/robch/archive/2007/05/04/introducing-a-new-speech-recognition-blogger.aspx</link><pubDate>Fri, 04 May 2007 20:15:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2412356</guid><dc:creator>robch</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robch/comments/2412356.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=2412356</wfw:commentRss><description>&lt;p&gt;If you've used Windows Speech Recognition in Windows Vista you've undoubtedly used Eric Brown's work. He's a software developer that's worked on speech tirelessly for several years. He's mostly focused on the dilatation system we have in Windows Speech Recognition, but he's also done several other cool things as well like our "How do I &amp;lt;blah blah blah&amp;gt;" help system integration.&lt;/p&gt; &lt;p&gt;If you want to know more about how dictation in Windows Speech Recognition works (more from a developer perspective) or how other applications can be dictation enabled you should head over to Eric's new blog: &lt;a href="http://blogs.msdn.com/tsfaware"&gt;TSFAware&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2412356" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category></item><item><title>SpeechSaver -- kinda like a screen saver, but for speech recognition's listening state</title><link>http://blogs.msdn.com/robch/archive/2007/04/28/speechsaver-kinda-like-a-screen-saver-but-for-speech-recognition-s-listening-state.aspx</link><pubDate>Sat, 28 Apr 2007 20:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2313826</guid><dc:creator>robch</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robch/comments/2313826.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=2313826</wfw:commentRss><description>&lt;P&gt;I was talking to a customer recently, Greg Duncan, and one of the things that he came up was an idea for a utility to automatically turn the speech recognition engine's state off after a certain amount of idle "speech" time. &lt;/P&gt;
&lt;P&gt;A couple emails later, this morning, Greg had already posted the full source code and a link to an installer for &lt;A class="" href="http://www.codeplex.com/speechsaver/Release/ProjectReleases.aspx?ReleaseId=3822" mce_href="http://www.codeplex.com/speechsaver/Release/ProjectReleases.aspx?ReleaseId=3822"&gt;SpeechSaver&lt;/A&gt;&amp;nbsp;on his &lt;A class="" href="http://coolthingoftheday.blogspot.com/" mce_href="http://coolthingoftheday.blogspot.com/"&gt;blog&lt;/A&gt;. I downloaded it, installed it, and checked it out. It does exactly what it's supposed to. &lt;/P&gt;
&lt;P&gt;Nice job, Greg.&lt;/P&gt;
&lt;P&gt;If you want a solution that automatically turns the microphone off after a set period of time of inactivity, you might want to check it out.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2313826" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Applications/default.aspx">Speech Applications</category><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/robch/archive/tags/Q_2600_amp_3B00_A/default.aspx">Q&amp;amp;A</category></item><item><title>SpeechTEK 2007 in NY</title><link>http://blogs.msdn.com/robch/archive/2007/04/24/speechtek-2007-in-ny.aspx</link><pubDate>Tue, 24 Apr 2007 17:36:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2260805</guid><dc:creator>robch</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robch/comments/2260805.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=2260805</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://www.speechtek.com"&gt;SpeechTEK&lt;/a&gt; is always an interesting convention for those that are interested in speech technologies. I often go to see what the industry at large is up to, and to see if I can meet some customers. &lt;/p&gt; &lt;p&gt;This year, in addition to just attending, I'll also be teaching&amp;nbsp; a session at SpeechTEK University, which is held on site at the same time. I'll be teaching STKU-6: Developing Applications Using System.Speech and SAPI on Windows Vista. &lt;/p&gt; &lt;p&gt;Here's the description of the course from the &lt;a href="http://www.speechtek.com/East2007/SpeechTEK2007_AdvanceProgram.pdf"&gt;SpeechTEK Program Guide&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;Developing Applications Using System.Speech and SAPI on Windows Vista&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Rob Chambers, Principal Development Lead and Architect, Microsoft)&lt;/p&gt; &lt;p&gt;Thursday, August 23rd, 2007, 1:30 p.m. – 4:30 p.m.&lt;/p&gt; &lt;p&gt;Speech recognition and speech synthesis have come a long way at Microsoft in the past 10 years. The evolution of the developer APIs, the included TTS and SR engines, and the integrated user experiences in Windows Vista will have a profound impact on the availability of Windows applications in the future. In this course, you will learn about both SAPI and System.Speech in a hands-on lab setting (bring your own laptop). Attendees with either COM and C++ experience or managed code developers with C# experience will experience Microsoft speech offerings for the desktop firsthand. (Attendees will receive hardware specs and resources to download in advance.)&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;If you've ever wanted to learn first hand how to use the developer APIs included for free with Windows Vista, feel free to sign up to SpeechTEK University this year. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2260805" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category></item><item><title>Windows Speech Recognition in Vista: Dictation Everywhere</title><link>http://blogs.msdn.com/robch/archive/2007/04/23/windows-speech-recognition-in-vista-dictation-everywhere.aspx</link><pubDate>Mon, 23 Apr 2007 17:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2247038</guid><dc:creator>robch</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/robch/comments/2247038.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=2247038</wfw:commentRss><description>&lt;P&gt;Here's a question from a reader about the Dictation Everywhere feature in Windows Speech Recognition in Windows Vista:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;This feature is thus very important to me and my future as a PC user. 
&lt;P&gt;I have found that in many form fields (such as the one I'm using to send this message) dictation is impossible unless I switch to "Enable dictation everywhere" (otherwise I get "what was that?" messages). There is no short command for switching, and even in that mode I have to confirm every fragment of text I dictate with "one, ok." And then I have to switch out of that mode again for navigation. 
&lt;P&gt;It is very important to me that I find ways around this, or at least that a way around it will soon exist. Would you be so kind as to let me know how I can stay up to date with Vista SR improvements, and whom I can contact about its development? 
&lt;P&gt;Thank you very much for your time; I really appreciate your efforts to communicate to the public about Vista SR.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now, for those of you that don't already know, Windows Speech Recognition allows users to dictate into any text field that supports a few &lt;A href="http://blogs.msdn.com/robch/archive/2005/08/08/448992.aspx" mce_href="http://blogs.msdn.com/robch/archive/2005/08/08/448992.aspx"&gt;standard platform APIs&lt;/A&gt;. These APIs (Application Programming Interfaces) are used by the speech recognition system, the handwriting recognition system, and input method editors for foreign languages. 
&lt;P&gt;However, some text fields in custom applications don't support what's needed. In those cases Windows Speech Recognition has a fall back input method. It's called Dictation Everywhere. You can turn it on by doing this: 
&lt;UL&gt;
&lt;LI&gt;Say, "Show Speech Options" 
&lt;LI&gt;Say, "Options" 
&lt;LI&gt;Say, "Dictation Everywhere"&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;That will toggle it on. Doing those three steps again will turn it off. 
&lt;P&gt;When Dictation Everywhere is turned on, we'll listen for the user to speak dictated text, even when they're not in an text field that doesn't support those APIs I mentioned. But ... Because the field doesn't support the right APIs, instead of just sticking the text in there, we're going to have a miniature correction experience with the user first. Otherwise, the user wouldn't be able to correct the text if there was a recognition error. 
&lt;P&gt;So ... If you're in one of those fields, use the three steps above to turn on dictation, then you can say, "Hello &amp;lt;period&amp;gt; This is a test &amp;lt;period&amp;gt;". The correction dialog will pop up and allow you to pick an alternative from the list. If you don't see what you really said, simple say it again. If you still don't see what you said, you can say "Spell it", and spell what you wanted. 
&lt;P&gt;This is the feature that the user was asking about. They'd like to be able to turn the command on and off easily by using a single voice command. 
&lt;P&gt;Unfortunately, since we don't have an end user feature either included directly into Vista at this time, nor do we offer one for download (yet!) for creating macros, end users can't really simulate the same impact of turning this feature on and off with a single voice command. 
&lt;P&gt;At least not easily... 
&lt;P&gt;If you're a programmer (or don't mind dabbling), you certainly could though. In fact, you can create a simple shell script that does this like this: 
&lt;BLOCKQUOTE&gt;
&lt;P&gt;set Recognizer = CreateObject("SAPI.SpSharedRecognizer") 
&lt;P&gt;Recognizer.EmulateRecognition ("show speech options")&lt;BR&gt;WScript.Sleep(1000)&lt;BR&gt;Recognizer.EmulateRecognition ("options")&lt;BR&gt;WScript.Sleep(1000)&lt;BR&gt;Recognizer.EmulateRecognition ("dictation everywhere") 
&lt;P&gt;set Recognizer = Nothing&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;When you run this it will connect to the shared recognizer that Windows Speech Recognition uses, it will pretend that the user spoke "show speech options", then wait for 1 second, then pretend that the user said "options", again wait for another 1 second, then again, pretend the user said "dictation everywhere". 
&lt;P&gt;In fact, you can even save this text as a file called "Dictation Everywhere Toggle.vbs" in your start folder (e.g. "c:\documents and settings\{your user name goes here}\start menu\dictation everywhere toggle.vbs") and you'll be able to say to Windows Speech Recognition, "Start Dictation Everywhere Toggle". &lt;/P&gt;
&lt;P&gt;Unfortunately, for all this to work, you actually have to turn &lt;A class="" href="http://blogs.msdn.com/robch/archive/2006/10/20/windows-speech-recognition-and-user-access-control.aspx" mce_href="http://blogs.msdn.com/robch/archive/2006/10/20/windows-speech-recognition-and-user-access-control.aspx"&gt;Access Control (UAC) off&lt;/A&gt;. Otherwise, the shell script can't communicate with the shared recognizer.&lt;/P&gt;
&lt;P&gt;In the future, though, we'll have a true end to end macro facility to deal with this in a secure way. Stay tuned for more info on that front... &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2247038" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Features/default.aspx">Features</category><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/robch/archive/tags/Q_2600_amp_3B00_A/default.aspx">Q&amp;amp;A</category></item><item><title>Keeping speech grammars up-to-date</title><link>http://blogs.msdn.com/robch/archive/2007/03/29/keeping-speech-grammars-up-to-date.aspx</link><pubDate>Thu, 29 Mar 2007 20:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1989586</guid><dc:creator>robch</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/robch/comments/1989586.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=1989586</wfw:commentRss><description>&lt;P&gt;I've been having a good conversation with some guys that are working on making it easier to program by voice using Python. Their project is called "&lt;A class="" href="http://tech.groups.yahoo.com/group/voicecoder/" mce_href="http://tech.groups.yahoo.com/group/voicecoder/"&gt;VoiceCode&lt;/A&gt;" and they've been working on it for quite some time. Currently it only supports Dragon NaturallySpeaking as a speech recognizer, but I'm helping them to understand how easy it would be to port to Vista. &lt;/P&gt;
&lt;P&gt;One issue that came up recently was: How can they keep their grammars up to date if their grammars change based on what application is running, or what the title is in any given application. I was trying to describe to them in email how they could use the &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/ms696160.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms696160.aspx"&gt;SetWinEventHook&lt;/A&gt; method, but I wasn't being as successful describing it to them as I wanted to... So ... I just wrote about 500 lines of code for them to show them.&lt;/P&gt;
&lt;P&gt;Then, I thought ... Hey, other people might want to see how to do this too. So I posted the code &lt;A class="" href="http://files.wsrguy.com/samples/Win32/ForegroundAppMonitor/ForegroundAppMonitor.cpp" mce_href="http://files.wsrguy.com/samples/Win32/ForegroundAppMonitor/ForegroundAppMonitor.cpp"&gt;here&lt;/A&gt;. Let me know if you have any questions!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1989586" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/robch/archive/tags/Q_2600_amp_3B00_A/default.aspx">Q&amp;amp;A</category></item><item><title>Visual Studio 2005 Service Pack 1 Update for Windows Vista</title><link>http://blogs.msdn.com/robch/archive/2007/03/07/visual-studio-2005-service-pack-1-update-for-windows-vista.aspx</link><pubDate>Wed, 07 Mar 2007 19:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1829038</guid><dc:creator>robch</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robch/comments/1829038.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=1829038</wfw:commentRss><description>&lt;P&gt;I know a lot of developers that have been waiting for this one. Yesterday, Microsoft announced the availability of &lt;A class="" href="http://blogs.msdn.com/ControlPanel/Blogs/Visual%20Studio%202005%20Service%20Pack%201%20Update%20for%20Windows%20Vista" mce_href="http://blogs.msdn.com/ControlPanel/Blogs/Visual Studio 2005 Service Pack 1 Update for Windows Vista"&gt;Visual Studio 2005 Service Pack 1 Update for Windows Vista&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;I've been using a prerelease version for some time and it's great. If you are a developer and you haven't downloaded it already, you might want to stop what you're doing and do it now!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1829038" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category></item><item><title>Installing additional speech recognizer languages...</title><link>http://blogs.msdn.com/robch/archive/2007/02/20/installing-additional-speech-recognizer-languages.aspx</link><pubDate>Tue, 20 Feb 2007 18:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1727273</guid><dc:creator>robch</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robch/comments/1727273.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=1727273</wfw:commentRss><description>&lt;P&gt;Here's a question that I get from time to time...&lt;/P&gt;
&lt;P&gt;Q: How do I install speech recognition for a language other than the language Windows Vista is running in?&lt;/P&gt;
&lt;P&gt;A: By installing a language pack. &lt;/P&gt;
&lt;P&gt;Language packs are &lt;EM&gt;the&lt;/EM&gt; Windows way of installing additional language support for features included in the OS. By default, when you install Windows Vista (or purchase a PC with Windows Vista already on it), it comes with a single language. &lt;/P&gt;
&lt;P&gt;In Windows Vista Enterprise and Windows Vista Ultimate, you can go to the control panel, search for "display language", and then click on the "Install or uninstall display languages" link.&lt;/P&gt;
&lt;P&gt;Follow the on-screen instructions, and in no time you'll have additional recognizer languages as long as it's a Windows Speech Recognition supported language. In Windows Vista we support&amp;nbsp;US English, UK English, German, French, Spanish, Japanese, Simplified Chinese, and Traditional Chinese.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1727273" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/robch/archive/tags/Q_2600_amp_3B00_A/default.aspx">Q&amp;amp;A</category></item><item><title>Transfering profiles programatically</title><link>http://blogs.msdn.com/robch/archive/2007/02/19/transfering-profiles-programatically.aspx</link><pubDate>Tue, 20 Feb 2007 08:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1722570</guid><dc:creator>robch</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robch/comments/1722570.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=1722570</wfw:commentRss><description>&lt;P&gt;Last week I wrote about how to &lt;A class="" href="http://blogs.msdn.com/robch/archive/2007/02/15/transferring-windows-speech-recognition-profiles-from-one-machine-to-another.aspx" mce_href="http://blogs.msdn.com/robch/archive/2007/02/15/transferring-windows-speech-recognition-profiles-from-one-machine-to-another.aspx"&gt;transfer profiles using the Easy Transfer Wizard&lt;/A&gt;. That generated some email and some questions in the community about how to do this programmatically.&lt;/P&gt;
&lt;P&gt;That's a good question. But unfortunately, the answer isn't that straight forward currently. &lt;/P&gt;
&lt;P&gt;In the &lt;A class="" href="http://blogs.msdn.com/robch/archive/2007/02/13/windows-speech-recognition-where-s-the-api-documentation.aspx" mce_href="http://blogs.msdn.com/robch/archive/2007/02/13/windows-speech-recognition-where-s-the-api-documentation.aspx"&gt;SAPI documentation&lt;/A&gt;&amp;nbsp;you can read about how some of this works, but there's not a single overview of how all this works. So ... I'll try to summarize how it works here.&lt;/P&gt;
&lt;P&gt;Here goes ...&lt;/P&gt;
&lt;P&gt;In SAPI, recognition profiles are accessed by the engine (and by the application) using the &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/ms720150.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms720150.aspx"&gt;Resource interfaces&amp;nbsp;of SAPI&lt;/A&gt;. Specifically, the ISpObjectTokenCategory, IEnumSpObjectTokens, ISpObjectToken, and ISpDataKey interfaces. &lt;/P&gt;
&lt;P&gt;To get a list of recognition profiles configured by the user you can use the &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/ms717535.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms717535.aspx"&gt;SpEnumTokens&lt;/A&gt; helper function (defined in sphelper.h). You'll need to specify the category you want to enumerate. That's the SPCAT_RECOPROFILES category. This will give you an IEnumSpObjectTokens interface, which is a standard derivative of the IEnum* class of interfaces. Using this interface, you can iterate thru the individual "tokens" by calling IEnumSpObjectTokens::Next -- each of the ISpObjectTokens you get back will represent a single recognition profile. &lt;/P&gt;
&lt;P&gt;Given a specific token you can QueryInterface for the ISpObjectToken interface, which derives from ISpDataKey. Then you can ask for the name of the reco profile, by calling &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/aa914233.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa914233.aspx"&gt;ISpDataKey::GetStringValue&lt;/A&gt;(NULL, &amp;amp;pszCoTaskMemAllocedProfileName). Be sure and call CoTaskFree on the string returned when you're done with it.&lt;/P&gt;
&lt;P&gt;To back up the profile, there are no special helpers, so you'll just have to do a few things the hard way. &lt;/P&gt;
&lt;P&gt;First, you should make a backup of the ISpDataKey settings. The easiest way to do this is to use the token's ID to open up the registry location directly. You see, typically the object token is simply a wrapper on top of registry access functions. The token ID is typically actually just nothing more than a path into the registry. For example, for my reco profile that I'm using right now, the token id (retrieved by calling &lt;A class="" href="http://search.msdn.microsoft.com/search/Redirect.aspx?title=ISpObjectToken%3a%3aGetID+(SAPI+5.3)+&amp;amp;url=http://msdn2.microsoft.com/en-gb/library/ms718244.aspx" mce_href="http://search.msdn.microsoft.com/search/Redirect.aspx?title=ISpObjectToken%3a%3aGetID+(SAPI+5.3)+&amp;amp;url=http://msdn2.microsoft.com/en-gb/library/ms718244.aspx"&gt;ISpObjectToken::GetID&lt;/A&gt;) is: "HKEY_CURRENT_USER\Software\Microsoft\Speech\RecoProfiles\Tokens\{90E13428-A7A5-419B-8034-EA6453E31906}"&lt;/P&gt;
&lt;P&gt;So, you'll have to write your own code to iterate thru the registry recursively and back up all the keys and values (with their names) that you find. &lt;/P&gt;
&lt;P&gt;There are a few special things that you have to take into consideration when doing this:&lt;/P&gt;
&lt;P&gt;1.) If the token id doesn't live directly under "HKEY_CURRENT_USER\Software\Microsoft\Speech\RecoProfiles\Tokens\", you shouldn't assume that the procedure I'm describing here will actually work to back up the recognition profile. If you see a token ID outside of this area, you should abort the backup.&lt;/P&gt;
&lt;P&gt;2.) While backing up the profile, you will encounter one or more key names called "Files". Under keys named "Files", the values represent "pointers" to files on disk. You'll have to also back up the files that these "file names" point to. &lt;/P&gt;
&lt;P&gt;3.) These files may start with character sequences that look like "%1c%\". If they do, you can replace the values between the percent signs with the text as returned from SHGetFolderPath. For example, one of that data files in my registry under a "Files" key has a "filename" of "%1c%\Microsoft\Speech\Files\TrainingAudio\SP_E18DB2EFB76A432B97889A3DB7210406.wav". The "%1c%" corresponds to a "real" filename of "C:\Documents and Settings\Rob\Local Settings\Application Data\Microsoft\Speech\Files\TrainingAudio\SP_E18DB2EFB76A432B97889A3DB7210406.wav". Again, you can use SHGetFolderPath with the hex value of 0x1c to get the path of "C:\Documents and Settings\Rob\Local Settings\Application Data" and you can put all this together.&lt;/P&gt;
&lt;P&gt;4.) When you restore the profile, you should take special care to restore files with different new filenames. If you don't, there could be some collisions. You can get a new filename by calling the ISpObjectToken::GetStorageFileName method. &lt;/P&gt;
&lt;P&gt;That's basically it.&lt;/P&gt;
&lt;P&gt;Yeah, I know... It's not necessarily the easiest thing you'll ever do, but it is possible, and this is basically how you do it. Hopefully, we'll be able to release an actual example that shows how a real end to end backup and restore works for profiles in the future. But until then, hopefully this post will illuminate some of the magic behind profile management in SAPI. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1722570" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Customer+Feedback/default.aspx">Customer Feedback</category><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/robch/archive/tags/Q_2600_amp_3B00_A/default.aspx">Q&amp;amp;A</category></item><item><title>Windows Speech Recognition -- Where's the API documentation?!</title><link>http://blogs.msdn.com/robch/archive/2007/02/13/windows-speech-recognition-where-s-the-api-documentation.aspx</link><pubDate>Tue, 13 Feb 2007 22:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1670722</guid><dc:creator>robch</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/robch/comments/1670722.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robch/commentrss.aspx?PostID=1670722</wfw:commentRss><description>&lt;P&gt;I get a lot of email from customers every day. And some days I end up answering the same questions again and again. Don't get me wrong, I love hearing from customers, and I love enabling them to do great things with Microsoft products. &lt;/P&gt;
&lt;P&gt;The real problem isn't that customers ask questions ... it's that&amp;nbsp;the information that they need isn't always easily found. Well ... I'm hopeful that all this blogging is really going to help users. So I'm going to try an experiment and see how it works.&lt;/P&gt;
&lt;P&gt;I'm going to try and start answering customer questions by sending them a link to my blog. If the answer is not already on my blog, I'll put it there, and then send them the freshly coined link... Sound good?&lt;/P&gt;
&lt;P&gt;OK... So what's the first question that I get asked frequently? Well, it's probably not the most common question, but it's one near and dear to my heart as a platforms kind of guy... &lt;/P&gt;
&lt;P&gt;Q: Where can I find Speech API documentation?&lt;/P&gt;
&lt;P&gt;A: On MSDN of course. Try these different locations depending on how you want to call into the speech APIs:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;C# and managed code: &lt;A href="http://msdn2.microsoft.com/en-us/library/system.speech.recognition.aspx"&gt;http://msdn2.microsoft.com/en-us/library/system.speech.recognition.aspx&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;VB and automation clients: &lt;A href="http://msdn2.microsoft.com/en-us/library/ms720592.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms720592.aspx&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;C++ and native code: &lt;A href="http://msdn2.microsoft.com/en-us/library/ms723627.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms723627.aspx&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Do you have a question? Send it in and I'll try to get it answered... &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1670722" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robch/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/robch/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/robch/archive/tags/Q_2600_amp_3B00_A/default.aspx">Q&amp;amp;A</category></item></channel></rss>