0

I am currently using SharpDX SourceVoice to play wav files in a WP8 app, which works fine for playing individual files.

However, I cannot find a way to play multiple files one after another in a loop without registering for events on the SourceVoice and queueing up the next the file. This seems to introduce a bit of stutter and isn't very seamless so I am hoping there is some way to queue both files up once and just loop over them.

There are a few questions around playing two files simultaneously (like this one: Best way to play two audio files simultaneously in Windows Phone 8), but I want to play them one after another in a loop.

The code I have to play a single file looks like:

xaudio = new XAudio2();
masteringVoice = new MasteringVoice(xaudio);

var nativefilestream = new NativeFileStream(String.Format(@"{0}", soundfile),NativeFileMode.Open,NativeFileAccess.Read,NativeFileShare.Read);
var soundstream = new SoundStream(nativefilestream);
var waveFormat = soundstream.Format;
var buffer = new AudioBuffer
{
    Stream = soundstream.ToDataStream(),        
    AudioBytes = (int)soundstream.Length,
    Flags = BufferFlags.EndOfStream
};

sourceVoice = new SourceVoice(xaudio, waveFormat, true);
sourceVoice.SubmitSourceBuffer(buffer, soundstream.DecodedPacketsInfo);
sourceVoice.Start();

If I want to loop a single piece of audio, I set the loop count on the AudioBuffer to infinite, as follows:

LoopCount = AudioBuffer.LoopInfinite,

I did try calling the SubmitSourceBuffer method twice with different AudioBuffers, with both having LoopCount set to LoopInfinite, but only the first one played.

Community
  • 1
  • 1
user783836
  • 3,099
  • 2
  • 29
  • 34

1 Answers1

0

I couldn't get this to work the way I wanted i.e. queue up two AudioBuffers and have them repeat. It turns out if you queue up two AudioBuffers and set Loop = x on each of them the first one loops x times, then the second one loops x times. Aslo, it looks like a buffer is removed from the queue once it has been played so it's doubtful you could loop two buffers together anyway.

I also tried creating a 'merged' AudioBuffer from the two individual AudioBuffers by copying their individual bytes into a MemoryStream but the resulting stream was not valid and couldn't be played (maybe due to there being sort of header or EOF marker in each of the individual streams).

Eventually, I settled on the solution of using a continuous ThreadPoolTimer to submit the AudioBuffer to the SourceVoice every x milliseconds, which achieve the desired result.

ThreadPoolTimer timer = ThreadPoolTimer.CreatePeriodicTimer(
(timer) =>
{
    sourceVoice.SubmitSourceBuffer(buffer, soundstream.DecodedPacketsInfo);
    sourceVoice.Start();

}, TimeSpan.FromMilliseconds(1500));

I'm still not sure if this is how it should be done and if anyone knows to the contrary I'll happily accept their answer.

user783836
  • 3,099
  • 2
  • 29
  • 34