I'm currently passing my time by creating a piano app. Each Key is represented of a simple button with a command which fires at click. This leads to executing this Method in ViewModel:
private void PlaySound(object parameter)
{
var mediaPlayer = new MediaPlayer();
mediaPlayer.Open(new System.Uri(#SoundBar.GetSoundPathByIdent(int.Parse(parameter.ToString()))));
mediaPlayer.Play();
{
I think the problem is that the MediaPlayer leaves a WeakReference which prevents the GarbageCollector from collecting it. Leading to overloading your RAM after playing a while.
The solution i found was to call: mediaPlayer.Close();
But this should only happen after the sound has finished playing, otherwise it will be cut.
Is there a way to check if the played sound has finished playing?
I have already spent some time doing research and testing but i couldn't come up with a working solution.
The Position and NaturalDuration properties give you details about where in the stream you're at (ie. Position / NaturalDuration gives you a value between 0.0 and 1.0 that represents the playback position as a percentage)
But you may want to build an "orchestrator" for your media playback. Assuming that you don't want to play all sounds at the same time, an orchestrator could be responsible for managing the lifetime of your media players, and determining where in the playback they are.
In your application you could create a single instance of the orchestrator on start up. The orchestrator could create and manage a pool of media players it could reuse when it needs to play a chord. Then your piano app could support a certain number of chords at the same time and have a single poller that determines which media players are free and which are "busy" playing audio.
Related
I have a heatmap plugin integrated in my Unity VR game(with SteamVR). The plugin uses eye tracking information to generate live heatmaps as the user gazes at different elements in the game. As the heatmaps are generated, the whole camera view(user's) is overlayed with heatmaps info and written to a MP4 file using FFMPEG.
The whole process works fine. But I have an annoying problem where during the recording the user's camera view is not stable and keeps flickering and stops only when the recording is stopped. It interrupts the smooth flow of his game
For now, I've narrowed down the code which causes the trouble,
public void Write(byte[] data)
{
if (_subprocess == null) return;
_stdin.Write(data);
_stdin.Flush();
}
From my understanding, It is in this part of the code stdinput is invoked to write to the file system. So, I surmise that the problem must be with accessing the file system which in turn must have caused some time delay when each frame is written in the update method. Correct me if i am wrong here.
The loading screen which appears during every frame write looks something like above. It interrupts the smooth flow of the game and also makes the recording useless as the user keeps focusing on the flicker rather than the actual objects of interest. I would really be grateful if someone shows light on the issue here?
Accessing the file system always takes a huge amount of time. Try offloading that work to another thread or a Coroutine.
The reason I want to do this is to be able to layer the background music. (e.g, simple song starts playing, player triggers something, adds an instrument). I can work out the timing issues, if any.
I thought I could do that with MediaPlayer/Song, but it wouldn't work.
All I'm really looking for is the downsides to use SoundEffectInstance.
p.s, I don't use XACT, since I'll be changing over to MonoGame eventually.
Thanks
Actually, that's what the SoundEffectInstance is for!
It has limitations though, depending on the platform your game is running:
On Windows Phone, a game can have a maximum of 16 total playing
SoundEffectInstance instances at one time, combined across all loaded
SoundEffect objects. The only limit to the total number of loaded
SoundEffectInstance and SoundEffect objects is available memory.
However, the user can play only 16 sound effects at one time. Attempts
to play a SoundEffectInstance beyond this limit will fail. On Windows,
there is no hard limit. Playing too many instances can lead to
performance degradation. On Xbox 360, the limit is 300 sound effect
instances loaded or playing. Dispose of old instances if you need
more.
Oh and by the way, it's been a long time since I played with XNA but I'm pretty sure that the XACT tool was no longer necessary by the end of it's life cycle.
I seem to recall that you could load an mp3 on the Content folder and play it via the SoundEffectInstance object.
Actually, I think you'll find using the MediaPlayer class combined with the Song class is the recommended way to play background music.
Provides methods and properties to play, pause, resume, and stop songs. MediaPlayer also exposes shuffle, repeat, volume, play position, and visualization capabilities.
I think the primary difference is that the MediaPlayer can stream the data into memory rather than loading it all in at once. So, for long playing music tracks this is the way to go.
Also, in MonoGame these classes are implemented by wrapping around the platform specific classes that do the same thing. For example, on Android the SoundEffectInstance uses the Android SoundPool (intended for sound effects) and the MediaPlayer uses the Android MediaPlayer (intended for music). See this post on the MonoGame forums for reference.
slygamer says: MediaPlayer for background music and SoundEffect for sound effects is how it is designed to be used.
I'm making a Windows game using XNA 4.0. I have an quick little intro screen that shows our studio logo and plays a sound. It lasts 1.5 seconds and looks and works as desired in windowed mode.
We want to run the game full screen. So all I added was "graphics.IsFullScreen = true" to the Game subclass constructor after the GraphicsDeviceManager is instantiated and we've set the preferred backbuffer dimensions. When the game starts the video card just glitches my monitors for like 1 or 2 seconds switching resolutions, etc. - and that is all a customary and understandable delay between the video card, the device drivers and my monitors all figuring out this change, but XNA is running the game loop while all this nonsense is going on.
This means my intro starts, runs and is over by the time the system gets around to actually displaying what I'm drawing and by then the intro is over. What I'd really like is a way to detect when the video card is actually rendering before I start drawing and playing sound and timing things assuming the player can see them. Searching around online, I've seen reference to a "graphics.EnsureDevice()" call that seems to have been deprecated and is no longer available in XNA 4.0.
I guess this is kind of dirty, but you could fire off a thread that continually checks to see if the DeviceParameter IsFullscreen is set to true on active graphics device, after you set the GraphicsDeviceManager.IsFullscreen property to true.
Once it is set, then you would start your game loop.
You could also write it in a way that the thread would only fire off if you set GraphicsDeviceManager.IsFullscreen to true. That way it would support both modes.
I want to synchronize the playback of a song to a timer so that I can keep the beats of a song in sync with things rendered on the screen. Any way of accomplishing this using NAudio?
Several out the output devices in NAudio support the IWavePosition interface, which gives a more accurate indication of where the soundcard is currently up to in the buffer it is playing. Usually this is reported in terms of number of bytes that have been played since playback started - so it does not necessarily correspond to the position within the file you are playing or within a song. So if you use this you will need to keep track of when you started playing.
Usually you would keep the things rendered on screen synchronized to the audio playback position, rather than the other way round.
I am developing an application in C# that has a form with Windows Media Player embedded inside. There are several links to some online content in my app. and I want user to change the content from one to another with a button click. Since WMP spent some time while buffering for the next content, I want to continue playing the current content. There is an event called "Buffering" in AXWindowsMediaPlayer class that signals when media player finishes buffering the content. But I could not achieve this with a single AXWindowsMediaPlayer object. Whatever I did, I could not continue to play the first content while buffering the second. :(
Any ideas?
Thanks in advance.
I suggest two instances of the Player control that you swap out as needed.
Alternatively, if the connection is fast enough cache each item on the local system and play from there.