4

I have an app that I need to play a wav file when a key is pressed, I use the SoundPlayer class but if another sound is being played when a new key is pressed, it stops the sound the play it again making it look ugly....

is there any way to play the same sound again even if there is another of being played?

thanks!

開発者
  • 670
  • 1
  • 9
  • 11

4 Answers4

5

Use PlaySound from the windows API in combination with the SND_ASYNC and SND_NOSTOP flags.

http://www.pinvoke.net/default.aspx/winmm.playsound

Usage

//And the actual usage
PlaySound (fileName, UIntPtr.Zero, (uint)(SoundFlags.SND_FILENAME | SoundFlags.SND_ASYNC | SoundFlags.SND_NOSTOP));

Declarations

[Flags]
public enum SoundFlags
{
    /// <summary>play synchronously (default)</summary>
    SND_SYNC = 0x0000,    
    /// <summary>play asynchronously</summary>
    SND_ASYNC = 0x0001,
    /// <summary>silence (!default) if sound not found</summary>
    SND_NODEFAULT = 0x0002,
    /// <summary>pszSound points to a memory file</summary>
    SND_MEMORY = 0x0004,
    /// <summary>loop the sound until next sndPlaySound</summary>
    SND_LOOP = 0x0008,    
    /// <summary>don't stop any currently playing sound</summary>
    SND_NOSTOP = 0x0010,
    /// <summary>Stop Playing Wave</summary>
    SND_PURGE = 0x40,
    /// <summary>don't wait if the driver is busy</summary>
    SND_NOWAIT = 0x00002000,
    /// <summary>name is a registry alias</summary>
    SND_ALIAS = 0x00010000,
    /// <summary>alias is a predefined id</summary>
    SND_ALIAS_ID = 0x00110000,
    /// <summary>name is file name</summary>
    SND_FILENAME = 0x00020000,
    /// <summary>name is resource name or atom</summary>
    SND_RESOURCE = 0x00040004
}

[DllImport("winmm.dll", SetLastError=true)]
static extern bool PlaySound(string pszSound, UIntPtr hmod, uint fdwSound);

Update

Apologies, you are correct. The API cannot be used to play sounds simultaneously. You should be using the waveOut api. Look at this article: http://www.codeproject.com/KB/audio-video/cswavrec.aspx

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • hello, thanks for the help, but it doesn't do what I need... it waits till the sound is finished playing and what I need is that a new one starts playing at the same time. in other works, it's a game that when the gun is fired, a wav file is played, it takes ~2 secs and the gun can be fired a lot of times per second... so I need a lot of gun shot sounds per second – 開発者 Dec 13 '10 at 15:28
  • Did you set the `SND_ASYNC` flag when calling `PlaySound`? That should fix the problem. – CodesInChaos Dec 13 '10 at 15:46
  • But when I used PlaySound for games a few years back it didn't work reliably. It's probably a good idea to use a sound api that fits your usage better. I used some wrapper over DirectSound at that time, but there are many others. – CodesInChaos Dec 13 '10 at 15:48
1

NAudio might offer what you need. I haven't used it myself, but it's relatively popular.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
1

There's a free (for non-commercial applications) sound library for .NET called Irrklang that supports playing multiple sounds (at least wav and mp3 from what I can gather) at the same time, their tutorial specifically covers this case as basic usage of the library.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
0

If you're asking, "how can I play multiple sounds at once" then SoundPlayer will never be the answer. PlaySound, I believe, is also similarly limited.

You might look at this question and this question for more options on sound APIs. I took a quick look at SDL and SDL Mixer and thought that SDL was too primitive (you have to mix the sounds yourself) and SDL Mixer was too heavyweight (it's all that and a bag of chips - unlimited channels of mixing and music (mp3, ogg, midi, etc)). I couldn't see an online reference for BASS's C# bindings, but it's free for non-commercial use.

Community
  • 1
  • 1
plinth
  • 48,267
  • 11
  • 78
  • 120