简体   繁体   中英

Playing Windows System Sounds with System.Media.SoundPlayer

Is it possible that the System.Media.SoundPlayer can not play Windows System Sounds found in c:\\Windows\\Media ??

I have the code:

using (var soundPlayer = 
       new SoundPlayer(@"c:\Windows\Media\Landscape\Windows Notify.wav")) 
{ 
    soundPlayer.Play(); 
}

Yet when I run this code I get the error:

Sound API only supports playing PCM wave files.

Am I missing something? Is there a way to play these files from a WPF application? (without converting them to PCM)

The SystemSounds class contains the following predefined system sounds:

Asterisk Beep Exclamation Hand Question

So for example, to play the Stop:

System.Media.SystemSounds.Hand.Play();

All other sounds require you read the desired sound from the registry and play it with code like this:

SoundPlayer simpleSound = new SoundPlayer(@"c:\Windows\Media\Landscape\Windows Notify.wav");

"Landscape" refers to a Windows "Sound Scheme" and the wav files therein are utilized by the Windows OS. As you have already determined, those files cannot be used directly.

Comparison of the filesize of the Windows Notify.wav within the Landscape directory and the Windows Notify.wav file within the base Windows\\Media directory is quite sizable; 222KB vs 25.5KB ---

If you go into the 'Sound' control panel applet and browse to 'Sounds' tab, you will see a dropdown list for "Sound Scheme:" and those additional folders within Windows\\Media will be displayed in that list.

I don't have links to back this up, but after countless hours in dealing with Control Panel Sounds programmatically, I would venture to guess that the 'Sound Scheme' wav files just contain relevant data (perhaps effect data) that is consumed at runtime to play the modified versions of those sounds ... I could be quite wrong about that last part; it's just a guess. Regardless, you won't be able to use those sound scheme files directly within your code.

If you must play that "Landscape" version of the Notify wav, then I'd suggest playing the sound and saving it into a new wave file in an audio editor. You can add the wave file to your installer/deployment project to play it into the Windows\\Media folder and call it directly the same way that you are already.

This was an interesting question, but has a simple answer. After reading about this problem, I tried out your code and got the same problem, so then I searched online for a solution. While not finding an exact solution, I did find the SoundPlayer not playing any bundled windows sounds PCM wav files post here on StackOverflow that showed some code that played an audio file from the Windows\\Media folder successfully.

I tried that code and it worked, so then I just had to work out why your example didn't work. I checked for any differences between the audio file that did play and your notify audio file in an audio editor, but they were both definitely WAV files.

I tried playing a different audio file from the Windows\\Media\\Landscape folder and got the same error. I then tried playing an audio file from a different sub folder in the Windows\\Media folder and still got the same error. However, I then noticed that many of the folders in the Windows\\Media folder had the same audio files in.

That got me thinking and I eventually realised that all of the audio files that are in these folders are actually in the Windows\\Media folder directly. So you can play the sounds, but you just have to ignore the ones in the sub folders and play the ones from the Windows\\Media folder. This will work:

SoundPlayer soundPlayer = new SoundPlayer(@"C:\Windows\Media\Windows Notify.wav");
soundPlayer.Play();

However, I can't tell you why we got that strange error, but I can only assume that the files in the folder could perhaps be some kind of links to the actual files in the Windows\\Media folder and simply used by the operating system for grouping them into categories... or something similar.

Since the sound seems to be in a compressed format, it has to be decompressed before you can play it using SoundPlayer. You can use Windows Audio Compression Manager to decompress the sound for playback:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd742945(v=vs.85).aspx

However, that's rather complex to implement, so I discovered a nice library that does all that for you, NAudio:

http://naudio.codeplex.com/

Using NAudio seems to be slightly more involved than using System.Media.SoundPlayer, but it also appears to offer far more functionality.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM