Stopping a SoundPlayer loop at the local level - c#

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.

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 can I play a sound with defined start- and end-time in .Net

In my C# project I want to play a sound with a specified start- and end time.
I used the System.Media.SoundPlayer with the .Play() function. But with this function I can only play the whole sound file or can abort it after I have counted the runtime.
In fact I want to say, that the given sound file should start for example at time 1m:25s:30ms and should end at time 1m:50s:00ms or after a duration of 10s or so.
Does anybody know a simple solution for his problem?
Thanks 4 help.
Not really an answer, but this question got me wondering if you can do something like this:
long startPositionInBytes = 512;
long endPositionInBytes = 2048;
using ( var audioStream = File.OpenRead(#"audio.wav") )
{
audioStream.Position = startPositionInBytes;
using ( var player = new SoundPlayer(audioStream) )
{
player.Play();
do
{
Thread.Sleep(1);
} while ( audioStream.Position <= endPositionInBytes );
player.Stop();
}
}
In case you want to play a Background Media Player (for e.g., an audio file) which would start from a specific time and would work for a certain duration, then this code snippet could also be useful:
StorageFile mediaFile = await KnownFolders.VideosLibrary.GetFileAsync(fileName);//the path
BackgroundMediaPlayer.Current.SetFileSource(mediaFile);
BackgroundMediaPlayer.Current.Position = TimeSpan.FromMilliseconds(3000/*enter the start time here*/);
BackgroundMediaPlayer.Current.Play();
await Task.Delay(TimeSpan.FromMilliseconds(10000/*for how long you want to play*/));
BackgroundMediaPlayer.Shutdown();//stops the player
**But this would only work for Windows 8.1 and above.
For more information, click here...
In the End I use the NAudio library. That can handle this - not in a perfect way but ok.
see https://stackoverflow.com/a/13372540/2936206
I got it to work by using Windows Media Player in a C sharp program with a timer control and an open dialog.
I followed a sample that used buttons on the form and made the media player invisible.
After opening the file with an Open button that used the open dialog to open the mp3 file, on the Play button I put this code [the end effect is that it started the file in position 28.00 and ended it in position 32.50]:
private void button2_Click(object sender, EventArgs e)
{
axWindowsMediaPlayer1.URL = openFileDialog1.FileName;
timer1.Start();
axWindowsMediaPlayer1.Ctlcontrols.currentPosition = 28.00;
axWindowsMediaPlayer1.Ctlcontrols.play();
}
Then in the timer tick event:
private void timer1_Tick(object sender, EventArgs e)
{
if (axWindowsMediaPlayer1.Ctlcontrols.currentPosition >= 32.50)
{ axWindowsMediaPlayer1.Ctlcontrols.pause(); }
label1.Text = String.Format("{0:0.00}",
axWindowsMediaPlayer1.Ctlcontrols.currentPosition);
}

Playing multiple sounds using muliple buttons

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.

Categories