I am trying to implement a simple game in .NET with C#. There is a ball bouncing against objects, and when it bounces I play a sound asynchronously using System.Media:SoundPlayer. The problem is that most of the time (not always) the ball freezes at the time of impact, for as long as the sound plays.
This happens on Windows XP, but not on Windows 7. I use .NET 3.5.
And the weirdest thing is that the problem disappears if I open the application Windows Media Player and play a few seconds of an mp3.
Here's the code where I initialize the SoundPlayer object:
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream s = a.GetManifestResourceStream("Game.Resources.GameBounce.wav");
_playerBounce = new System.Media.SoundPlayer(s);
_playerBounce.Load();
...and when the ball hits an obstacle, this line is called:
_playerBounce.Play();
I have also tried "Attempt #4" in this post:
How to use System.Media.SoundPlayer to asynchronously play a sound file?
Another desperate attempt, based on some advice I found somewhere on the net, was to save the sound stream to a file, that SoundPlayer works better when initialized from a file.
Neither of those attempts worked.
Any ideas?
Related
I am playing background music using
SoundPlayer bgMusic = new SoundPlayer(#"bgmusic.wav");
then
bgMusic.PlayLooping();
but if I try to play any other sounds the music stops, is there a way to keep it going without using another thread
You ought not use SoundPlayer Class for this work; SoundPlayer is a lightweight class for playing occasional incidental sounds in an application. It will occasionally remove sounds if other things are going on in the audio subsystem (like a music playing). (WaveOutPlayer) API solve your problem.
I'm making a Windows Form application that is supposed to play an animated gif while playing music.
I used SoundPlayer, and everything worked flawlessly. Then I found out I can't play multiple audio files with SoundPlayer, which was a problem (Background music AND effects needed).
So I looked a little bit into DirectSound, but my application froze everytime I did anything DirectSound related (Device, Buffer...).
So now I'm trying out WMP, I was happy at first, but when I enabled a GIF (Transparent, in case it matters), the music stopped in less than a second while you could see the GIF to stop for a frame or so, like it's loading something heavy. And this happens every time that audio and GIF are playing at the same time, no matter if one of them started in advance. When I used SoundPlayer, I could play 20 animated GIFs at once with no effect on audio.
To sum it up:
SoundPlayer = Only one audio file, unacceptable
DirectSound = Freezes for some reason (Maybe worth trying again? I'd like to put focus of this question on WMP though, I lost the code anyway)
WMP = Won't play along nicely with animated GIFs, which are required.
I tried playing both .wav and .mp3 file, no difference.
I added the wmp.dll reference before.
using System;
using System.Windows.Forms;
using System.Media;
private void button2_Click(object sender, EventArgs e)
{
var player = new WMPLib.WindowsMediaPlayer();
player.URL = "song.wav";
pictureBox1.Visible = true;
}
Is there something I should know about WMP? Can you recommend some other method? It does seem that the audio stops when the pocess reaches certain memory usage. It's steady on about 45 MB, but once I play the audio file it starts increasing, and plays until it reaches about 48 MB when it stops and returns to 45 MB.
Thanks for taking your time and helping me in any way.
EDIT: I was using a GIF picture with resolution of 500x500 which I used SizeMode=StretchImage on to actually make it appear smaller (200x200). In this case, the music played for about 0.2 seconds. I resized the resource picture to 100x100, using StretchImage to make it appear as 200x200 again, and the music played for about 8 seconds, about 4 seconds if I loaded two GIFs at once. Changing the .mp3 bitrate to make it just 170KB didn't help at all. I mean my Google Chrome takes 3GB of my memory and still plays multiple videos just fine, while my Form is taking not even 50MB and struggles. Surely there must be a way to play GIF and a song. Is there some kind of MemoryAssignLimit property? Or does WMP simply fail when it comes to bigger resources? Is it a limitation set by WinForms?
Followed this solution, and it worked like charm, GIFs everywhere and 30 overlapping songs, and nothing stops unless I want it to. Great.
This is driving me bonkers! When trying to play a sound or any media element in a windows phone 8 app I get "Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))"
And that is all it says. If I look at the stack trace it shows: at Windows.UI.Xaml.Controls.MediaElement.Play()
Example code is:
XAML:
MediaElement x:Name="sndClick" Source="Assets/Sounds/Click.wav" Volume="10" AutoPlay="False"
Code:
sndClick.play();
I am trying to port a Windows 8 app to Windows Phone 8. The Windows 8 app works perfectly with the exact same code. This must be some issue with the Windows Phone. Everything else works, it just crashes when the phone trys to play media.
Not all the elements that play sounds crash the program, unless you click them a few times. Some elements always crash on the first click. No sounds ever play, even if the program doesn't crash with the exception it never plays any sounds.
ONE time (and only one time) it played the first couple frames of one of the animation files (.wmv) and then crashed.
It is a weird problem. All the code is copied from the working Windows 8 program and everything works except for the media. If I comment out the sound.play()'s and I disable the media player the program works fine.
At first I thought it might be that the resources weren't copying so I set the "Copy to Output Directory" to "Always Copy". No effect.
I tried the simulators and I tried it on physical hardware, it is the same on everything.
It isn't a resource issue, the simulators and the hardware have more than enough system resources, the whole app is only 22mb's.
It's not a codec issue, the animation is a .wmv file and the sounds are all .wav. Both should be natively supported on any windows device.
I have searched around and seen others with similar problems but I haven't seen any solutions. Does anybody know what is causing this issue and how to fix it? I would very much appreciate it.
I am pulling my hair out on this.
Thanks,
-RW
OK I fix it.
Windows Phone 8.1 simply hates it when there is more than one MediaElement in the program... Even just playing one at a time throws the error and wont play any sounds.
It is annoying. It is further annoying that it doesn't seem that XNA works in 8.1 (at least I couldn't get it to work)
The solution was to use SharpDX.
Special Thanks to this post: Multiple audio stream in Universal App(Runtime API), XNA SoundEffect replacement
I removed all but one MediaElement and added installed SharpDX and SharpDX Xaudio2 from the package installer thing. Then:
using SharpDX;
using SharpDX.XAudio2;
using SharpDX.IO;
using SharpDX.Multimedia;
private void PlaySound(string strPath)
{
XAudio2 xAudio = new XAudio2();
var masteringVoice = new MasteringVoice(xAudio);
var nativeFileStream = new NativeFileStream(strPath, NativeFileMode.Open, NativeFileAccess.Read, NativeFileShare.Read);
SoundStream stream = new SoundStream(nativeFileStream);
var waveFormat = stream.Format;
AudioBuffer buffer = new AudioBuffer
{
Stream = stream.ToDataStream(),
AudioBytes = (int)stream.Length,
Flags = BufferFlags.EndOfStream
};
var sourceVoice = new SourceVoice(xAudio, waveFormat, true);
sourceVoice.SubmitSourceBuffer(buffer, stream.DecodedPacketsInfo);
sourceVoice.Start();
}
And then just:
PlaySound("Assets/Sounds/Click.wav");
It works quite well! And the one remaining MediaElement that I need for an animation works now. My hair is even starting to grow back (though it is growing back grey).
If anyone else is having this issue, this is the fix. I hope it helps someone.
I'd like to be able to press a button to play a sound of a button being pressed while music is already playing. SoundPlayer is no help because it stops the music to play the sound.
I have added the sounds to my Resources (WindowsFormsApplication2.Resources.Properties.button) and I don't want to have to type in the file location.
Answer from MerickOWA
You CANNOT play two sounds at once using SoundPlayer.
SoundPlayer is using the native WINAPI PlaySound function to accomplish the task which has no support for playing simultaneous sounds. Creating multiple instances of SoundPlayer won't help.
There are many options most of which involve implementing a lot of the low level API to window's native audio library or DirectSound (note neither are C# and require alot of interop code)
The simplest option would be to depend on windows media player to play the audio for you.
Add a reference to "C:\Windows\System32\wmp.dll"
then use
var player = new WMPLib.WindowsMediaPlayer();
player.URL = #"..\..\bin\debug\tribal dance.wav";
Note: play starts immediately after setting the URL property
The down side of this approach is your reliance on media player for your application to work properly. On the upside, you can use any file format media player supports.
In C# I cannot get SoundPlayer class from System.Media to play any wav from my C:\Windows\Media folder using the following code. All I get is no sound:
String filename = "C:\\Windows\\Media\\tada.wav";
SoundPlayer sp = new SoundPlayer(filename);
sp.Load();
sp.Play();
I have checked the wave file "tada.wav" with a program called "Gspot" that tells me the audio codec is "PCM Audio". I do not receive any compiler warnings or errors and there is no exceptions raised when I run the program. I just do not get any sound. My speakers are on, and I can play the file with Windows Media Player.
Adding the wav as a project resource does not make any difference. Could somebody please help me figure out why I cannot get any sound?
The Play() method plays the sound a separate thread. That is, the console app spins a new thread in which to play the sound. This is great for Windows applications so that the sound playing does not stop the Windows main thread. In a console app, when the parent thread ends the child threads all die as well. -- thus no sound.
There is a PlaySync() method that does NOT spawn a new thread and thus will keep the console app thread alive until it has finished playing your sound.
Are you using this as the body of a main() method in a console application? The application is probably ending, thereby shutting down the thread which plays the audio.
I copied and pasted your code into the main of a new "Visual C# Console Application". I added the "using System.Text;" line at the top of the file, compiled, stepped through it, and it worked. When I ran it (without debugging) I got no sound.
If you add the line:
System.Threading.Thread.Sleep(2000);
After the call to Play(), the application will stay around long enough to play the audio.
For me (VS 2022, .net 6, C # 10) it worked:
Import the "tada.wav" file into the main directory.
Change in: Properties (tada.wav) - Copy to Output Directory to: Copy always.
Later it was enough to:
SoundPlayer player = new SoundPlayer("tada.wav");
player.Load ();
player.Play ();