Playing multiple sounds using muliple buttons - c#

How to make multiple buttons play different sounds one at a time and have a common stop button using Windows Phone XNA framework? When a sound is played, it should play looped until one hits the stop button or hits another button.
The way I used SoundEffect with CreateInstance, it looped and played fine but when a second button is clicked, the second sound starts playing along with the first. Also need help with creating the common stop button. Thanks a lot in advance.
I was trying something like below for each button.
private void button2_Click(object sender, RoutedEventArgs e)
{
var stream = TitleContainer.OpenStream("Sounds/A3.wav");
var effect = SoundEffect.FromStream(stream);
SoundEffectInstance instance = effect.CreateInstance();
instance.IsLooped = true;
instance.Play();
But since the instance created isn't on a program-wide level, I'm having trouble creating a common stop button.
I'm a beginner in programming. Thank you for your understanding.

You can add a member variable to your class and some helper methods:
public class YourClass
{
private SoundEffectInstance currentSoundEffect = null;
private void StopCurrentSoundEffect()
{
this.currentSoundEffect.Stop();
this.currentSoundEffect = null;
}
private void PlaySoundEffect(string fileName)
{
this.StopCurrentSoundEffect();
using (var stream = TitleContainer.OpenStream("Sounds/A3.wav"))
{
var soundEffect = SoundEffect.FromStream(stream);
this.currentSoundEffect = soundEffect.CreateInstance();
this.currentSoundEffect.IsLooped = true;
this.currentSoundEffect.Play();
}
}
}
Now, each of your event handlers can just call this.PlaySoundEffect with the desired file name.

Related

C# repeating a mp3 file once it has finished

In my current project, i have music that plays depending on the gamestate. Like most games, once the soundtrack ends it then repeats. I'd like to implement such feature into my game so it automatically plays however i'm uncertain where i'd start.
The code/algorithm must acknowledge the fact that the soundtrack has ended and repeat baring in mind that it also will have more code connected to it once i create the gamesettings and sounds sub menu where the user is able to change the sounds etc. This is what i have so far:
static public WindowsMediaPlayer Introthemetune = new WindowsMediaPlayer();
public LaunchScreen()
{
this.Opacity = 0;
InitializeComponent();
Introthemetune.URL = "Finalised Game Soundtrack.mp3";
}
You can do this in two ways,
1. Subscribe to PlayStateChange Event
You would need to subscribe to PlayStateChange event and check the NewState
Introthemetune.PlayStateChange += Introthemetune_PlayStateChange;
private void Introthemetune_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
if(e.newState == 8)
{
// Play Again
}
}
You can read more on the different play states here
2. Set Loop Mode.
The most easiest approach would be to set the loop mode.
Introthemetune.settings.setMode("loop", true);
Introthemetune.URL = "Finalised Game Soundtrack.mp3";
This would ensure the track is played repeated continuously.

C# winforms Windowsmovieplayer not finding mp3 resource

For my project i'm implementing mp3 soundtracks using WindowsMediaPlayer library, to particular areas of the game. I've successfully implemented one already for the "launchscreen" and navigational menus.
I've copied the exact code and added it to my new "GameScreen" form but haven't had any success with finding the Soundtrack itself. When i put in the other Soundtrack into the other URL property it works perfectly fine which makes me believe it doesn't find it in the directory. What makes me believe this further is when i put the Mercury Soundtrack into the "Launchscreen" form it doesn't work also. I've also tried adding the whole path to the file from file explorer but it doesn't agree with the backslashes and so that is also not viable.
Here is the code that i have working at the moment. Its globally accessible because it's stops in a different form
static public WindowsMediaPlayer Introthemetune = new WindowsMediaPlayer();
public LaunchScreen()
{
this.Opacity = 0;
InitializeComponent();
Introthemetune.URL = "Finalised Game Soundtrack.mp3";
}
private void Gamescreen_Load(object sender, EventArgs e)
{
Introthemetune.controls.play(); //only plays once need on loop
}
Here's the exact same code but with the different soundtrack and yet it doesn't work.
WindowsMediaPlayer MercuryTheme = new WindowsMediaPlayer(); //instantiating new class containing the mercury themetune
public MercuryGameScreen()
{
this.Opacity = 0;
InitializeComponent();
MercuryTheme.URL = "Mercury Soundtrack.mp3";
}
private void MercuryGameScreen_Load(object sender, EventArgs e)
{
MercuryTheme.controls.play(); //only plays once need on loop
}
I want it to simply player the soundtrack.
Any help is greatly appreciated as this has me severely perplexed.

My Music Player showing multiple instances of the same form, for each track

I am trying to create a simple media player that just runs from the notifyIcon tray using a context menu strip, sitting on an hidden form.
When I click on the menu item 'play mp3's' it opens up a folder, allowing me to select a bunch of mp3 tracks. These tracks are stored in a listbox on the hidden form allowing me to manipulate them through the C# code. The code I have will always play the first song, no problem, but the ones after that has been a pain.
The way I found to make the songs continue to play was by using ShowDialog for each song, but as you guessed that means there are multiple instances of the same form. Soon as I stop using the show.dialog, I am back to one song again. Is it because I am using the WMPLib without the actual player on the form, I am sure that is not the case. I have managed to pick up tons of knowledge on here to get me this far, like using PlayStateChange, being able to select the next Item in the list box and how to play a song list. Unfortunately most of the time this is with using the media player console and buttons.
Here is the specific code that is causing the issue, as it stands it plays every track, soon as I comment out showdialog, it only plays the first song.
private void trackplayer()
{
listBox1.SelectedIndex = listBox1.SelectedIndex + 1;
var selectedUrl = listBox1.SelectedItem.ToString();
player.URL = selectedUrl;
player.controls.play();
mytempFormOpen();
}
public void mytempFormOpen()
{
var myform1 = new Form1();
myform1.ShowDialog();
}
Could you please help a frustrated newbie, any questions I am happy to respond to.
Here is my FormLoad section
#region check internet when form opens
private void Form1_Load(object sender, EventArgs e)
{
notifyIcon1.Text = (playingToolStripMenuItem.Text);
checkTheInternet();
}
#endregion
Here is the Internet Checker Code called from the loadform
#region Check for Internet Connection Loop
private void checkTheInternet()
{
while (true)
{
bool con = NetworkInterface.GetIsNetworkAvailable();
if (con == false)
{
MessageBox.Show("No Internet Connection!");
playingToolStripMenuItem.Text = "No Internet Connection!";
notifyIcon1.Icon = radio_Off;
notifyIcon1.Visible = true;
return;
}
else
{
return;
}
}
}
#endregion
This is where the file selection starts
region Play MP3 List Automatically
private void mP3ToolStripMenuItem_Click(object sender, EventArgs e)
{
player.PlayStateChange += new WMPLib._WMPOCXEvents_PlayStateChangeEventHandler(player_PlayStateChange);
string[] files, paths;
OpenFileDialog oFD = new OpenFileDialog();
oFD.Multiselect = true;
oFD.Filter = "Music Files |*.mp3;*.wav";
if (oFD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
pauseToolStripMenuItem.Visible = true;
files = oFD.SafeFileNames;
for (int i = 0; i < files.Length; i++)
{
listBox1.Items.Add(paths[i]);
myCount = i + 1;
}
trackplayer();
}
}
If opening a new form is needed to play your song, I am not sure why since I do not have all your code, but you do not want multiple forms then do this. Create a private field which will hold a reference to your form:
private Form1 prevForm;
Change your myTempFormOpen to:
public void mytempFormOpen()
{
if (prevForm != null)
{
prevForm.Close();
}
prevForm = new Form1();
prevForm.ShowDialog();
}
Also myTempFormOpen should be MyTempFormOpen to follow .NET naming conventions.
Also in checkInternet method, you can return right away if connection is true instead of checking false first. Also, not sure why you need the while loop.
Let me know if that solves your issue.
I eventually found the answer by using a timer. The answer to the solution can be found here How to detect when a mp3 file has finished playing Big Thanks to all those that helped.

How do I play two sounds one after the other in a Windows Forms application?

I want to play two sounds one after the other in reaction to a button click. When the first sound finishes, the second sound should start playing.
My problem is that every time the button is clicked these two sounds are different and I don't know their lengths in order to use Thread.Sleep. But I don't want these sounds to play on top of each other.
Sounds like you're after the PlaySync method of SoundPlayer class.. first add this on top:
using System.Media;
Then have such code:
SoundPlayer player = new SoundPlayer(#"path to first media file");
player.PlaySync();
player = new SoundPlayer(#"path to second media file");
player.PlaySync();
This class is available since .NET 2.0 so you should have it.
The MediaPlayer has MediaEnded event. In the event handler, just start the new media and they should play back to back.
protected System.Windows.Media.MediaPlayer pl = new MediaPlayer();
public void StartPlayback(){
pl.Open(new Uri(#"/Path/to/media/file.wav"));
pl.MediaEnded += PlayNext;
pl.Play();
}
private void PlayNext(object sender, EventArgs e){
pl.Open(new Uri(#"/Path/to/media/file.wav"));
pl.Play();
}
In Shadow Wizards example, it's not necessary to make a new soundplayer each time.
This also works:
player.SoundLocation = "path/to/media";
player.PlaySync();
player.SoundLocation = "path/to/media2";
player.PlaySync();
Example Using NAudio
private List<string> wavlist = new List<string>();
wavlist.Add("c:\\1.wav");
wavlist.Add("c:\\2.wav");
foreach(string file in wavlist)
{
AudioFileReader audio = new AudioFileReader(file);
audio.Volume = 1;
IWavePlayer player = new WaveOut(WaveCallbackInfo.FunctionCallback());
player.Init(audio);
player.Play();
System.Threading.Thread.Sleep(audio.TotalTime);
player.Stop();
player.Dispose();
audio.Dispose();
player = null;
audio = null;
}

Stopping a SoundPlayer loop at the local level

I'm working on setting up an alarm that pops up as a dialog with multiple sound file options the user can choose from. The problem I'm having is creating a sound player at the local level that I can close with a button. The problem I'm having is that the sound keeps looping when I close the form because the SoundPlayer doesn't exist within the button click event.
here's what I have:
void callsound()
{
if (SoundToggle == 0) // if sound enabled
{
if ((SoundFile == 0) && (File.Exists(#"attention.wav")))
{
System.Media.SoundPlayer alarm = new System.Media.SoundPlayer(#"attention.wav");
alarm.PlayLooping();
}
if ((SoundFile == 1) && (File.Exists(#"aahh.wav")))
{
System.Media.SoundPlayer alarm = new System.Media.SoundPlayer(#"aahh.wav");
alarm.PlayLooping();
}
}
private void button1_Click(object sender, EventArgs e)
{
//alarm.Stop(); Only works if SoundPlayer declared at class level
this.Close();
}
Is there a way I can do what I want to do by declaring the SoundPlayer instances where I am? Or is there a way to declare it at the class level, and still be able to change the sound file based on user settings?
Why is this a problem? SoundPlayer doesn't support playing more than one sound at the same time anyway. Move it to class scope, override OnFormClosing event, problem solved.
public partial class Form1 : Form {
private System.Media.SoundPlayer alarm;
protected override void OnFormClosing(CancelEventArgs e) {
if (alarm != null) alarm.Stop();
}
}
You can try:
SoundMixer.stopAll();
or
SoundMixer.soundTransform = new SoundTransform(0);
The SoundMixer class controls global sound, so it should stop everything in the same security sandbox.
Using Powershell, I was playing with playing .wav files and started a repeating loop using the following:
$Playwav = new-object ('Media.SoundPlayer') $playpath1
$Playwav.PlayLooping()
I stopped the loop inside Powershell IDE by Run Section (F8):
$Playwav = new-object ('Media.SoundPlayer') $playpath1
$Playwav.PlayLooping()
$Playwav.stop()
FWIW, the .wav in my example was FPS Doug takethatbitch.wav. So the runaway loop made me laugh.
Hope this helps.

Categories