In my app I'm using SoundEffect to play some sounds. I want to know if there's a way of knowing when a SoundEffect finished its run so a second one will start right after.
This scenario is not supported out of the box by XNA as far as i know.
The SoundEffect class exposes a Duration property that you might use to achieve what you're after.
Build some "SoundManager" class (basically a simple scheduler), that will do all the fancy coordination of sounds playback.
This class will hit off a SoundEffect playback, scheduling the next one to occur exactly after Duration had elapsed.
the old question, but i had to do the same thing today, i tried the method based on duration but finally stopped with own solution which seems the simplest for me:
1) create static helper class let's say 'SoundsManager' as in lysergic-acid's answer.
2) create a Queue of SoundsEffectInstanses and play first of them ("_sheduledSounds" in code below).
3) Update class with each game loop and check if soundinstance is stopped:
public static void Update()
{
if (_sheduledSounds != null && _sheduledSounds.Count > 1)
{
if (_sheduledSounds.Peek().State == SoundState.Stopped)
{
_sheduledSounds.Dequeue();
_sheduledSounds.Peek().Play();
}
}
}
Set this
BufferDescription.GlobalFocus flag = True;
This will tell a SoundEffect finished its run.
Related
I am playing an Audio use Windows Media Player in c# WinForms. I want to display a message at the end of the audio play back.
I have a separate Audio class for playing audio and in the play method I have written:
Player = new WMPLib.WindowsMediaPlayer();
public static void play()
{
Player.controls.play();
Player.PlayStateChange += new WMPLib._WMPOCXEvents_PlayStateChangeEventHandler(Player_PlayStateChange);
}
private void Player_PlayStateChange(int NewState)
{
if ((WMPLib.WMPPlayState)NewState == WMPLib.WMPPlayState.wmppsStopped)
isComplete=true;
}
public static boolean hasCompleted()
{
return isComplete;
}
here isComplete is a boolean variable initialized to false
In my form, the code for my play button is:
//Play my audio
while(!hasCompleted());
//display message
The problem is that when i click the play button, my application goes into an infinite loop.
However when i do this:
while(!hasCompleted())
MessageBox.Show("Playing");
//display message
It works fine.
Why is this happening?
I dont want to display a message while it's playing.
I tried using:
Player.currentMedia.duration
and duration string property for a timer or Thread.sleep application but the value returned by both is always 0.
I also tried giving a delay of 1-2 seconds before calling the duration property but this doesn't work as some of my audio tracks are just 2 seconds long.
It is not the best way to do so since you are in a busy waiting situation which waste a lot of CPU cycles and may not work as you wish. I would recommend you to use "Event". Here you can find a very basic example:
http://www.codeproject.com/Articles/11541/The-Simplest-C-Events-Example-Imaginable
http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx
Heey,
We created a game with Monogame but we got the following problem.
We got a themesong that plays when you have loaded the game now is the problem that the themesong sometimes plays but sometimes just doesn't. We convert it by the XNA pipeline to a wma and load it into our game with the .xnb together but just sometimes the music doesn't wanna start.
We just use the standard code for starting a song and all of this code does fire.
internal void PlayBackgroundMusic()
{
if (MediaPlayer.GameHasControl)
{
MediaPlayer.Volume = mainVolume;
MediaPlayer.Play(backgroundMusic);
MediaPlayer.IsRepeating = true;
}
}
We also use SoundEffects but these work 100% of the time it's only the song that won't play everytime you start. Windows RT runs it fine by the way.
Make sure that the debugger gets into the if statement through debugging (or remove the statement temporarily). Another possibility might be that the function is running before the game is fully initialized. You could try delaying the function until the game has been fully loaded.
PS: I can't comment on questions yet so here's an answer.
Edit:
Alright, after some messing around with the Song class and looking in the implementation in MonoGame I came to the conclusion that the SoundEffect class is easier to use and better implemented.
backgroundSound = Content.Load<SoundEffect>("alarm");
protected override void BeginRun()
{
// I created an instance here but you should keep track of this variable
// in order to stop it when you want.
var backSong = backgroundSound.CreateInstance();
backSong.IsLooped = true;
backSong.Play();
base.BeginRun();
}
I used this post: using BeginRun override to play the SoundEffect on startup.
If you want to play a song, use the Song class. But make sure you are using ".mp3" instead of ".wma" before converting them into ".xnb".
backgroundMusic = Content.Load<Song>("MainTheme");
MediaPlayer.Play(backgroundMusic);
MediaPlayer.IsRepeating = true;
See MSDN.
I'am building a game in C#/XNA, it is an top-view racing game and I want to play a sound effect, when my car bumps into a wall.
The problem is that my sound keeps looping so, when I hit a wall, the song will instantly start playing, but I want it to play, and when it is finished playing, then it can be played again.
Here is the code that takes care of the collision:
if (map[x][y] == 0)
{
car.speed = 0;
crash.Play(); }
Please ask me if I'am not clear about something.
Thanks in advance!
Here is the complete answer to your questions: http://msdn.microsoft.com/en-us/library/dd940203.aspx
SoundEffectInstance instance = soundEffect.CreateInstance();
instance.IsLooped = true;
However, by default, SoundEffect should not be looped...
Call SoundEffect.CreateInstance() to get a SoundEffectInstance. Then set the IsLooped property to false before you call Play:
crashSoundEffectInstance.IsLooped = false;
You may want to look into the SoundEffectInstance class. Here's an example on how to use it properly.
You can check if the sound effect state to see if it's currently playing
Edit: I've added a more complete code, as I felt it was needed. It's roughly the same example as in the link I've provided. (Note: This code is untested)
//In your content load
SoundEffect crash;
crash = Content.Load<SoundEffect>("PathToYourSoundEffect");
SoundEffectInstance sei = crash.CreateInstance();
//In your update code
if(sei.State == SoundState.Stopped || sei.State == SoundState.Paused)
{
sei.Play();
}
I'm writing an application using C#/Windows Presentation Foundation.
It is visualizing the steps of a dance with foot shapes.
Currently I'm playing the music as WAV-file and timing the steps with a Timer.
Because of the irregularities of a Timer the music is not in sync with the steps.
I need some kind of synchronization, this is why I wanted to use MIDI-files.
To sync the steps I need an event for each time in the music and would then show the next step. In this case I wouldn't use the Timer anymore.
I already looked at NAudio. I found tutorials for playing MP3-files which don't help me. I created a MidiFile-object but I don't know how to play it. I know that a MIDI-file contains information on how to play the music (for synthesizers) but I don't want to implement my own player.
What is a simple way to play a MIDI-file with NAudio?
How can I receive Events in each time of the music?
Is there an alternative to NAudio that can probably help me better?
Is there an alternative to MIDI that can sync to my visualization?
I am thankful for every kind of help. I've been searching for a while and think that I am maybe looking in the wrong direction.
With DryWetMIDI (I'm the author) playing MIDI files along with firing played events is pretty simple:
namespace SimplePlaybackApp
{
class Program
{
private static Playback _playback;
static void Main(string[] args)
{
var midiFile = MidiFile.Read("The Greatest Song Ever.mid");
var outputDevice = OutputDevice.GetByName("Microsoft GS Wavetable Synth");
_playback = midiFile.GetPlayback(outputDevice);
_playback.EventPlayed += OnEventPlayed;
_playback.Start();
SpinWait.SpinUntil(() => !_playback.IsRunning);
Console.WriteLine("Playback stopped or finished.");
outputDevice.Dispose();
_playback.Dispose();
}
private static void OnEventPlayed(object sender, MidiEventPlayedEventArgs e)
{
// ... do something
}
}
}
More info in Playback article and Playback API reference.
If you want to get deeper into the midi internals this looked like a pretty cool library and source code to explore.
http://code.google.com/p/midi-dot-net/
I know I can reference XNA for the SoundEffect class and that's what I've been doing so far but I was wondering if there was a better way than what I've been doing.
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using (var stream = TitleContainer.OpenStream("test.mp3"))
{
var effect = SoundEffect.FromStream(stream);
FrameworkDispatcher.Update();
effect.Play();
}
For my test app I have 20 sounds each 1 second long that I want to play once button are pressed. I'm playing around with different techniques but if possible I'd like to know how professionals go about doing this before I commit in making a sound effect based app. Little things such as loading the sound effect first or loading it the instance the button is pressed would be helpful.
Thanks.
If I were you I would use PhoneyTools SoundEffectPlayer
This class is used to play SoundEffect
objects using the XNA integration. The
player must live long enough for the
sound effect to play so it is common
to have it scoped outside a method.
For example:
public partial class MediaPage : PhoneApplicationPage
{
// ...
SoundEffectPlayer _player = null;
private void playButton_Click(object sender, RoutedEventArgs e)
{
var resource = Application.GetResourceStream(new Uri("alert.wav", UriKind.Relative));
var effect = SoundEffect.FromStream(resource.Stream);
_player = new SoundEffectPlayer(effect);
_player.Play();
}
}
I think a good example would be the official sample on AppHub. It demonstrates how to play multiple sounds. You can directly download the sample from here.
This sample demonstrates how to use
the XNA Framework's SoundEffect and
SoundEffectInstance classes to play
multiple sounds simultaneously in a
Silverlight application for Windows
Phone. It also shows a simple way to
set up a DispatchTimer to call
FrameworkDispatcher.Update in order to
simulate the Game loop for the XNA
Framework's internals. Finally, it
shows how to load a wave audio file
into a Stream that can be played by
the SoundEffect classes.