So you have some great wave files (.wav) to play in your Windows Store App on your WinRT device? But you got lost after a few online searches on how to do that and are not sure which of the following methods is the best?

Playing wav files in a XAML/C# Windows Store App using SharpDX.

options

So what are the options?

After trying out some things, it was a post by Morten Nielsen who showed the code that put me in the right direction and I created a wave player that preloads waves and uses a new voice for each time you play them. Even if it is already playing.

Download the demo project

Step 1: Install SharpDX

SharpDX is a managed DirectX API that supports Windows 8 Store apps. Use NuGet to add it to your project.

Step 2: Add WavePlayer to your Project

using System;
using System.Collections.Generic;
using SharpDX.IO;
using SharpDX.Multimedia;
using SharpDX.XAudio2;

namespace WavePlayerDX {
public class WavePlayer : IDisposable {
public bool IsSoundOn { get; set; }

private readonly XAudio2 xAudio;
readonly Dictionary<string, MyWave> sounds;

public WavePlayer() {
    xAudio = new XAudio2();
    xAudio.StartEngine();
    var masteringVoice = new MasteringVoice(xAudio);
    masteringVoice.SetVolume(1);
    sounds = new Dictionary<string, MyWave>();
}

// Reads a sound and puts it in the dictionary
        public void AddWave(string key, string filepath) {
    var wave = new MyWave();

    var nativeFileStream = new NativeFileStream(filepath, NativeFileMode.Open, NativeFileAccess.Read);
    var soundStream = new SoundStream(nativeFileStream);
    var buffer = new AudioBuffer { Stream = soundStream, AudioBytes = (int)soundStream.Length, Flags = BufferFlags.EndOfStream };

    wave.Buffer = buffer;
    wave.DecodedPacketsInfo = soundStream.DecodedPacketsInfo;
    wave.WaveFormat = soundStream.Format;

    sounds.Add(key, wave);
}

// Plays the sound
        public void PlayWave(string key) {
    if (!sounds.ContainsKey(key)) return;
    var w = sounds[key];

    var sourceVoice = new SourceVoice(xAudio, w.WaveFormat);
    sourceVoice.SubmitSourceBuffer(w.Buffer, w.DecodedPacketsInfo);
    sourceVoice.Start();
}

public void Dispose() {
    xAudio.Dispose();
}
}

public class MyWave {
public AudioBuffer Buffer { get; set; }
public uint[] DecodedPacketsInfo { get; set; }
public WaveFormat WaveFormat { get; set; }
}
}
private WavePlayer _wavePlayer = new WavePlayer();

void MainPage_Loaded(object sender, RoutedEventArgs e) {
_wavePlayer.AddWave("spacy", "spacy.wav");
}

private void Button_Click_1(object sender, RoutedEventArgs e) {
_wavePlayer.PlayWave("spacy");
}

And that’s all folks. Note that I only did minor tests and I am not sure if all the voice resources are disposed correctly. So use this code at your own risk!

Written by Loek van den Ouweland on 2012-11-22.
Questions regarding this artice? You can send them to the address below.