Search code examples
c#xamlaudiowindows-8xaudio2

Windows 8 xaudio2 playing wav file in multitouch app


I am learning how to work with xAudio2. Made a simple application Windows 8 in Visual Studio 2012 Express For Windows 8. Simple xAudio2 player class:

public class SoundEffect 
{
    readonly XAudio2 _xaudio;
    readonly WaveFormat _waveFormat;
    readonly AudioBuffer _buffer;
    readonly SoundStream _soundstream;
    SourceVoice sourceVoice;

    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
        };
        //sourceVoice = null;


    }

    public void Play()
    {
            sourceVoice = new SourceVoice(_xaudio, _waveFormat, true);

            if (sourceVoice != null)
            {
                sourceVoice.FlushSourceBuffers();
                sourceVoice.SubmitSourceBuffer(_buffer, _soundstream.DecodedPacketsInfo);

                sourceVoice.Start();
            }
    }
    public void Stop()
    {
        sourceVoice.Stop();
    }
}

And Xaml:

<Border Background="Gray" MinHeight="150" MinWidth="150" Margin="10,10,0,0" x:Name="A"  PointerPressed="btnAPointerPressed" PointerReleased="btnAPointerReleased" />

enter image description here

and:

private SoundEffect shotEffect = new SoundEffect(@"sounds\mywav.wav");
        private void btnAPointerPressed(object sender, PointerRoutedEventArgs e)
    {
        bool _hasCapture = ((Border)sender).CapturePointer(e.Pointer);
        shotEffect.Play();
    }

    private void btnAPointerReleased(object sender, PointerRoutedEventArgs e)
    {
        ((Border)sender).ReleasePointerCapture(e.Pointer);
        shotEffect.Stop();
    }

Tested in Windows 8 Simulator. If I press one finger, then everything is fine. When I click on the button - the sound plays when I let go of your finger - the sound stops.

enter image description here

If I click with two fingers and let go of both fingers, the sound continues to play. And the result is aliasing.

enter image description here

Called two events: btnAPointerPressed and two events: btnAPointerReleased but the sound continues to play. As if the audio stream freezes and continues to play. As if the audio stream freezes and continues to play. I want to understand the problem haudio2? or I do not properly done something?


Solution

  • When you call Play() again - the previous SourceVoice gets replaced with a new one in your SoundEffect, but you never stop the old one. You should create a new SourceVoice with each touch, but keep them all associated with the pointer IDs so that we can stop each of them when the associated pointers are released.