{"id":577,"date":"2008-10-12T11:28:41","date_gmt":"2008-10-12T16:28:41","guid":{"rendered":"http:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/577"},"modified":"2008-10-12T11:28:41","modified_gmt":"2008-10-12T16:28:41","slug":"silverlight-game-programming-playing-an-audio-file","status":"publish","type":"post","link":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/577","title":{"rendered":"Silverlight Game Programming: Playing an Audio File"},"content":{"rendered":"

\"image\" In my recent Silverlight game<\/a>, there are a variety of sound effects that occur from bullet fires to explosions. Most of the audio files are brief, lasting only for a second or less on average.<\/p>\n

I had a few options — put a MediaElement<\/a> directly on the UI (in XAML) and reuse each as needed, or create new MediaElements on demand. Rather than live with the artificial restrictions that would be inherent in a design which potentially limited the total number of simultaneous audio streams playing at one time, I decided on the second option — create them on demand. <\/p>\n

Playing a supported audio file in Silverlight is easy as:<\/p>\n

MediaElement <\/span>me = new <\/span>MediaElement<\/span>();\nme.Source = new <\/span>Uri<\/span>(fileName, UriKind<\/span>.Relative);\nme.Volume = volume;\nme.AutoPlay = true<\/span>;<\/pre>\n
Game<\/span>.Sky.Children.Add(me);<\/pre>\n

<\/a><\/a><\/p>\n

 <\/p>\n

Boom. Explode<\/strong>. The audio plays (thanks to AutoPlay–which I’ve explicitly set here though the default is true<\/em>). The part that annoys me though is that once these audio files are completed, there’s no way to have them be automatically removed from the control tree. A MediaElement is a UIElement — so it’s not zero impact to leave them around. So, they build up, and build up. <\/p>\n

My simple technique is to attach to the individual file’s CurrentStateChanged<\/a> event.<\/p>\n

public static void <\/span>PlayAudio(string <\/span>fileName, double <\/span>volume)\n{\n    MediaElement <\/span>me = new <\/span>MediaElement<\/span>();\n    me.Source = new <\/span>Uri<\/span>(fileName, UriKind<\/span>.Relative);\n    me.Volume = volume;\n    me.AutoPlay = true<\/span>;\n    me.CurrentStateChanged += new <\/span>RoutedEventHandler<\/span>(Audio_CurrentStateChanged);\n\n    Game<\/span>.Sky.Children.Add(me);\n}\n\npublic static void <\/span>Audio_CurrentStateChanged(object <\/span>sender, RoutedEventArgs <\/span>e)\n{\n    if <\/span>(sender is <\/span>MediaElement<\/span>)\n    {\n        MediaElement <\/span>me = sender as <\/span>MediaElement<\/span>;\n        if <\/span>(me.CurrentState == MediaElementState<\/span>.Paused)\n        {\n            me.CurrentStateChanged -= new <\/span>RoutedEventHandler<\/span>(Audio_CurrentStateChanged);\n            Game<\/span>.Sky.Children.Remove(me);\n        }\n    }\n}<\/pre>\n

In the CurrentStateChanged event handler, the code verifies that the Media is a Paused state (which happens when the media has finished playing) and then removes the UIElement<\/a> from the control tree. (By the way, the Game.Sky<\/strong> object is a technique that I’ve used to expose globally the base UI element used throughout the game).<\/p>\n

It’s cool that Silverlight can play WAV, MP3, and WMA files (my game uses all three types!)<\/p>\n","protected":false},"excerpt":{"rendered":"

In my recent Silverlight game, there are a variety of sound effects that occur from bullet fires to explosions. Most of the audio files are brief, lasting only for a second or less on average. I had a few options — put a MediaElement directly on the UI (in XAML) and reuse each as needed, […]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[4],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pd5QIe-9j","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":630,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/630","url_meta":{"origin":577,"position":0},"title":"Drumming on Silverlight","date":"December 8, 2008","format":false,"excerpt":"A few weeks ago someone posted on their blog a simple drum kit written in Silverlight (Update: I found the original drum inspiration post here). I thought I\u2019d give it a go as well tonight. Here\u2019s the result: (click to launch) \u00a0 I used a few of the same tricks\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":723,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/723","url_meta":{"origin":577,"position":1},"title":"Silverlight Stopwatch class in C#","date":"March 1, 2009","format":false,"excerpt":"I needed a simple method for doing some timings in Silverlight. Silverlight lacks the high performance query counter that is available natively in Windows (and available in .NET 3.5 for example), but it does have a TickCount. My code (mostly) mirrors the existing .NET Stopwatch class using the TickCount property\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1162,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/1162","url_meta":{"origin":577,"position":2},"title":"Silverlight to become Microsoft’s next VB6?","date":"November 1, 2010","format":false,"excerpt":"There was a huge uproar in the tech blogs this past week regarding some comments made by Bob Muglia (of Microsoft) as reported by Mary Joe Foley in a post entitled, \u201cMicrosoft: Our Strategy with Silverlight has shifted.\u201d The quotes that caused the most ruckus are: \u201cSilverlight is our development\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":388,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/388","url_meta":{"origin":577,"position":3},"title":"Silverlight Weather Demonstration","date":"June 26, 2008","format":false,"excerpt":"Demonstration available here. (You'll need to wait for a moment while it loads the first time). I've created a reasonably simple, yet multi-technology (and discipline) demonstration using Silverlight for the user interface and ASP.NET as the back-end. The demonstration uses: Silverlight 2.0 Data binding Delayed downloading of images \"Web services\"\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.wiredprairie.us\/blog\/wp-content\/uploads\/2008\/06\/image21.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1016,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/1016","url_meta":{"origin":577,"position":4},"title":"Silverlight vs. Flash vs. Photoshop Text Rendering","date":"March 24, 2010","format":false,"excerpt":"Curious about text rendering characteristics between Flash 10, Silverlight 4.0 and Photoshop, I created two small applications, one in Flash CS 4, and one in Visual Studio 2010. The Silverlight 4.0 tests are using the release candidate which was current as of March 23, 2010. I used Times New Roman\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"image","src":"https:\/\/i0.wp.com\/www.wiredprairie.us\/blog\/wp-content\/uploads\/2010\/03\/image_thumb.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":871,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/871","url_meta":{"origin":577,"position":5},"title":"Time for JavaScript.NEXT","date":"December 2, 2009","format":false,"excerpt":"OK, I\u2019ll admit that HTML 5, when it becomes a true standard and the common browsers implement it and all of CSS 3 that we won\u2019t need as many browser plug-ins for doing rich interactive applications anymore. We could ditch Microsoft\u2019s Silverlight and Adobe\u2019s Flash and not look back. But,\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/posts\/577"}],"collection":[{"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/comments?post=577"}],"version-history":[{"count":0,"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/posts\/577\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/media?parent=577"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/categories?post=577"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wiredprairie.us\/blog\/index.php\/wpjson\/wp\/v2\/tags?post=577"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}