SoundPlayer does not play sound first time it´s called - c#

I've a really simple method for playing sound effects:
private void PlaySound(string file)
{
var sp = new SoundPlayer(#"Effects\" + file + ".wav");
sp.Play();
}
Then I do this to call it:
PlaySound("music");
Now, the first time PlaySound("music") gets called, it won't play it. The second time and all the other times after that it will.
Any ideas of what goes wrong here?

Try this:
private void PlaySound(string file){
using (SoundPlayer player = new SoundPlayer(#"Effects\" + file ' ".wav"))
{
// Use PlaySync to load and then play the sound.
player.PlaySync();
}
}
Why use PlaySync? If you just call the Play method in this program, the program will terminate before the sound plays. The Sync indicates that the program should pause while the sound plays.

You need to call the load method before playing.If the the file is not already loaded ,the file will be loaded with a call to Play.Which explains why the file is not played the first time.
If you call Play before the .wav file has been loaded into memory, the .wav file will be loaded before playback starts.-MSDN
Both Load and PlaySync will block the current thread.A better option would be to use the LoadAsync to load the file asynchronously.

Related

Windows Form Not playing any sound on SoundPlayer Class

First of all, My music is .wav file and I'm sure of it; I want to use it as a background music but it doesn't work!
even my sound system windows telling me this form you actually created has no sound.
also I tried these codes below but didn't work!
using (var player = new SoundPlayer("F:\\youtube\\Music\\fl.wav"))
{
// Use PlaySync to load and then play the sound.
// ... The program will pause until the sound is complete.
player.PlaySync();
}
SoundPlayer soundPlayer = new SoundPlayer("F:\\youtube\\Music\\fl.wav");
soundPlayer.Play();

CefSharp detect webm video end

I have a WPF C# application using cefsharp v79.1.360.
The app is happily playing a single local webm file inside the browser.
Now I would like to pass a string of local file names to the app and play them sequentially. Thus when one webm finishes playing the next one in sequence will start. Nothing else is contained in the page, just the webm.
My first thought was to detect when the current webm finishes and then load the next file. I am not seeing any events being thrown or handlers that can do this for me.
I am using the FrameLoadEnd handler for other purposes but it only fires when the webm has finished loading, not when it is done playing.
Anyone know if detecting the ending of a webm video is possible?
My other thought is to load each webm into a stream and play the entire batch.
For user experience purposes I think it would be better to play each one individually, in sequence.
Thanks
Decided the best way to solve the problem was to create an html page that would accept a delimited string of video locations. It handles cycling through the list, playing each one individually. All it had to do was change the src of the video tag when the onended event fired and when the loadPlaylist function below is called.
The C# app passed the playlist to the html via a javascript call:
Browser.FrameLoadEnd += (sender, args) =>
{
//Wait for the Main Frame to finish loading
if (args.Frame.IsMain)
{
var playlist = navigationContext.Parameters[NavigationParameterKeys.WebAddress].ToString();
args.Frame.ExecuteJavaScriptAsync("loadPlaylist('" + playlist +"');");
}
};

How can I play a sound in Console Application in a For loop to sound like somebody is typing?

My biggest problem is that it is only played once in the end of the loop. I was wondering if there is a Pause for loop to play a sound and then continue the loop but I can't find anything like this.
class Feladat
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
int seconds = 3;
public void Udv()
{
player.SoundLocation = "./sounds/type2.wav";
Console.WriteLine();
string szoveg = "Üdvözöllek !";
for (int i = 0; i < szoveg.Length; i++, System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.050)))
{
string current = Convert.ToString(szoveg[i]);
System.Console.Write(current);
player.Play();
}
}
}
I had to Cut off the start of the .wav file, because it was too long for the play intervall. Problem Solved !
From the docs:
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.
Seems loading is not done in time your loop iterates again.
Try moving 'System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.050))' from the loop to after player.Play(); and tell us if it helps.

Clicking a button then playing a sound, pauses the UI and if you spam the button continuously plays? [duplicate]

This question already has answers here:
How to use System.Media.SoundPlayer to asynchronously play a sound file?
(2 answers)
Closed 5 years ago.
I've been trying to get this button to do what I want for a little now. I want it to play a sound when I press it, which is what I managed to do. However, its like the application freezes every time you press the button, giving the sound all of its attention, etc. So basically my goal is to make the button play a sound without making the UI have to stop and allow it to play, before moving on. I also would like to know if there is a way to make a button play sound when pressed, but when pressed again the current sound is stopped and plays again, to prevent it from playing "X" amount of clicks you clicked the button, etc.
Here is my code:
public static void ButtonSound()
{
SoundPlayer _sound = new SoundPlayer();
try
{
_sound.Stop();
_sound.SoundLocation = path + "ButtonTap.wav";
_sound.Load();
_sound.PlaySync();
}
catch
{
}
finally
{
_sound.Dispose();
}
}
And Button code:
private void Button()
{
SoundPlayers.ButtonSound();
}
Note, I have my SoundPlayer in another class, and I am using DelegateCommands to reference my Button() method, etc. I am also using .wav files. Also, is there a more efficient way to achieve that task I am trying to accomplish? If you need anything else, just ask.
Thanks!
Your UI is freezing because that is what you are asking for when you call _sound.PlaySync().
Looking at the SoundPlayer documentation, you could use the Play() method:
Plays the .wav file using a new thread, and loads the .wav file first
if it has not been loaded.
Using this method should also solve the problem of playing the sound repeatedly, since you will no longer be queuing your calls.
Also, what you did there with Try-Finally-Dispose can be simplified with using, so your code would look like this:
public static void ButtonSound()
{
using (var _sound = new SoundPlayer())
{
_sound.SoundLocation = path + "ButtonTap.wav";
_sound.Play();
}
}
Note that your _sound.Stop() doesn't make sense, since you are calling it on a new object, but just calling Play() on a new object will make the old sound stop and then play the new one.
Also, the doc says that Play() loads the file if it has not been loaded, that is why I skipped the _sound.Load() call.

How to check if sound effect is playing (Looping a BG Song)

Here is the setup I am rolling at the moment. Given this, how can I tell when the _BGMusic SoundEfect is over? I am running a game loop that cycles a few times a second and I ultimately want to loop this song.
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
SoundEffect _BGMUSIC;
public Page1() {
...
LoadSound("sfx/piano.wav", out _BGMUSIC);
...
}
private void LoadSound(String SoundFilePath, out SoundEffect Sound) {
// For error checking, assume we'll fail to load the file.
Sound = null;
try {
// Holds informations about a file stream.
StreamResourceInfo SoundFileInfo =
App.GetResourceStream(new Uri(SoundFilePath, UriKind.Relative));
// Create the SoundEffect from the Stream
Sound = SoundEffect.FromStream(SoundFileInfo.Stream);
FrameworkDispatcher.Update();
} catch (NullReferenceException) {
// Display an error message
MessageBox.Show("Couldn't load sound " + SoundFilePath);
}
}
From this code it looks like you have just stored the sound in Sound but you don't show where you implement the Sound.Play() method. While there isn't a Sound.IsPlaying boolean which would probably solve your problem, there is a Sound.Duration property which you may use to solve your problem, especially if you couple that with a Timer (which can be used in tandem to set off a flag to show whether or not the sound is playing.
Also something I have never used but just found is the Sound.IsDisposed property. I would definitely look into this as well because it may be exactly for what you are looking.
Alright so the answer to this question is actually very simple and outlined in Microsoft's MSDN page very nicely (for once).
To implement it with what I have up above currently you need to do the following.
Create a global SoundEffectInstance
SoundEffectInstance _BGMUSICINSTANCE;
In my example I initialize the SoundEffect in my main method so underneath it I want to initialize the SoundEffectInstance.
_BGMUSICINSTANCE = _BGMUSIC.CreateInstance();
Now that the instance is loaded and ready we can set its loop property to true. You can do this also in the main method or wherever you want. It's a global
_BGMUSICINSTANCE.IsLooped = true;
Finally play the song
_BGMUSICINSTANCE.Play();
Reference page
http://msdn.microsoft.com/en-us/library/dd940203(v=xnagamestudio.31).aspx

Categories