Weblog About All Tech Stuff

May 30, 2008

Roleplaying Multiple Cooccurring Sounds in WPF

Filed under: Software — Tags: , , , — jerry35 @ 4:56 am

WPF’s MediaElement makes believe bare media playback pretty square, but moving beyond the mere scenarios can sometimes bring up surprising challenges. For example, I late saw someone triped up up by the MediaElement when assaying to run several sounds at the same time.

As you’ll pick up, one solution would have been to expend MediaPlayer alternatively of MediaElement. The difference between these WPF classes is fairly square. MediaPlayer is the class that recognizes how to run media files – both video and audio. MediaElement is a wrapper around MediaPlayer that plies a uncomplicated way to tie it into a ocular tree (i.e. a user interface), which in turn gets us addict it into things like the animation system or event triggers.

(Remark: do not be misled by the class name. Although WPF and Windows Media Player depend upon the same infrastructure for media decrypting, the MediaPlayer class is not a wrapper around the Windows Media Player control. While they partake codecs, the path by which deciphered video twigs the screen in WPF is significantly unlike from Windows Media Player.)

How would that have you into trouble when utilizing MediaElement? If it’s a wrapper around MediaPlayer, certainly you could utilise a MediaElement any place a MediaPlayer would lick? In fact it’s not e’er that uncomplicated. To run across why, we’ll start with a elementary example.

One MediaElement

The elementaryest way to utilise MediaElement is to lend it to a UI and charge it at a media lodge:

<Window x:Class="MediaPlayback.Window1"  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  Title="Window1" Height="300" Width="300">  <MediaElement Source="file:///c:/windows/media/tada.wav" /> </Window> 

This will toy the file before long as the UI loads. If you desire a bit more control, you can tell it to hold off until you’re quick:

<MediaElement x:Name="audioPlayer"  Source="file:///c:/windows/media/tada.wav"  LoadedBehavior="Manual" /> 

It’ll at present accommodate off until you phone audioPlayer.Play().

This approach is too oft sufficient for spieling multiple unlike sounds. you can exchange the Source property and call up Play over again. Still, if you desire to toy multiple sounds at the same time, this approach doesn’t work – arranging the Source will hold on playback if it is in progress. A single MediaElement or MediaPlayer can simply roleplay one thing at a time.

That’s OK, because we can e’er make multiple MediaElements.

Multiple MediaElements

Changing the example above merely by lending multiple MediaElements to the Window will kibosh the Xaml from hoarding, because Window can have merely a single lineal descendant. So we require to regain something to reserve the MediaElements. And this is where the example I saw triped up up: the developer assigned them into the UI’s Resources section.

On the face of it, this was a perfectly fair thing to do – the elements are all recreating audio, so it doesn’t appear like they should require to be part of the ocular tree, indeed why not make up them resources? After all, WPF’s resource mechanism is planed to take hold utile objects, decently?

Well this is where the difference between MediaPlayer and MediaElement suits of import. Think of, the distinction is that MediaElement plugs into media playback into a ocular tree. And it sours out that until it makes believe that connection, MediaElement won’t toy the media. That prepares sense for video – you assume’t desire that to begin runing before you can construe it. But while you might reckon a connection with the ocular tree would be optional for audio, MediaElement reckons it otherwise. (And there are reasons for that. For example, MediaElement can synchronise media playback with timelines of animations in the ocular tree.)

Indeed in this case, the additional functionality provided by the wrapper has worked against us.

One solution is only to feed the MediaElement what it needs. As foresightful as we assign it into the ocular tree, it’s felicitous. So we can put the elements into a layout panel such as a Grid or Canvas:

<Canvas>  <MediaElement x:Name="mediaElem1"  Source="file:///c:/windows/media/tada.wav"  LoadedBehavior="Manual" />  <MediaElement x:Name="mediaElem2"  Source="file:///c:/windows/media/Windows Logoff Sound.wav"  LoadedBehavior="Manual" /> </Canvas> 

The other approach is to proceed flat for the MediaPlayer – if we have no need for the ocular tree integration features MediaElement puts up, we may as good proceed flat to the underlying player. The simply snag is that you can’t format MediaPlayer from Xaml – you must utilise the Open method to charge it at the media lodge, and Xaml doesn’t do method calls off. But it’s not a immense amount of effort:

MediaPlayer mp = new MediaPlayer(); mp.Open(new Uri(wavPath)); mp.Play(); 

That is all the code needed; we wear’t require anything at all in the Xaml. And to run multiple coinciding sounds, you can just make multiple MediaPlayers.

Relating Posts:
Snippet Compiler update
Cyphering rant
Prospicient term strategies for utilizing Java EE
CVS on the Web
Check out out popfly game creator
If the news is of import it will regain me

No Comments Yet »

No comments yet.

RSS feed for comments on this post.

Leave a comment

Blog at WordPress.com.