{"id":6453,"date":"2007-03-20T11:19:00","date_gmt":"2007-03-20T11:19:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/03\/20\/coding-a-euchre-game-part-6-pump-up-the-volume-matt-gertz\/"},"modified":"2024-07-05T14:49:09","modified_gmt":"2024-07-05T21:49:09","slug":"coding-a-euchre-game-part-6-pump-up-the-volume-matt-gertz","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/coding-a-euchre-game-part-6-pump-up-the-volume-matt-gertz\/","title":{"rendered":"Coding a Euchre Game, Part 6:  Pump up the volume (Matt Gertz)"},"content":{"rendered":"<h2><font size=\"5\"><font color=\"#365f91\"><font face=\"Cambria\">Coding a Euchre Game, <span>Part 6:<span>&nbsp; <\/span>Pump up the volume<\/span><\/font><\/font><\/font><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Ever since Commodore first introduced the SID chip to their line of PCs way back in the earlier 80\u2019s, sound has been an important experience in any computer game.<span>&nbsp; <\/span>What\u2019s particularly exciting to me is that audio has caught up to graphics as far as game relevance goes \u2013 I can\u2019t imagine <i>Planescape: Torment<\/i> having the same sort of immersive experience without Mark Morgan\u2019s haunting, searching themes, or <i>Icewind Dale<\/i> messaging the loneliness and weariness of travelling across the ice plains without Jeremy Soules\u2019 amazing harmonies.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Alas, I can\u2019t pretend that I will be walking you through composing a soundtrack for the Euchre game \u2013 you\u2019re on your own for that one (I can\u2019t even play the piano without looking at my fingers \u2013 which is actually the same problem I have with typing, come to think of it).<span>&nbsp; <\/span>Nevertheless, there\u2019s a lot you can do with sound in Visual Basic 2005.<span>&nbsp; <\/span>I\u2019m going to cover two areas:<span>&nbsp; <\/span>sound effects and text-to-speech.<\/font><\/p>\n<h2><font face=\"Cambria\" color=\"#4f81bd\" size=\"4\">Sound Effects<\/font><\/h2>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Recording a sound is fairly simple, and for a card game where the action is fast, the sounds need to be punchy and iconic.<span>&nbsp; <\/span>Overall, I wanted my game to convey that same feeling I get when playing cards with real people, so I identified three types of sounds that I would miss if they weren\u2019t in the game:<\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraphCxSpFirst\"><span><span><font face=\"Calibri\" size=\"3\">&#8211;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">Shuffling the deck<\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font face=\"Calibri\" size=\"3\">&#8211;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">Slapping a card to the table<\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraphCxSpLast\"><span><span><font face=\"Calibri\" size=\"3\">&#8211;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">Some sort of reaction to a good hand or a good game \u2013 applause, for example<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">I dug around in my desk, came up with a microphone, and recorded the first two sounds myself using the Sound Recorder that comes with Windows.<span>&nbsp; <\/span>For the reaction noise, I grabbed three different public domain sounds of applause (soft applause, loud applause, and wild applause) \u2013 of course, if I was going to sell this game, I would have licensed the sounds or recorded my own.<span>&nbsp; <\/span>All of these got stored as WAV files.<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">If you\u2019ve been following along with my previous posts, you\u2019ve probably already guess that the next step is to get the sounds into the resource manager.<span>&nbsp; <\/span>Right-click the project and bring up \u201cProperties,\u201d click the Resource tab, and use the Add Resource-&gt;Add Existing File to bring in the WAV files.<span>&nbsp; <\/span>(To show the audio resources, click the first dropdown in the RM and select \u201cAudio\u201d \u2013 you can play any resource in there by right-clicking it and choosing the appropriate command.)<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Now, let\u2019s start using the sound.<span>&nbsp; <\/span>Fortunately, playing sounds is very easy using the VB2005 My.Computer functionality:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> PlayApplause(<span>ByVal<\/span> level <span>As<\/span> <span>Integer<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Select<\/span> <span>Case<\/span> level<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Case<\/span> 1<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>My<\/span>.Computer.Audio.Play(<span>My<\/span>.Resources.SoundApplauseSoft, _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span>AudioPlayMode.WaitToComplete)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Case<\/span> 2<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span>My<\/span>.Computer.Audio.Play(<span>My<\/span>.Resources.SoundApplauseLoud, _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span>AudioPlayMode.WaitToComplete)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Case<\/span> 3<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>My<\/span>.Computer.Audio.Play(<span>My<\/span>.Resources.SoundApplauseWild, _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span>AudioPlayMode.WaitToComplete)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Select<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Let\u2019s take a<span>&nbsp; <\/span>deeper look at what\u2019s going on here.<span>&nbsp; <\/span>\u201cPlay\u201d is an overloaded method available to you in the My.Computer.Audio namespace which will play sounds immediately for you.<span>&nbsp; <\/span>The first argument is either the name of the sound resource, its location on disk, or a stream; the second argument specifies how the sound plays (foreground, background, or loop in the background).<span>&nbsp; <\/span>In my case, I\u2019ve specified the audio resource directly (using the friend property automatically generated for me by the resource manager).<span>&nbsp; <\/span>I\u2019ve also elected to go with \u201cWaitToComplete\u201d (i.e., foreground) as my play mode, since the sounds are short and thus I\u2019m not worried about the user having to wait a long time for them to finish.<span>&nbsp; <\/span>I also don\u2019t want to drown out the text-to-speech I\u2019ll be implementing later, which could happen if both played at once, so I\u2019ve preferred to block on the applause.<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Using sound is more than just playing the sound, however.<span>&nbsp; <\/span>For example, when I added a shuffling sound to the game, I hard-coded the sound to play three times in a row.<span>&nbsp; <\/span>This ended up being an irritation \u2013 I found myself mocking the sound as it played, because the pattern was the same every time.<span>&nbsp; <\/span>It was a perfectly good sound, but I came to realize that it seemed a bit predictable in its playback.<span>&nbsp; <\/span>Furthermore, playing the shuffle sound three times in a row made it a long time to wait if I decided to close the game or restart it.<span>&nbsp; <\/span>It took a very minor change to make all of this feel more natural to me \u2013 I simply introduced some randomness to the amount of time the cards were shuffled, and then added a message pump beween sounds to facilitate handling any events that might have occurred:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>For<\/span> i = 0 <span>To<\/span> EuchreTable.GenRandomNumber(2) + 1<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>My<\/span>.Computer.Audio.Play(<span>My<\/span>.Resources.SoundShuffleDeck, _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span>AudioPlayMode.WaitToComplete)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; The shuffle sound is long, and so I need to pump <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8216; messages to see if the user closes or restarts<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; the application.<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Application.DoEvents()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span>If<\/span> Exiting = <span>True<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Throw<\/span> <span>New<\/span> EuchreException(<span>&#8220;ExitGame&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> Restarting = <span>True<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Throw<\/span> <span>New<\/span> EuchreException(<span>&#8220;NewGame&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Next<\/span> i<\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">(If you\u2019ll bear with me, I\u2019d like to digress for a moment into the realm of randomness.<span>&nbsp; <\/span>I\u2019ve been asked many times how one generates a random number, what seeds to use, etc, etc..<span>&nbsp; <\/span>For the record, here\u2019s my preferred method for generating a random integer, which comes straight from the MSDN topic on RNGCryptoServiceProvider:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Shared<\/span> <span>Function<\/span> GenRandomNumber(<span>ByVal<\/span> MaxVal <span>As<\/span> <span>Integer<\/span>) _<\/span><\/p>\n<p class=\"MsoNormal\"><span>As<\/span><span> <span>Integer<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Create a byte array to hold the random value.<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> randomNumber(0) <span>As<\/span> <span>Byte<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Create a new instance of the RNGCryptoServiceProvider. <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> Gen <span>As<\/span> <span>New<\/span> Security.Cryptography.RNGCryptoServiceProvider()<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Fill the array with a random value.<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Gen.GetBytes(randomNumber)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Convert the byte to an integer value to make the modulus <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\u2018 operation easier.<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> rand <span>As<\/span> <span>Integer<\/span> = Convert.ToInt32(randomNumber(0))<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Return the random number mod the number<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; of possibilities.<span>&nbsp; <\/span>The possible values are zero-<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; based.<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> rand <span>Mod<\/span> MaxVal<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Function<\/span><\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">I\u2019ve found that most other random number generators are too non-random for me, especially in a card game where the randomness will be asked for a lot.<span>&nbsp; <\/span>It\u2019s probably overkill for this app &#8212; Randomize + Rnd would have worked fine &#8212; but I don\u2019t like multiple ways of doing things, and I know this one will always be nicely random, whatever the application.)<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">I then proceed to add calls to play the varying levels of applause when the user wins a hand or a game, as well as the appropriate sound every time a card as played.&nbsp; My.Computer.Audio makes this all very straightforward.<\/font><\/font><\/span><\/p>\n<h2><span><font size=\"4\"><font color=\"#4f81bd\"><font face=\"Cambria\">Text To Speech<\/font><\/font><\/font><\/span><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Now, if this was a professional-quality game, it\u2019s unlikely that I\u2019d be using text-to-speech in it \u2013 instead, I would hire voice actors to speak any relevant lines.<span>&nbsp; <\/span>However, as neither Patrick Stewart nor James Earl Jones has been returning my calls, I\u2019ll press on valiantly with using TTS.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">The first thing&nbsp;you&#8217;ll need here is the Microsoft Speech SDK, which can be downloaded from <\/font><a href=\"http:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyId=5E86EC97-40A7-453F-B0EE-6583171B4530&amp;displaylang=en\"><font face=\"Calibri\" color=\"#0000ff\" size=\"3\">http:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyId=5E86EC97-40A7-453F-B0EE-6583171B4530&amp;displaylang=en<\/font><\/a><font face=\"Calibri\" size=\"3\">. You need both the SDK itself (SpeechSDK51.exe) and the redistributable package (speechsdk51msm.exe), the latter since you\u2019ll be deploying our game to other machines later on.<span>&nbsp;&nbsp; <\/span>Upon download completion (warning:<span>&nbsp; <\/span>it\u2019s rather a large download), go ahead &amp; launch the downloaded EXEs to install the SDK bits to the appropriate place, and then launch the resulting setup.EXE to install them.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">To actually use the TTS functionality, you&#8217;ll need to add a reference to the Microsoft Speech Object Library.<span>&nbsp; <\/span>To do this, right-click on the project and choose \u201cAdd reference\u2026\u201d<span>&nbsp; <\/span>This will bring up the Add Reference dialog (which might take some time to come up, depending on how many available references are installed on your machine).<span>&nbsp; You <\/span>then click the COM tab and scroll down to the aforementioned library, select it, and click OK.<span>&nbsp; <\/span>(Since this is a COM reference, an interop DLL will be generated for you and tossed into your output directory.)<span>&nbsp; <\/span>You will now be able to use the SpVoice object as a type.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Once the SDK is installed, using the TTS functionality in the Euchre game is pretty easy.<span>&nbsp; <\/span>The machine may have several voices on it, so&nbsp;I&#8217;ve given the user the ability to pick a voice for each player.<span>&nbsp; <\/span>On my game options dialog (one of my few modal dialogs \u2013 I\u2019ve attached a picture of it to this post), I\u2019ve added three combo boxes which allow the user to select a voice for each AI player, and I just need to populate those combo box dropdowns:<\/font><\/p>\n<p class=\"MsoNormal\"><span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Try<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Voice = <span>New<\/span> SpVoice<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Catch<\/span> ex <span>As<\/span> Exception<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Try<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.LeftVoiceCombo.Enabled = <span>False<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.PartnerVoiceCombo.Enabled = <span>False<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.RightVoiceCombo.Enabled = <span>False<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> Voice <span>IsNot<\/span> <span>Nothing<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> Voices <span>As<\/span> ISpeechObjectTokens = Voice.GetVoices()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> NumberOfVoices <span>As<\/span> <span>Integer<\/span> = Voices.Count<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> Voices.Count &gt; 0 <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>For<\/span> i <span>As<\/span> <span>Integer<\/span> = 0 <span>To<\/span> Voices.Count &#8211; 1<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> s <span>As<\/span> <span>String<\/span> = Voices.Item(i).GetDescription<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.LeftVoiceCombo.Items.Add(s)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.PartnerVoiceCombo.Items.Add(s)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.RightVoiceCombo.Items.Add(s)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Next<\/span> i<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.LeftVoiceCombo.Enabled = <span>True<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.PartnerVoiceCombo.Enabled = <span>True<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Me<\/span>.RightVoiceCombo.Enabled = <span>True<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">where Voice is a member of the options dialog class defined as follows:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> Voice <span>As<\/span> SpVoice = <span>Nothing<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Note that I\u2019ve guarded against the case where the user has uninstalled voice capabilities by wrapping the SpVoice creation in a try-catch block.<span>&nbsp; <\/span>(I won\u2019t throw up an error or anything, since not having a voice doesn\u2019t make the game useless \u2013 I just disable the combo boxes in such a case so that the user can\u2019t choose a voice.) <\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">The voice descriptions I\u2019ve added to the combo boxes read something like \u201cMicrosoft Mary,\u201d \u201cMicrosoft Sam,\u201d etc., and although that\u2019ll help the user remember which voice he\/she prefers in the future, it would also be useful to let the user hear the voice when selecting it to make sure it\u2019s the desired one.<span>&nbsp; <\/span>So, here\u2019s where we add the first code that actually says a string.<span>&nbsp; <\/span>I\u2019ll create an event handler for each dropdown to handle when the dropdown is closed (i.e., when a selection is made):<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> LeftVoiceCombo_DropDownClosed(<span>ByVal<\/span> sender <span>As<\/span> <span>Object<\/span>, _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span><span>ByVal<\/span> e <span>As<\/span> System.EventArgs) _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span>Handles<\/span><span> LeftVoiceCombo.DropDownClosed<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Speak(<span>Me<\/span>.LeftVoiceCombo.SelectedIndex)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">where Speak is a private method on the options dialog class coded thusly:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> Speak(<span>ByVal<\/span> VoiceIndex <span>As<\/span> <span>Integer<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> Voice <span>IsNot<\/span> <span>Nothing<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> Voices <span>As<\/span> ISpeechObjectTokens = Voice.GetVoices()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Voice.Voice = Voices.Item(VoiceIndex)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Voice.Speak(<span>My<\/span>.Resources.SAY_LetsPlayEuchre)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">And SAY_LetsPlayEuche is just a string reference in my resource manager which has the value \u201c<strong>lets play euchre<\/strong>.\u201d<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">The speech engine is actually pretty darn clever \u2013 given an English string resource, it can usually puzzle out how to say the word; thus, I didn\u2019t even need to spell euchre as \u201cyooker\u201d to get the right pronunciation.<span>&nbsp; <\/span>(Note that the Japanese and Chinese speech engines can also be downloaded.) It also pays attention to punctuation, so that things like commas, question marks, and exclamation marks cause the appropriate pauses or emphasis to happen during speech.<span>&nbsp; <\/span>There\u2019s even something that TTS can do that a voice actor wouldn\u2019t be able to \u2013 it can personalize the speech.<span>&nbsp; <\/span>Thus, when the player wins the game, I can have the partner congratulate him or her by using the string \u201c<strong>great game {0}!<span>&nbsp; <\/span>shall we play again?<\/strong>\u201d \u2013 I just use String.Format to replace the <strong>{0}<\/strong> with the player\u2019s name (there are edit boxes for each player\u2019s name on the options dialog) before calling Voice.Speak.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Since each AI player in the game will now have a distinct voice, and since I don\u2019t want to have to keep changing the voice all of the time to match the current player, I\u2019ll design a EuchreSpeech class (right-click the project, choose \u201cAdd\\Class\u2026\u201d etc.), an instance of which will be owned by each AI player.<span>&nbsp; <\/span>Each EuchreSpeech instance needs an actual voice, so I need to create an SpVoice object for each one.<span>&nbsp; <\/span>The code is very similar to that of the options dialog, except that I already know which voice I want: <\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Sub<\/span> SetVoice(<span>ByVal<\/span> VoiceIndex <span>As<\/span> <span>Integer<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Try<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Voice = <span>New<\/span> SpVoice<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Catch<\/span> ex <span>As<\/span> Exception<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Try<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> Voice <span>IsNot<\/span> <span>Nothing<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> Voices <span>As<\/span> ISpeechObjectTokens = Voice.GetVoices()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> NumberOfVoices <span>As<\/span> <span>Integer<\/span> = Voices.Count<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> Voices.Count &gt; 0 <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>VoiceToUse = VoiceIndex<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Voice.Voice = Voices.Item(VoiceToUse)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Else<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Voice = <span>Nothing<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">where VoiceIndex is the index of the voice I got from the options dialog for this player.<span>&nbsp; <\/span>(I could have had the options dialog pass voice references directly to the EuchreVoice objects, but it only has one voice shared by all of the combo boxes.<span>&nbsp; <\/span>I suppose I could have created three actual voices, but I didn\u2019t want to get carried away with voice creation or have some sort of dual-ownership of a voice, and iterating the voices is fairly cheap anyway.) Note that I don\u2019t call this code in the constructor for the player.<span>&nbsp; <\/span>This is because I don\u2019t destroy the EuchrePlayer\/EuchreSpeech objects between the games (which would be wasteful), but I do give the user the option to change voices and other options between games, and so this code needs to be separate from the constructor.<span>&nbsp; <\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Since the voice is already known for each player, the code which causes a player to say something is very simple \u2013 here\u2019s the functions called when an AI player wishes to pass:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216; Called by the BidFirstRound in EuchreTable for a given player<\/span><span><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>Public<\/span><span> <span>Sub<\/span> SpeakPass(<span>ByVal<\/span> seat <span>As<\/span> EuchrePlayer.Seats)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> seat &lt;&gt; EuchrePlayer.Seats.Player <span>And<\/span> SoundOn = <span>True<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8216; EVoice is the EuchreSpeech member of EuchrePlayer<\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Players(seat).ESpeech.SayPass()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216; Members of EuchreSpeech (the ESpeech from above)<\/span><span><span>&nbsp;&nbsp; <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Sub<\/span> SayPass()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Say(<span>My<\/span>.Resources.SAY_Pass)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> Say(<span>ByVal<\/span> s <span>As<\/span> <span>String<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> Voice <span>IsNot<\/span> <span>Nothing<\/span> <span>Then <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span>&#8216; Voice is the SpVoice member of EuchreSpeech<\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Voice.Speak(s)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">And, in the string resource manager, SAY_Pass = \u201c<strong>I pass<\/strong>.\u201d<span>&nbsp; <\/span>It\u2019s just that easy!<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Like I said at the beginning of this session, you may or may not decide to use TTS in a game, but it\u2019s certainly useful in other applications where accessibility is an issue, and so it\u2019s a handy tool to know how to use.<span>&nbsp; <\/span>Next time, I\u2019m going to discuss game logic. See you then!<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&#8211;Matt&#8211;*<\/font><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/EuchreOptions.jpg\">EuchreOptions.jpg<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Coding a Euchre Game, Part 6:&nbsp; Pump up the volume Ever since Commodore first introduced the SID chip to their line of PCs way back in the earlier 80\u2019s, sound has been an important experience in any computer game.&nbsp; What\u2019s particularly exciting to me is that audio has caught up to graphics as far as [&hellip;]<\/p>\n","protected":false},"author":258,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[22,195],"tags":[101,165],"class_list":["post-6453","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-matt-gertz","category-visual-basic","tag-matt-gertz","tag-vb2005"],"acf":[],"blog_post_summary":"<p>Coding a Euchre Game, Part 6:&nbsp; Pump up the volume Ever since Commodore first introduced the SID chip to their line of PCs way back in the earlier 80\u2019s, sound has been an important experience in any computer game.&nbsp; What\u2019s particularly exciting to me is that audio has caught up to graphics as far as [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6453","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/258"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=6453"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6453\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=6453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=6453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=6453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}