{"id":123,"date":"2014-06-15T23:28:00","date_gmt":"2014-06-16T07:28:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2014\/06\/15\/vb-universal-windows-app-part-4-using-sharpdx-for-sound-effects\/"},"modified":"2024-07-05T12:37:48","modified_gmt":"2024-07-05T19:37:48","slug":"vb-universal-windows-app-part-4-using-sharpdx-for-sound-effects","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/vb-universal-windows-app-part-4-using-sharpdx-for-sound-effects\/","title":{"rendered":"VB Universal Windows App Part 4: using SharpDX for sound effects"},"content":{"rendered":"<p>This is Part 4 of the &#8220;<a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/tags\/universal\/\">VB Universal Windows App<\/a>&#8221; series:<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-1-getting-started.aspx\">Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer<\/a><\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-2-for-the-developer-sharing-xaml-assets-and-code.aspx\">Part 2: Sharing XAML, Assets and Code<\/a><\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-3-for-the-end-user-roaming-settings-and-in-app-purchases.aspx\">Part 3: Local and Roaming settings, and In-App purchases<\/a><\/li>\n<li><strong>&gt; Part 4: Sound effects with SharpDX<\/strong><\/li>\n<li><span style=\"color: #000000\"><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/20\/vb-universal-windows-app-part-5-calling-into-platform-specific-apis-from-pcl.aspx\">Part 5: How to call platform-specific APIs from common code<\/a><\/span><\/li>\n<li><span style=\"color: #000000\"><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/21\/vb-universal-app-downloads.aspx\">Download full source code<\/a><\/span><\/li>\n<\/ul>\n<p>So far we&#8217;ve built a solid app, sharing as much code and XAML as possible by placing it in our PCL. For today&#8217;s post we&#8217;ll continue the process, adding game-quality&nbsp;sound effects&nbsp;to our app. SharpDX is the best way to do this.<\/p>\n<ul>\n<li><a href=\"http:\/\/media.ch9.ms\/ch9\/6eaf\/e80bd717-59ce-427b-8c1b-d5cc52dd6eaf\/8audio_Source.wmv\">How Do I video: add audio through SharpDX<\/a> [3mins]<\/li>\n<\/ul>\n<p>Please bear with me. This is a long technical post, because playing game-like audio is a technically involved low-level task. The video lasts&nbsp;3 minutes, and you should watch it first before returning to read the rest of this post, in which I&rsquo;ll explain the <em>why<\/em> as well as the <em>how<\/em>.<\/p>\n<p>&nbsp;<\/p>\n<p>I wish audio weren&#8217;t this difficult! I&#8217;d actually started using MediaElement, a simple easy-to-use XAML control for playing audio, and it worked great on Windows. But then I discovered that Windows Phone only allows a maximum of two MediaElements, i.e. no more than two sounds playing at a time. Not good for a game. That&#8217;s why I was forced to turn to low-level audio and SharpDX. SharpDX is a tremendous project. If anyone wants to volunteer their time to help improve it, please start at the <a href=\"https:\/\/github.com\/sharpdx\/SharpDX\">SharpDX website<\/a>.<\/p>\n<p>I wrote a small wrapper&nbsp;for SharpDX and put it into&nbsp;a class called WavePlayer.<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/00\/00\/00\/35\/13\/13462E00WavePlayer2E00vb\">Download source code &#8220;WavePlayer.vb&#8221;<\/a><\/li>\n<\/ul>\n<p style=\"margin-left: .25in\"><strong><em>Pro tip:<\/em><\/strong><em> The SharpDX audio library is just a thin wrapper around XAudio2, one of the two low-level audio APIs in Windows &#8211; the other is called WASAPI. XAudio2 is complicated to use effectively. You load the audio sample from disk into an XAudio2.AudioBuffer. You can load it just once, and then play repeatedly from the buffer. To play a sound, you construct an XAudio2.SourceVoice. There can be many SourceVoice objects playing audio at a time. Once a SourceVoice has finished playing, it&#8217;s good to re-use it for future requests, rather than wastefully creating a fresh SourceVoice every time. All this work should all be done on background threads, since otherwise it causes UI &#8220;hiccups&#8221;. WavePlayer.vb does all this.<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 1:<\/strong> App1_Common &gt; Manage Nuget Packages &gt; Online &gt; nuget.org &gt; SharpDX.Toolkit.Audio &gt; Install<\/p>\n<p><strong>Step 2:<\/strong> App1_Common &gt; Add &gt; Class &#8220;WavePlayer.vb&#8221;. Paste in the implementation of class WavePlayer, from the download link above.<\/p>\n<p><strong>Step 3:<\/strong> App1_Common &gt; App.vb &gt; Add a&nbsp;two variables in the TRANSIENT STATE section, and initialize the WavePlayer object<\/p>\n<p><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\"><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Shared<\/span>&nbsp;BeepFile&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">As<\/span>&nbsp;<span style=\"background: white;color: #2b91af;font-family: Consolas;font-size: 9.5pt\">StorageFile<\/span><br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Shared<\/span>&nbsp; <span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">wavePlayer<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">As<\/span>&nbsp;&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">New<\/span>&nbsp;&nbsp;<span style=\"background: white;color: #2b91af;font-family: Consolas;font-size: 9.5pt\">WavePlayer<\/span><br \/><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 4:<\/strong> Initialize the BeepFile variable. This has to be done asynchronously, because it involves reading from disk and therefore might take some time. We wouldn&#8217;t want to delay showing the first screen while waiting for BeepFile.<\/p>\n<p>Note: I&#8217;ve done disk work on a background thread, via Task.Run. This is because disk access can sometimes cause &#8220;hiccups&#8221; of 1-2ms. This kind of hiccup would be un-noticeable in a regular data-entry app. But because I&#8217;m writing a game, I don&#8217;t want any hiccups.<\/p>\n<p><span style=\"background: white;color: black;font-family: Consolas;font-size: small\"><span style=\"background: white;color: black;font-family: Consolas\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas\">Public Shared<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas\">Sub<\/span>&nbsp;<span style=\"background: white;color: black;font-family: Consolas\">OnLaunched<\/span><span style=\"background: white;color: black;font-family: Consolas\">(e <span style=\"background: white;color: blue;font-family: Consolas\">As<\/span><span style=\"background: white;color: black;font-family: Consolas\">&nbsp;<span style=\"color: #2b91af\">LaunchActivatedEventArgs<\/span><\/span><\/span><span style=\"background: white;color: black;font-family: Consolas\">)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StartInitializationAsync()<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;.<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"background: white;color: blue;font-family: Consolas\">End<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas\">Sub<\/span>&nbsp;<\/span><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">&nbsp;&nbsp;&nbsp; Shared <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Async <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Sub<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\"> StartInitializationAsync()<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas;font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Try<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Await <\/span><\/span><\/span><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\">Task<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">.Run(<\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Async <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Function<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">()<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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><\/span><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Dim<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\"> folder = <\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Await<\/span><\/span><\/span><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\">Package<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">.Current.InstalledLocation.GetFolderAsync(<\/span><\/span><span style=\"color: #a31515;font-family: Consolas\"><span style=\"color: #a31515;font-family: Consolas\"><span style=\"color: #a31515;font-family: Consolas\">&#8220;App1_Common\\Assets&#8221;<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BeepFile&nbsp;= <\/span><\/span><\/span><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Await<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\"> folder.GetFileAsync(<\/span><\/span><span style=\"color: #a31515;font-family: Consolas\"><span style=\"color: #a31515;font-family: Consolas\"><span style=\"color: #a31515;font-family: Consolas\">&#8220;beep.wav&#8221;<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">)<br \/>&nbsp;&nbsp;&nbsp;&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><\/span><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">End <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Function<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Catch<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\"> ex <\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">As <\/span><\/span><\/span><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\">Exception<br \/><\/span><\/span><\/span><\/span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendErrorReport(ex)<\/span><\/span><\/span><span style=\"font-size: small\"><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\"><br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><\/span><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">End <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Try<br \/>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><\/span><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">End <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Sub<\/span><\/span><\/span><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 5:<\/strong> Dispose of&nbsp;the wavePlayer&nbsp;in the OnSuspending method:<\/p>\n<p><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\"><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Public Shared<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Async<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Function<\/span>&nbsp;<span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">OnSuspendingAsync(<\/span><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">)&nbsp;<\/span><span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">As<\/span><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;<span style=\"background: white;color: #2b91af;font-family: Consolas;font-size: 9.5pt\">Task<\/span><\/span><br \/><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;.<\/span><br \/><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wavePlayer.Dispose() : wavePlayer = <\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Nothing<\/span><br \/><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;<\/span><br \/><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">End<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Sub<\/span><br \/><\/span><\/p>\n<p><strong>Step 6:&nbsp;<\/strong>Restore&nbsp;the wavePlayer&nbsp;in the OnResuming method:<\/p>\n<p><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Public Shared Sub<\/span><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\"> OnResuming(<\/span><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">)<\/span><br \/><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">If<\/span>&nbsp;<span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\"> wavePlayer <\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Is<\/span>&nbsp;&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Nothing<\/span>&nbsp;&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Then<\/span>&nbsp;<span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\"> wavePlayer = <\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">New<\/span>&nbsp;&nbsp;<span style=\"background: white;color: #2b91af;font-family: Consolas;font-size: 9.5pt\">WavePlayer<\/span><br \/><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">End<\/span>&nbsp;&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Sub<\/span><br \/><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;<\/span><\/p>\n<p><strong>Step 7:&nbsp;<\/strong>Inside the two App.xaml.vb files, from both Windows and Phone projects, call into the common App.vb implementation of OnResuming:<\/p>\n<p><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">&nbsp;&nbsp;&nbsp; Sub<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\"> OnResuming(sender <\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">As <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Object<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">, e <\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">As <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Object<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">) <\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Handles <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Me<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">.Resuming<br \/><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; App1_Common.<\/span><\/span><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\"><span style=\"color: #2b91af;font-family: Consolas\">App<\/span><\/span><\/span><span style=\"font-family: Consolas\"><span style=\"font-family: Consolas\">.OnResuming()<\/span><\/span>&nbsp;<\/span><br \/><span style=\"font-size: small\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">&nbsp;&nbsp;&nbsp; End <\/span><\/span><\/span><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\"><span style=\"color: #0000ff;font-family: Consolas\">Sub<\/span><\/span><\/span><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 8:&nbsp;<\/strong>Add a call to play audio, wherever you want it! Remember that BeepFile gets initialized asynchronously, so we have to cope with the possibility that it&#8217;s still Nothing.<\/p>\n<p><span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">If<\/span>&nbsp;<span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">&nbsp;BeepFile <\/span><span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">IsNot<\/span>&nbsp;&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Nothing<\/span>&nbsp;&nbsp;<span style=\"background: white;color: blue;font-family: Consolas;font-size: 9.5pt\">Then<\/span>&nbsp;<span style=\"background: white;color: black;font-family: Consolas;font-size: 9.5pt\">wavePlayer.StartPlay(BeepFile)<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2>&nbsp;<\/h2>\n<h2>Conclusion<\/h2>\n<p>We&#8217;ve now created a solid VB Universal app &#8211; although under the hood, a universal app is really two separate apps. We&#8217;ve successfully been able to do all of our coding inside App1_Common, because we&#8217;ve been calling into APIs that are common to Windows and Windows Phone.<\/p>\n<p>Stay tuned for tomorrow&#8217;s blog post, where we cover how to call into APIs that <em>aren&#8217;t<\/em> common to Windows and Windows Phone. Thankfully there aren&#8217;t many of them!<\/p>\n<p>&nbsp;<\/p>\n<p>&#8212; <br \/><em><strong>Lucian<\/strong><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is Part 4 of the &#8220;VB Universal Windows App&#8221; series: Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer Part 2: Sharing XAML, Assets and Code Part 3: Local and Roaming settings, and In-App purchases &gt; Part 4: Sound effects with SharpDX Part 5: How to [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[21,16,195],"tags":[36,99,160,180],"class_list":["post-123","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-im-a-vb","category-vb-universal-windows-apps","category-visual-basic","tag-async","tag-lucian-wischik","tag-universal","tag-windows-phone"],"acf":[],"blog_post_summary":"<p>This is Part 4 of the &#8220;VB Universal Windows App&#8221; series: Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer Part 2: Sharing XAML, Assets and Code Part 3: Local and Roaming settings, and In-App purchases &gt; Part 4: Sound effects with SharpDX Part 5: How to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/123","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\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=123"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/123\/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=123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}