How do I prevent audio overlap? - c#

Sorry for the title. I couldn't think of a better one. Also, sorry for my English.
I have these four forms. Forms 2-4 have a button that when pressed will play a specific sound from Form 1. There are times that all buttons from the three forms will be pressed almost the same time which causes the audio played from Form 1 overlap each other. How do I prevent this?
Edit:
When all buttons are pressed, I want the audio to "take turns" on being played. "Audio 2, 3" must wait for "Audio 1" to finish playing before they play, and then Audio 3" must wait as well for "Audio 2" to finish. Each "Audio playback" is composed of a SpeechSynthesizer (played using .SpeakAsync) and a SoundPlayer (played using .PlaySync). There's an internet outage on my ISP so I'm just using my phone. It would be quite hard to manually type the code on my phone so sorry for that.

Hi I did a similar thing with a game I made where I had the problem of sounds playing over the top of eachother. In the method that dealt with the sounds, I did this:
SoundPLayer sound = new SoundPlayer(..);
SoundPLayer anotherSound = new SoundPlayer(..);
public async void gameMethod()
{
sound.Play();
await Task.Delay(400); //length of sound
//some code ...
anotherSound.Play();
}
This worked for me and just used await Task.Delay(..) to add more time around sounds - not sure if this is the way to do this but it might be helpful

Related

Controlling Sounds in audio in multiple forms

I want to play a playlist in the resources folder for a windows forms project I'm working on (wav or mp3). The application will be completely offline. (actually a game project)
What I want to do is this:
I need to be able to stop or convert a music that I created in one form to another sound file, depending on the situation.
In this case, I couldn't figure out how to write a code block. There are many examples that describe how we can pause and start the music on single form, but I have not come across an example that covers the whole project and can be intervened from different forms.
I'm not sure if I explained exactly what I wanted to ask, but I can give an example as follows. Let's say I created 3 forms.
1st form and 2nd form game menus.
In these menus, the same music should continue to play.
But when I reach the 3rd form, this music should be cut and replaced with in-game music.
What I want to ask is: How can I control the music I created in form 1, in form 2 or form 3?
The reason I don't use the soundplayer class is because I have to play multiple sounds at once.
i.e., somehow I need to make the music player "static" so that I can control it from all forms, but I couldn't find the way around it.
var importer = new RawSourceWaveStream(Properties.Resources.sound, new WaveFormat());
var soundFx = new WaveOut();
soundFx.Init(importer);
soundFx.Play();
For example, in this way, I start playing the music in the form1. I need to give the command to change this music in the form3, but somehow I cannot reach the "soundfx" object that I defined there because I cannot make this process static.
I think that your intuition is valid. It is probably not the best way, but I inffer that it is a way that you would manage to do.
Have a public static class, that holds a private (or public) instance of you sound player. Have public static methods of the different things that you want to do with the audio player.
Control that class from all forms.
Since this is your intuition. I am curious of what have you so far in this way?
Anyhow, I have a few questions.
When you say "convert" the music, what do you mean?
What do you mean that you couldnt find a way around it?
Can you add some code of how you are controlling the sounds? With some code, people will be able to better support you.
It is recommended that you use MediaPlayer. From your description, MediaPlayer can better meet your needs. Compared with SoundPlayer, MediaPlayer has the following characteristics:
Multiple sounds can be played at the same time (create multiple MediaPlayer objects);
You can adjust the volume (Volume property);
You can use Play, Pause, Stop and other methods to control;
You can set the IsMuted property to True to achieve mute;
You can use the Balance property to adjust the balance of the left and right speakers;
The speed of audio playback can be controlled through the SpeedRatio property;
The length of the audio can be obtained through the NaturalDuration property, and the current playback progress can be obtained through the Position property;
Seek can be performed through the Position property;
Use MediaPlayer to play audio files as follows:
MediaPlayer player = new MediaPlayer();
player.Open(new Uri("BLOW.WAV", UriKind.Relative));
player. Play();
A MediaPlayer object can only play one file at a time. And the file is played asynchronously, you can also call Close to release the file.
For details, please refer to https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.mediaplayer?view=windowsdesktop-7.0
When using it in VS, you need to perform the following steps first:
This way you can find MediaPlayer in the toolbar.
If you still have any questions please speak up.

How to make a smooth moving Audio-Slider in Xamarin.Forms

How can one make a smooth moving audio player in Xamarin.Forms? Thats what i tried:
Using an MediaPlayer to play Audio-Files. Media-Player is used within
a Service called "AudioPlayer".
The property "AudioPosition" is bound to the value of the slider.
There is a cancellation token used to cancel the playing.
Code looks like:
await Task.Run(
() =>
{
while (!ct.IsCancellationRequested)
{
this.AudioPosition = this.audioPlayer.CurrentPosition;
}
},
ct);
This works great if i play an audio file once. However, if i try to replay the file, a few times, the UI gets blocked more and more. Seems like the Task.Run() always creates a new task and doesn't "dispose" the older ones..?
I also tried to update the values in the Device.InvokeOnMainThread() if if i use that, the Slider won't get updated at all.
How can i update the audio slider while the file is playing in a smooth way?
Have you tried using a Timer instead of a Task with a while loop?
I assume your app is the only one controlling playback - so you could handle the timer in your playback pause / stop event handlers / commands.
The amount of code you are providing isn't enough to give more advanced suggestions.

Delay between on screen display and parallel port trigger

I am working on a research project which needs precise timing/synchronize between the on screen display and a trigger from parallel port in Unity.
What I am trying to do is to flash the screen to white while sending a trigger to the parellel port at the same time (desired difference is within 10ms).
I mesured the screen flash with a photodiode to determine the exact time it turns white, and synchronize it with the trigger from parellel port. I always observed a delay of 40 - 70ms between the trigger and the flash (the flash arrived slower) which is my main problem.
What I have tried so far:
- Update the flash and send the trigger in the same frame (bigger delay)
- Update the flash -> WaitForEndOfFrame() -> send trigger (lower delay but still big). Below is a sample code:
IEnumerator UpdateParallelPort()
{
while (true)
{
yield return new WaitForEndOfFrame();
if (flashed == FlashState.ToWhite)
{
parallelPort.SendTrigger();
}
}
}
I also tested if the flash take multiple frames to be rendered by using ReadPixels to determine at what frame the screen turn white, but it was not the case, it was in the same frame when I issued the command. So I guess the delay comes from the time the buffer being sent to screen ? If that is the case, is there anyway to determine/synchronize the exact timing, or to minimize it ?
This is my first post in Stackoverflow, hope that I explained it clear enough. Thank you in advance for your help!
which needs precise timing
I have bad news, completely forget it.
Unity is a game engine through-and-through.
The whole entire raison d'etre, the most fundamental aspects of it, is that it lets you render mesh of dinosaurs etc, with "total compromise" of granular time, and reasonable overall perceptive time.
Unfortunately, you literally could not choose a worse milieu for the project! Sorry! :O

WPF / C#: async load/buffer next movie clip

I need a main 'home' video (full screen HD) running in a loop, and then at some point (say the user presses a key) another short movie plays (one of twelve selected at random), and then back to the home movie loop.
I'm using the mediaElement in WPF from my C# code - Is there a way to load the next movie into memory so that it's ready to play instantly? It currently takes about a second or so...
(I'm actually using two media elements with the triggered movie on top - I was doing a cross fade but have taken that out now until I can buffer the next clip. Not sure if this is the best way of doing this, any ideas? Many Thanks.
I figured out a way in case anyone is interested.
You can just specify a bunch of mediaElements on top of each other (can have different z index but not essential). Then did
video.Opacity = 0.0;
video.Play();
video.Pause();
for all of them, then when you want to play one you just set the opacity to 1 and play it and it'll play instantly.
Don't know if that's the best way, but works well. Now going to implement a cross fade to finish up. Happy days.

WPF: Implementing a MediaPlayer Audio / Video Seeker

I am currently working on an MP3 player (in a WPF application) with a WPF MediaPlayer and basically, I want to implement a Song Seeker which moves along with the current playing song.
I already implemented a song slider (from Sacha Barber's application) and it works when the user drags the seeker manually (as in, the song continues from that position) but I cannot figure out how to make the seeker move according to the current position in the song.
Trouble is I don't think there is a way to check when the Position property of the MediaPlayer has changed, so I'm stumped as to how I should implement this feature.
Any ideas on how to go about such an issue?
[Update]
As regards incrementing the seeker with a timer, I actually thought of using the reason I didn't try it yet is because I think there is a better way to implement this using the MediaTimeline...but I'm yet to figure out how.
ARISE answer! and serve your master
OK, I've figured out how to work this. I'm sure I'm not doing it the completely correct way but it does work.
Here is the code-behind of a WPF application, with a Pause/Play button.
public partial class Main : Window
{
MediaPlayer MPlayer;
MediaTimeline MTimeline;
public Main()
{
InitializeComponent();
var uri = new Uri("C:\\Test.mp3");
MPlayer = new MediaPlayer();
MTimeline = new MediaTimeline(uri);
MTimeline.CurrentTimeInvalidated += new EventHandler(MTimeline_CurrentTimeInvalidated);
MPlayer.Clock = MTimeline.CreateClock(true) as MediaClock;
MPlayer.Clock.Controller.Stop();
}
void MTimeline_CurrentTimeInvalidated(object sender, EventArgs e)
{
Console.WriteLine(MPlayer.Clock.CurrentTime.Value.TotalSeconds);
}
private void btnPlayPause_Click(object sender, RoutedEventArgs e)
{
//Is Active
if (MPlayer.Clock.CurrentState == ClockState.Active)
{
//Is Paused
if (MPlayer.Clock.CurrentGlobalSpeed == 0.0)
MPlayer.Clock.Controller.Resume();
else //Is Playing
MPlayer.Clock.Controller.Pause();
}
else if (MPlayer.Clock.CurrentState == ClockState.Stopped) //Is Stopped
MPlayer.Clock.Controller.Begin();
}
}
The trick is that once you set the clock of a MediaPlayer, it becomes clock controlled, thus the use of MPlayer.Clock.Controller to do all of the controlling :)
Never played with media player but assuming you know the length of song could you not setup a timer that ticks every second while the song is playing. Therefore for every tick just increment the seeker in relation to how long the song is in total.
Song is 100 seconds long. Therefore every second/tick is worth 1 percent of total progress.
You'd have to stop the timer when pausing song etc...
MediaElement has a position property which you could use for this: http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.position.aspx
Have you checked out the WPF MediaKit yet?

Categories

Resources