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
SharpDX is a managed DirectX API that supports Windows 8 Store apps. Use NuGet to add it 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!