Song doesn't play all the time in Monogame - c#

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.

Related

Unity Start nog called on real build

I've made a dice app as a project to learn to work with unity (it was so good in my eyes that I put it on the google play store) but when I downloaded it from there, the Start function of at least 2 scripts isn't called and I have no idea whether the other Start functions are being called.
Here you can see 2 of the Start functions that aren't called
void Start()
{
light = light.GetComponent<Light>();
GetComponent<Button>().onClick.AddListener(TaskOnClick);
rawImage = GetComponent<RawImage>();
isLockMode = false;
rawImage.texture = getIconLock(isLockMode);
}
void Start()
{
Screen.fullScreen = false;
Dice.AddDie();
Input.gyro.enabled = true;
GlobalConfig.onShowShadowsChanged += onShadowsEnabledChange;
}
They work when I use Unity Remote on my smartphone and they also work when I just use unity without the remote...
the first script is attached to a UI element and the second script is attached to an empty GameObject called 'App'
It's also even more weird because they used to work but then I switched pc's (but used the same code).
I think something is wrong with the building itself
Found out the problem, the build was generating two files, an .apk and an other .odb or somethingl ike that (might be another extension). I had to untick 'split application binary' in the player settings

Stop the SoundEffect from looping

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();
}

MonoTouch: Playing sound

I am trying to play a short sound when user taps on the specific button. But the problem is that I always receive Object reference not set to an instance object. means Null!
I first tried MonoTouch.AudioToolBox.SystemSound.
MonoTouch.AudioToolbox.AudioSession.Initialize();
MonoTouch.AudioToolbox.AudioSession.Category = MonoTouch.AudioToolbox.AudioSessionCategory.MediaPlayback;
MonoTouch.AudioToolbox.AudioSession.SetActive(true);
var t = MonoTouch.AudioToolbox.SystemSound.FromFile("click.mp3");
t.PlaySystemSound();
Let me notice that "click.mp3" is in my root solution folder and it is flagged as Content.
The other approach is MonoTouch.AVFoundation.AVAudioPlayer.
var url = NSUrl.FromFilename("click.mp3");
AVAudioPlayer player = AVAudioPlayer.FromUrl(url);
player.FinishedPlaying += (sender, e) => { player.Dispose(); };
player.Play();
But same error. I googled it and I see that many people has this problem. We need to know whether it is a bug or not.
About using SystemSound and MP3 see this question and answer: Playing a Sound With Monotouch
For AVAudioPlayer be aware that the following pattern is dangerous:
AVAudioPlayer player = AVAudioPlayer.FromUrl(url);
player.FinishedPlaying += (sender, e) => { player.Dispose(); };
player.Play();
since Play is asynchronous. This means the managed player instance can get out of scope before FinishedPlaying occurs. In turn this out of scope means the the GC could already have collected the instance.
A way to fix this is to promote the player local variable into a type field. That will ensure the GC won't collect the instance while the sound is playing.
Your code looks correct (I compared to the code here, which is able to play audio).
What might be the problem is that the audio file isn't included in the app bundle somehow. You can easily check it with this code:
if (!System.IO.File.Exists ("click.mp3"))
Console.WriteLine ("bundling error");
In most cases it would be the File does not exist. If you are like me, and you made sure that the file exists. Ensure the following:
The Path of the file should be relative to your Class (ie: Sounds\beep.wav) (Absolute path did not work for me on the simulator)
Ensure that you are defining the SoundSystem in the class level. This is because MT has a ver agressive Garbage Collector and could dispose your SoundSystem before it even starts playing. see this question

What to use for playing sound effects in silverlight for wp7

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.

Playing a second SoundEffect after the first one has finished

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.

Categories

Resources