4

For size reasons I need to bundle a WP7 app with compressed audio (mp3, wma etc). How do I play these freely/simultaneously?

The XNA framework only supports WAV files, so unless there is a pure C# managed code library somewhere to decompress mp3/wma/ogg (?) on the fly, the next option would be...

MediaElement. But I don't get good results with MediaElement. It seems that you need to add a MediaElement specifically as a tag in the xaml, and you can't use several instances (several tags). As soon as I play a certain MediaElement I can't play another MediaElement on the same page. I don't find anything about a restriction in the reference (the reference is very empty). I also tried dynamically creating MediaElement objects, but that doesn't seem valid at all, or I just cannot get it to play the files at all.

Gergely Orosz
  • 6,475
  • 4
  • 47
  • 59
Jonny
  • 15,955
  • 18
  • 111
  • 232

4 Answers4

3

Use the built-in XNA content pipeline sound effect compression!

The default setting for a SoundEffect content type is "Best" compression quality (which appears to, in fact, be no compression at all). Set the compression quality to "Low" and you will get a much, much smaller file. Or "Medium" for a nice balance between size and quality.

To change this setting, select your .wav file in the solution explorer, press F4 to bring up the properties window, expand the "Content Processor" node, and change the compression quality setting that appears.


Here are instructions with screenshots:

Create a new WP7 XNA game project (or otherwise get an XNA Content Project)

Create Project

Add a wav file to the content project:

Add sound effect

Wav File Added

Press F4 with the wav file selected in the Solution Explorer to bring up the properties window.

Content Properties

Expand the "Content Processor" node and change the compression quality to the desired setting.

Set Compression

A setting of "Best" gives no compression (raw waveform), settings of "Medium" and "Low" give a much smaller file.

Andrew Russell
  • 26,924
  • 7
  • 58
  • 104
  • There is no "Content Processor" node in a wav files properties. I have: Build Action, Copy to Output Directory, Custom Tool, Custom Tool Namespace, File Name and File Path only. Are you sure this is for WP7? – Jonny Aug 11 '11 at 14:49
  • 1
    @Jonny You're adding the `wav` files directly to a regular project. You need to use an XNA Content Pipeline project, and then load them via `ContentManager`. – Andrew Russell Aug 12 '11 at 01:29
  • Tried creating a few other kinds of projects but don't find anything like a Content Processor node. I'm thinking this is something that is not available in VS 2010 for Windows Phone. Did a google and "XNA Game Studio" was suggested - I'm just using the WP7 SDK. – Jonny Aug 12 '11 at 03:36
  • @Jonny I am pretty sure that XNA Game Studio comes with the WP7 tools - but if not, then just download it (it's free). In the "Add New Project" dialog you should be able to create an "Empty Content Project (4.0)". If your app is a Silverlight app, then you need to have it reference a "Windows Phone Game Library (4.0)" project which in turn can have a "Content Reference" to the content project. You may need to be targeting WP7.1 (Mango) to integrate XNA and Silverlight in the same app. – Andrew Russell Aug 12 '11 at 05:41
  • After looking this up a bit more it seems the compression things aren't available on the WP platform http://msdn.microsoft.com/en-us/library/dd282474.aspx – Jonny Aug 15 '11 at 03:08
  • @Jonny That's the overall XNB compression, applied to every XNB file as a final pass (similar to zipping the file). It's unrelated to the lossy compression (probably WMA or something similar) applied to sound effects as part of the content processing step. I have verified that setting the compression settings correctly reduces the sound effect size significantly (to about 10-20% of uncompressed) and works on a WP7 build. – Andrew Russell Aug 15 '11 at 03:23
  • See also http://msdn.microsoft.com/en-us/library/dd231952.aspx "Some content types, such as Song Class and SoundEffect Class data, may not benefit from a general lossless compression algorithm. This is especially true if **data is already compressed in a specialized format.**" – Andrew Russell Aug 15 '11 at 03:25
  • OK. I'll try to give one more go later when I get most other stuff out of the way. Mango release just around the corner... :-P – Jonny Aug 15 '11 at 03:27
  • I've added instructions with screenshots. – Andrew Russell Sep 01 '11 at 15:04
  • I'm sure that whoever downvoted this had a really good reason, and they were too busy to provide an explanation, and that it wasn't just Gergely Orosz being spiteful... – Andrew Russell Sep 03 '11 at 06:18
  • Uhhh. While I have no real use for this now (app already in Marketplace) I did try the instructions above and yeah of course they seem right. I'm not sure this would eventually have been useful in my app - three steps of compression only and not sure what quality/size that would give in the end. But you deserve a few +es for the help, not downvotes. As a conclusion, MS has a lot to do with their WP7 frameworks. Not supporting mp3 (well) out of the box is so 1990. :-D – Jonny Sep 07 '11 at 10:04
2

In my experience currently there's no good solution for this on WP7. Either you use wavs with XNA and grow the size of the xap or use mp3s with the very limited MediaElement functionalty, compromising on what you can implement with it.

You might be able to port some C# audio libraries to WP7, I haven't heard of any so far so it might be long shot.

In one of my apps I finally decided to go with the wav + XNA combination after playing around with different options for a good while.

Community
  • 1
  • 1
Gergely Orosz
  • 6,475
  • 4
  • 47
  • 59
  • You seem to be right about this, unfortunately. There is no good solution. How did Microsoft think when they decided app devs don't need compressed audio? Sure you can play mp3/wma with MediaElement, but MediaElement seems buggy (or very limited at best). I'm in the position where I can't use XNA+wav because that would grow my app from 20 MB to around 200 MB - no one wants to get an app like that through 3G. My "solution" will probably be like you say, constrain the functionality by only allowing one sound to play at once - stopping any previous sound before playing the next sound. – Jonny Aug 15 '11 at 03:12
  • 1
    See [my answer](http://stackoverflow.com/questions/7022360/wp7-play-many-compressed-mp3-wma-etc-audio-files-simultaneously-dynamically/7025544#7025544). XNA on WP7 supports compressed sound effects. – Andrew Russell Aug 15 '11 at 03:34
  • Just FYI in XNA 4.0 I have pure C# code playing ogg files with DynamicSoundEffectInstance - see codeplex here: http://xnaogg.codeplex.com/ – jjxtra Dec 28 '11 at 09:16
2
using Microsoft.Xna.Framework.Media;

void PlaySound(string pathToMp3) {
   Song song = Song.FromUri("name", new Uri(pathToMp3, UriKind.Relative));
   Microsoft.Xna.Framework.FrameworkDispatcher.Update();
   MediaPlayer.Play(song);
}
nikib3ro
  • 20,366
  • 24
  • 120
  • 181
1

You could use MediaElement and set the source to the mp3, but this cannot be changed from code as in.

MediaElement me = sender as MediaElement;
me.Source = new Uri(

as you cannot load resources into the source. you could use multiple MediaElements in your xaml and stop them and start the ones you require. As long as you predetermined which files you wanted to load at compile time.

You could also combine those files into one and play them at a particular location, like so.

me.Position = new TimeSpan(0, 0, 0, 0, 1);
me.Play();
Joseph Le Brech
  • 6,541
  • 11
  • 49
  • 84