Posts Tagged ‘c#’

I have spent the past couple of hours trying to make a sound effect play quickly and correctly using the MediaElement. I was tring to play the sound effects using the following code:


var snd = new MediaElement {AutoPlay = false, Volume = 60};
var folder = await Package.Current.InstalledLocation.GetFolderAsync(@"Assets\Sounds");
var file = await folder.GetFileAsync("shot.wav");
var stream = await file.OpenAsync(FileAccessMode.Read);
snd.SetSource(stream, file.ContentType);
snd.Play();

If I attempt to play a single MediaElement repeatedly and quickly, it sometimes (often) doesn’t play. Creating multiple MediaElements and trying to play them in quick succession is a mixed bag, sometimes they play correctly, sometimes they don’t play, and sometimes they save themselves up and all play at once!

MediaElement just doesn’t cut it.

After some searching on the Internet, it would seem that SharpDx is the answer! I have heard of it before but never used it.

The power of DirectX for .NETSharpDX is an open-source project delivering the full DirectX API under the .Net platform, allowing the development of high performance game, 2D and 3D graphics rendering as well as realtime sound application.

In VS2012 choose Tools > Library Package Manager > Package Manager Console.

Type: Install-Package SharpDX.XAudio2

If you get an error make sure that NuGet doesn’t need any updates!

I created a new class called SoundEffect and gave it the following variables:

readonly XAudio2 _xaudio;
readonly WaveFormat _waveFormat;
readonly AudioBuffer _buffer;
readonly SoundStream _soundstream;

And initiate them with a constructor:

public SoundEffect(string soundFxPath)
{
_xaudio = new XAudio2();
var masteringsound = new MasteringVoice(_xaudio);


var nativefilestream = new NativeFileStream(
soundFxPath,
NativeFileMode.Open,
NativeFileAccess.Read,
NativeFileShare.Read);

_soundstream = new SoundStream(nativefilestream);
_waveFormat = _soundstream.Format;
_buffer = new AudioBuffer
{
Stream = _soundstream.ToDataStream(),
AudioBytes = (int) _soundstream.Length,
Flags = BufferFlags.EndOfStream
};
}

Then to play the sound effect I simply created a Play() method:

public void Play()
{
var sourceVoice = new SourceVoice(_xaudio, _waveFormat, true);
sourceVoice.SubmitSourceBuffer(_buffer, _soundstream.DecodedPacketsInfo);
sourceVoice.Start();
}

I create a new instance of the SoundEffect class:
private SoundEffect shotEffect = new SoundEffect(@"Assets\Sounds\shot.wav");

And then simply play it:
shotEffect.Play();
 
This works perfectly 😀

Advertisements