A song in XNA cuts off - c#

My code:
Variables:
//Menu Song
Song mainMenuTheme;
bool songstart = false;
LoadContent() method:
//Load the song
mainMenu = Content.Load<Song>("musics\\mainMenuTheme");
MediaPlayer.IsRepeating = true;
In the Update() method:
//Start the song
if (!songstart)
{
MediaPlayer.Play(mainMenuTheme);
songstart = true;
}
So the song is in .wma format, 6.32MB and the duration is 00:01:36. How to make the WHOLE song loop? Because when I start debugging it cuts off after a while and loops again. Any suggestions?

Try using .mp3 instead of .wma for Song class.
Your code seems corrert.

Related

How to play Multiple sound files from the properties using Sound Player

i am making a quiz and in each form i have background music and if they get an answer correct i want to play a sound effect. When i do this is stops the background music and plays the sound effect then no sound is playing, does anyone know how do it?
public static System.Media.SoundPlayer player = new System.Media.SoundPlayer();
public static void sound(string form)
{
switch (form)
{
case "Login":
player.Stop();
player.Stream = Properties.Resources._2marioloadscreen;
player.PlayLooping();
break;
}
}
Here's an example of how to do it, assuming you have two wav files (one for background music, and one for the correct answer sound effect). The key is to know when the sound effect is done playing, then continue with the background music again.
I wrote it as a simple C# Console App.
class Program
{
private static SoundPlayer player;
static void Main(string[] args)
{
using (player = new SoundPlayer())
{
player.SoundLocation = "bkgnd.wav";
player.PlayLooping();
Console.WriteLine("bkgnd.wav is now playing in a loop. (Hit ENTER key to start the hoorayyouwon.wav)");
Console.ReadLine();
Console.WriteLine("hoorayyouwon.wav is now playing.");
player.Stop();
player.SoundLocation = "hoorayyouwon.wav";
player.PlaySync(); // this ensures the hoorayyouwon.wav plays completely before it gets to the next line of code.
Console.WriteLine("bkgnd.wav is now continuing (actually, starting over). (Hit ENTER key to exit)");
player.SoundLocation = "bkgnd.wav";
player.PlayLooping();
Console.ReadLine();
}
}
}

c# - how to remove the interval between two timer ticks

I am using timer to connect several audio files together. There are a list of audio files and the timer will read files one by one. Once there is an audio read, it will be played. The goal is to play the audio file right after the previous one when it is finished(without any break).
(I am using Naudio)
Here is the code:
private void timer_key_Tick(object sender, EventArgs e)
{
if(!isPlaying)
{
//play the current audio
DirectSoundOut dso = sounds2[key_indexer];
dso.Play();
targetMusics.Add(dso);
}
else
{
foreach (DirectSoundOut dso in targetMusics)
{//stop the current audio
dso.Stop();
}
targetMusics.Clear();
key_indexer++; //switch to the next audio
if (key_indexer >= myMT.Keys.Count)
{
key_indexer = 0;
timer_key.Stop();
}
}
isPlaying = !isPlaying;
}
However, the fact is, when the first music finished, the second one didn't play at once. It comes after one second break. Is this the problem about timer itself? How should I change it?
Thanks for the help from #HansPassant. I made a mistake about logic in this timer. Here is the correct code after I applied his suggestion:
//stop the current playing
foreach(DirectSoundOut d in targetMusics)
{
d.Stop();
}
targetMusics.Clear();
//stop the entire process
if (key_indexer >= myMT.Keys.Count)
{
key_indexer = 0;
timer_key.Stop();
}
else
{ //play the current audio
DirectSoundOut dso = sounds2[key_indexer];
targetMusics.Add(dso);
dso.Play();
key_indexer++;
}

Playing music from collection with SoundPlayer

So I am doing a simple piano and trying to traverse the collection where I stored the notes, but the SoundPlayer doesn't want to play them properly in "without debugging mode", playing only the last one. However when I put a breakpoint there it plays all of them
public static List<MusicNote> music = new List<MusicNote>(15);
public static void PlayAll()
{
SoundPlayer sp = new SoundPlayer();
for (int i = 0; i <= music.Count - 1; i++)
{
string text = music[i].pitch.ToString();
sp.SoundLocation = (#"c:\my path here\" + text + ".wav");
sp.Play();
sp.Stop();
}
}
Pitch is simply ordinal number to link to file.
Thanks in advance
U better use PlaySyn in order to tell your program to wait until the music complete
// Create new SoundPlayer in the using statement.
using (SoundPlayer player = new SoundPlayer())
{
for (int i = 0; i <= music.Count - 1; i++)
{
string text = music[i].pitch.ToString();
sp.SoundLocation = (#"c:\my path here\" + text + ".wav");
// Use PlaySync to load and then play the sound.
// ... The program will pause until the sound is complete.
player.PlaySync();
}
}
I think its better when you use PlaySync(); instead of Play();
Because then you don't need the Stop() methode.
Here a link to the docu of SoundPlayer
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.

How to get the duration of mp3 file without playing or storing them

I am building a wp8 app which could play poems line by line displayed in listbox.
Say I have 20 lines of Poems showing as 20 items in listbox. I have 20 mp3 files (one for each line), I used BackgroundAudioPlayer to play individual files and select each item (poem) in listbox. During playback of these mp3 files, there were delays of 1-3 seconds, so I found the full version of these mp3 files (20 files merged into one), reading poems line by line.
I am playing this mp3 file using BackgroundAudioPlayer. Playing as one file, I cannot select each item in listbox as I don't know the line number by playing one mp3 file.
Now what I want is to store the duration of 20 files in seconds, without storing and playing. The files are located in a link (http:123.com/1.mp3, /2.mp3, ...)
I used AudioTrack with absolute path and then used duration property, but it always returns zero. How can I get the duration of an mp3 file without playing them?
Edited:
In the background Agent I did below:
protected override void OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState)
{
switch (playState)
{
case PlayState.TrackReady:
TrackDuration tr = DataSource.Connection.Table<TrackDuration>().SingleOrDefault();
if (tr.IsGetTrackDuration)
{
if (player.Track != null)
{
player.Position = TimeSpan.FromSeconds(player.Track.Duration.TotalSeconds);
Recitation r = DataSource.Connection.Query<Recitation>("select * from Recitation where ID = " + player.Track.Title).SingleOrDefault();
r.AyaDuration = player.Track.Duration.TotalSeconds;
DataSource.saveRecitionDownloaded(r);
PlayNextTrack(player);
}
}
break;
}
NotifyComplete();
}
protected override void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param)
{
switch (action)
{
case UserAction.Play:
PlayTrack(player);
break;
case UserAction.Seek:
if (null!=player.Track)
player.Position = (TimeSpan)param;
break;
}
NotifyComplete();
}
private void PlayNextTrack(BackgroundAudioPlayer player)
{
if (++currentTrackNumber >= audioTrack.Count)
return;
PlayTrack(player);
}
private void PlayTrack(BackgroundAudioPlayer player)
{
//If No Track then load Track
if (audioTrack.Count == 0)
{
//Load Tracks and Add them into Track Play List
}
if ((player.Track == null) || (player.Track.Title != audioTrack[currentTrackNumber].Title))
player.Track = audioTrack[currentTrackNumber];
if ((player.Track != null) && (player.PlayerState != PlayState.Playing))
player.Play();
}
The question is It plays some of the files which I don't want. (tr.IsGetTrackDuration) is always true, but I don't know why it plays some?
MusicProperties class has a property for the duration
MusicProperties musicProperties = await file.Properties.GetMusicPropertiesAsync();
outputText.AppendLine("Duration: " + musicProperties.Duration);
Ok I have a thought here. Under the AudioPlayer class, there is a TrackReady event that is set by default to play the track. Instead of playing by default, set a bool to true if you're simply wanting to obtain the duration, and false if you actually wish to play a track (when you're wanting to play the full mp3).
The bool value would have to be set in the main app before the track is set, and then read in the AudioPlayer each time the OnPlayStateChanged is called.
protected override void OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState)
{
//read GettingDuration value here
try
{
switch (playState)
{
case PlayState.TrackReady:
if (GettingDuration)
{
//store duration somehow and get the next track in line
}
else
{
player.Play();
}
break;
}
}
}

Why is my background music not looping?

Dose anyone have any idae why this code is not working for my background music to constantly loop??
In load Content:
backgroundMusic.Play(0.3f, 0.0f, 0.0f); //play background music (first float number is for volume)
In update:
SoundEffectInstance instance = backgroundMusic.CreateInstance(); //creates instance for backgroundMusic
instance.IsLooped = true; //states that instance should loop meaning background music loops and never stops
Thanks in advance
Edit: I now have this:
Content Load:
Song backgroundMusic = Content.Load<Song>("backgroundMusic");
and then seperately:
public void PlayMusicRepeat(Song backgroundMusic)
{
MediaPlayer.Play(backgroundMusic);
MediaPlayer.IsRepeating = true;
}
If you need to manage the backgroud music you should use the Song class, SoundEffect should be used only for sound effects.
Something like this:
public void PlayMusicRepeat(Song song)
{
MediaPlayer.Play(song);
MediaPlayer.IsRepeating = true;
}
Of course the loading should be like this:
Song music = Game.Content.Load<Song>("background");
You are playing the SoundEffect, but looping the SoundEffectInstance, that won't work.
And following this article from Microsoft (http://msdn.microsoft.com/en-us/library/dd940203.aspx), you have to set the IsLooped property BEFORE playing the sound.
So your code should look like this:
In LoadContent:
instance = backgroundMusic.CreateInstance();
instance.IsLooped = true;
In Update:
if(instance.State == SoundState.Stopped)
instance.Play();

Categories