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");
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.
"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.
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.
Related
Ok so there are a couple inherent understandings
1) I know the SoundPlayer class, despite being able to load System.IO.Stream interfaces, is 100% incapable of playing more than one sound at once, despite all the multithreading and multiple-property usage.
2) I know WMPLib is the go to answer for playing multiple files. Sadly, it requires a URL, and according to MSDN, that URL cannot point to a resource. WindowsMediaPlayer class is also incapable of loading IO.Stream interfaces.
3) I saw a hack where you write out a temporary audio file to disk and have WMPlib play that, and to that I say "polite pass"
Simply put, I do not want users messing with the source audio files. I intend to distribute just the executable and not a zip containing a tonn of files. This is why I opted for the .resx
Is there not another audio player available to C# that can take an IO.Stream that is capable of playing more than one thing at a time?
My little program is a text adventure, and I intend to have a little ambient loop playing in the background while some sound effects play to reflect what's happening on the screen.
I am currently having a probelm, where a file was sent to me as .m4a and I renamed it to .wav..... (I think that is the issue as I can play other .wav files)
Now it is giving me this error when I run the code:
Additional information: The file located at c:\Windows\Media\dj.wav is not a valid wave file.
Maybe I just need to change it back to .m4a and then have some website convert it to .wav compared to me just renaming it?
My code looks like this:
using System.Media;
playSimpleSound();
private void playSimpleSound()
{
SoundPlayer simpleSound = new SoundPlayer(#"c:\Windows\Media\dj.wav");
simpleSound.Play();
}
Also, how can I write my path, so that it would hit the file in the debug folder? Because I am going to deploy this to a thin client in another building.
Changing the extension of a file does not change the content in it. M4A are MPEG-4 audio-only data, whereas WAV files are typically raw and uncompressed audio samples.
To convert the data itself, you'll need to use an audio transcoding tool like SoX or GoldWave.
As for your path specifier, you can simply use "dj.wav" or "wavfiles\dj.wav", basically relative to where your exe sits. This is because the current working directory is set to where it resides when started with a simple double click in explorer. You can, however also specify the full path using the answer here.
Hope this helps!
I am new to direct show development. I am learning things about direct show. I am trying to write a method which plays some audio files. It works fine for many .mp3 files, but for some of my mp3 file the method RenderFile() of interface IGraphBuilder throws following exception
COMException occured : "Pins cannot connect due to not supporting the same transport."
My best guess is that I am missing some codec to play those files. Can anyone suggest what I am doing wrong. Is there any way to select a filter which can play those files. I am able to play those files with Windows Media Player, so I believe that I have required codecs installed.
Any help will be of great value.
Thanks in Advance.
This is a well known problem with MP3 files and standard DirectShow fitler reading them. The problem is that if a file has a big section with ID3 tags, the filter might give up skipping them to audio data and this makes the whole playback fail.
These files will still play fine if you open them starting with WM ASF Reader Filter. This assumes you build, or at least start building, the graph manually to override default building behavior.
I need to play back 30 second audio clips, 1 per second, in winforms dotnet.
I am currently loading/playing the wav files from the filesystem, which works fine on a notebook, but is causing problems on a netbook. Can I pre-load all sound files into memory, if so how?
If you use the SoundPlayer to play your files you can preload the file with SoundPlayer.Load.
SoundPlayer sp = new SoundPlayer("filename");
sp.Load(); // preload
sp.Play();
Edit:
As noted by the documentation you may also use SoundPlayer.LoadAsync to load the sound in the background.
I'm inclined to say that you would load the file into a system.io.memorystream of some sort. Hopefully the libraries that play your file, will take a memorystream or memorystream can be converted into the data structure that this library takes.
Here's a recent example that creates a .wav file (a sine) in memory entirely from scratch and plays it. What you're trying to do should be much simpler, and you should be able to derive it from the sample posted.
Real low level sound generation in C#?
I'm trying to write a Silverlight application that reads a media file from a database (most likely a .mpeg or .mpg) and play it on the fly using either a Silverlight MediaPlayer or ExpressionMediaPlayer. When I try using Expression Media Player it plays .wmv and .mp4 files but NOT .mpeg or .mpg file extensions. Is this even possible? If so, HOW?!
I tried going a different route originally where I wrote a Service to Encode the file using a LiveJob and then play it on the ExpressionMediaPlayer from the port using mms://localhost:8080 but I couldn't figure out how to use that to Play/Pause the video. It just ran through once and stopped. Any suggestions on that?
I'm using Expression Encoder 3 & Silverlight 4 by the way.
i think you're out of luck, check out this page from msdn.
You are going to have to re-encode the file if you want it to play in Silverlight.