0

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

Matt McManis
  • 4,475
  • 5
  • 38
  • 93

1 Answers1

1

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

TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • I'm not able to use SoundPlayer as it can't play 2 sounds at one time. But I don't have to use MemoryStream, just as long as it can play from memory. I'm just trying to find a way to reduce the delay, I was thinking hard drive speed was causing it. – Matt McManis Mar 06 '18 at 02:33
  • Task.Run() would not play 2 at once. DllImport PlayWorker(), `IsBeingPlayed` not found. – Matt McManis Mar 06 '18 at 03:49
  • @MattMcManis is being played is just a copy and paste error, and dosnt need to eb there – TheGeneral Mar 06 '18 at 03:54