Matt McManis
Matt McManis

Reputation: 4675

Play WAV File from Memory using MediaPlayer Class

I play a .wav sound file when a key is pressed. But there is a delay before playing the sound.

How can I copy the file to memory and play it from MemoryStream instead of the Hard Drive?

if (e.Key == Key.Enter) {
    MediaPlayer player = new MediaPlayer();
    Uri uri = new Uri("Sounds\\enter.wav", UriKind.RelativeOrAbsolute);
    player.Open(uri);
    player.Play();
}

I'm also using this global keyboard hook, it might be contributing to the delay.

https://gist.github.com/Ciantic/471698

Upvotes: 0

Views: 1404

Answers (1)

TheGeneral
TheGeneral

Reputation: 81493

If your requirements are to play from a MemoryStream explicitly, then you cant use MediaPlayer as far as i know. If it suits you, you can use SoundPlayer though

    soundPlayer = new System.Media.SoundPlayer(memoryStream);
    soundPlayer.Play();

Or

    soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
    soundPlayer.Stream.Write(buffer, 0, buffer.Length);
    soundPlayer.Play();

Update

MediaPlayer has a delay, its not designed to play short sounds in that way.

This is totally untested, however, you could try SoundPlayer in a Task.Run threadpool or background thread. that way you get your buffering performance gain

byte[] buffer;

Task.Run(() =>
            {
               soundPlayer = new SoundPlayer()
               soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
               soundPlayer.Stream.Write(buffer, 0, buffer.Length);
               soundPlayer.Play();
               // or
               soundPlayer = new System.Media.SoundPlayer(memoryStream);
               soundPlayer.Play();
            });

Or another approach Play multiple sounds using SoundPlayer

// Sound api functions
[DllImport("winmm.dll")]
static extern Int32 mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback)

...

private void PlayWorker()
{
    StringBuilder sb = new StringBuilder();
    mciSendString("open \"" + FileName + "\" alias " + this.TrackName, sb, 0, IntPtr.Zero);
    mciSendString("play " + this.TrackName, sb, 0, IntPtr.Zero);
}

Lastly

If the above still aren't suitable, you might be better of at looking at DirectSound or maybe even nAudio, or something that has a bit more power in this respect

Upvotes: 1

Related Questions