Question

I have added a notification sound for some text message as a reference of the Main file of my project and try to make it work as follows

System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream s = a.GetManifestResourceStream("SignInSound.wav");
System.Media.SoundPlayer player = new System.Media.SoundPlayer(s);
player.Play();

I have the sound played, but it is not absolutely the one I added. Instead standard windows sound is played. Any ideas?

Update

The issue is in getting the file from resources

System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream s = a.GetManifestResourceStream("SignInSound.wav");
Was it helpful?

Solution

Judging by the documentation, your resource stream is bad.

The Play method plays the sound using a new thread. If you call Play before the .wav file has been loaded into memory, the .wav file will be loaded before playback starts. You can use the LoadAsync or Load method to load the .wav file to memory in advance. After a .wav file is successfully loaded from a Stream or URL, future calls to playback methods for the SoundPlayer will not need to reload the .wav file until the path for the sound changes.

If the .wav file has not been specified or it fails to load, the Play method will play the default beep sound.

So the problem is that GetManifestResourceStream() is not doing what you think it's doing.

Solution (based on ResourceManager)

var thisType        = this.GetType();
var assembly        = thisType.Assembly;
var resourcePath    = string.Format("{0}.{1}", assembly.GetName().Name, thisType.Name);
var resourceManager = new ResourceManager(resourcePath, assembly);
var resourceName    = "SignInSound";

using ( Stream resourceStream = resourceManager.GetStream(resourceName) )
{
    using ( SoundPlayer player = new SoundPlayer(resourceStream) )
    {
        player.PlaySync();
    }
}

OTHER TIPS

It seems that the System.Media.SoundPlayer class has a very limited amount of WAV formats it supports. I have tried using the string path constructor, and it works with some .wav files, while it fails with others.

Here is some sample code. If you're using Windows 7, you can check it for yourself, just make a default new Windows Forms Application and add one button to it.

Notice how the code works for the "success" string, and throws an InvalidOperationException for the "fail" string.

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        System.Media.SoundPlayer player;

        public Form1()
        {
            InitializeComponent();
            string success = @"C:\Windows\Media\Windows Battery Critical.wav";
            string fail = @"C:\Windows\Media\Sonata\Windows Battery Critical.wav";
            player = new System.Media.SoundPlayer(success);

        }

        private void button1_Click(object sender, EventArgs e)
        {
            player.Play();
        }
    }
}

Notice that the file under "success" has a bit rate of 1411 kbps, while the other one has 160 kbps. Try your code with a WAV file with a bit rate of 1411 kbps and let us know how it works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top