Archive for August, 2010

Windows Phone 7 Sound Effects Issue

08 Aug

I’m writing this for new people who are just starting Windows Phone 7 development.  This is something I’m sure all WP7 developers solve while developing their projects, but I thought I’d share my experiences on sound effects to save someone’s time when they run into this.

I’m starting a new application that had a need to create a sound effect on a button press.  Simply enough, right? I figured this would be very easy but this was my first attempt at developing a WP7 project.  First I added the MP3 to the project:


Then I referenced it using MediaElement into my Grid from the MainPage.xaml file like so:

  1. <MediaElement x:Name="MySoundFile" Source="soundeffect.mp3" AutoPlay="False"></MediaElement>

Then within the button click event method I added:

  1. MySoundFile.Position = TimeSpan.Zero;
  2. MySoundFile.Play();

This is apparently a standard way to play sounds within Silverlight.  This did not work in the emulator.   Even changing the Build action of the file to ‘Resource’ did not help.  After some Binging around I found out this is a known issue and someone suggested this workaround.  Within the App.xaml add the MediaElement to Application.Resources:

  1. <!–Application Resources–>
  2. <Application.Resources>
  3.           <MediaElement x:Key="AppSoundFile" Source="soundeffect.mp3" AutoPlay="false"></MediaElement>
  4. </Application.Resources>

Then create method within App.xaml.cs as:

  1. public void PlaySoundEffect()
  2. {
  3.     MediaElement myME;
  4.     myME = (MediaElement)this.Resources["AppSoundFile"];
  5.     myME.Position = TimeSpan.Zero;
  6.     myME.Play();
  7. }

Then call this method from your click event as:

  1. App currentApp = (App)Application.Current;
  2. currentApp.PlaySoundEffect();

This worked great in the emulator. I am not sure why, but it may be how the MediaElement is defined programmatically compared to being referenced from XAML when played.

However, a major problem became apparent after deploying directly to my LG WP7 preview device; it didn’t play at all.  Some more Binging and I found this logged bug.  Someone posted a workaround to use the XNA libraries to play the effect.  The problem with this is you have no control to stop it after the sound is executed and it cant be an MP3 file, but WAV works.  I converted the soundeffect.MP3 to soundeffect.WAV.  I then added Microsoft.Xna.Framework to my project references.  Within my MainPage.xaml.cs file I added:

  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Audio;

Then I made a call to the effect within the click event as such:

  1. var stream = TitleContainer.OpenStream("soundeffect.wav");
  2. var effect = SoundEffect.FromStream(stream);
  3. FrameworkDispatcher.Update();
  4. effect.Play();

This worked great in both the emulator and device.  For something I thought would be extremely easy this seemed like a bit of a chore.  I’m presuming the direct MediaElement call will work on release, but I’m surprised at something as common as playing a sound file is not completely functional yet.  I’m not sure if this is the best way to do this within a WP7 application.  If anyone has a better way to handle sounds, please let me know.

Update – 8/21/2010

Turns out that having my hardware device physically connected to my computer AND the Zune player disables MediaElement.  Once you disconnect it from the Zune player, the object plays fine on real hardware.  So I just need to remember to yank the device off to test any MediaElement objects. 

In the case of the app the example above shows pieces of, I’m going to continue using the XNA calls.  The reason is it allows multiple calls into it to stack the sound multiple times.  MediaElement can only be called once and will not play additional sounds until the first call completes.  In some situations this is fine, but is not preferable in my case.  


Posted in WP7