Diposal of SoundPlayer and Resource in C# - c#

I am working on a kind of (at least closely related) Virtual Keyboard and want to include some clicking Sound. For testing I have just used
SoundPlayer player = new SoundPlayer(Resource2.click);
player .PlaySync();
Now I obviously do not want it to be Sync since it would freeze the keyboard.
Instead, if a new button gets clicked while the previous click-Sound is still playing, I would prefer the first one to stop and just start over with the new click. It is always the same sound for every button, approx. 1 sec long, but there might be a lot of events (typing speed)
So I planned to just go with
//Startup
SoundPlayer player = new SoundPlayer(Resource2.click);
player.Load();
and
//ButtonClickEvent
player.Stop()
player.Play()
//More stuff
Though while looking around I found this thread:
How to use System.Media.SoundPlayer to asynchronously play a sound file?
My way of doing it would be his Attempt #1, but he seems to have a problem:"SoundPlayer and the embedded resource stream are not immediately disposed".
Now I am not quite sure what is meant by this. Does this only concern memory issues if I have many different SoundPlayer objects? Or is this something else which might give me problems on the long term, which I did not see in my first tests. This is my main question. Additionally: Is there something else I overlooked that might give problems once in a while? E.g. stopping the player while it is not running multiple times?

Related

XNA SoundEffect Distortion

So I am currently making a game where you are running and defeating enemies. When you get to the boss and kill him he has a death sound, but what happens is that is plays the death sound all distorted. I don't know what is going on, sometimes are better than others but they are all distorted. MonsterA is my boss Monster and enemy health is his health. here is my code(This is in the Draw() Method):
if (enemyHealth == 0)
{
sprite.PlayAnimation(deathAnimation);
if (spriteSet != "MonsterA")
{
killedSound.Play();
}
if (spriteSet == "MonsterA")
{
bossKilledSound.Play();
}
isDead = true;
}
Put your code in the Update method. The Draw method is ment (pretty much) only for drawing. Also, it's not very clear to me, but the Draw function does't fire just every time after Update. I think it's kind of async, but watis for Update. It's a foggy topic for me, but try putting that code in Update instead of Draw. If that's not the case, try running the game on another PC that is much slower or much faster than the one you are debugging on. That should lead you to the next clue why is this happening.
EDIT:
... assuming that you are not starting the sound on every fire of Draw/Update, witch is not likely because from your explanation, other sounds play well, and only this one is the problem.

Using thread two part of a program differently

I'm actually coding a pacman (C# Console) i would like to know how to move my ghost each seconds, but i would also like to be able to move my pacman whenever i want.
I would like my ghost keep mooving each second whatever pacman do, i should be able to move pacman when ever i want, and ghosts just have to move every second.
I guess i have to use Thread system, so i would like to know if you know how i have to proceed and how thread works, can't find any information about that :s.
You do not need to use different threads for each ghost. This can all be done on one thread using a Game Loop
The central component of any game, from a programming standpoint, is
the game loop. The game loop allows the game to run smoothly
regardless of a user's input or lack thereof.
Most traditional software programs respond to user input and do
nothing without it. For example, a word processor formats words and
text as a user types. If the user doesn't type anything, the word
processor does nothing. Some functions may take a long time to
complete, but all are initiated by a user telling the program to do
something.
Games, on the other hand, must continue to operate regardless of a
user's input. The game loop allows this. A highly simplified game
loop, in pseudocode, might look something like this:
while( user doesn't exit )
check for user input
run AI
move enemies
resolve collisions
draw graphics
play sounds
end while
The game loop may be refined and modified as game development
progresses, but most games are based on this basic idea.
Follow that pattern and your game will be much easier to write.
You're probably confused because Console.ReadKey() is blocking...so your game loop would be stuck waiting for the user to press a key right? What you do is only grab the keystroke with ReadKey() if there is already one in the queue. This can be checked with Console.KeyAvailable which returns true if a key is already there. This way the game loop just keeps looping around if no key has been pressed...but you can still trap it and do something with it. Try this quick example out and see what happens:
class Program
{
static void Main(string[] args)
{
while (true)
{
System.Threading.Thread.Sleep(250);
Console.Write(".");
if (Console.KeyAvailable)
{
ConsoleKeyInfo key = Console.ReadKey(true); // read key without displaying it
Console.WriteLine("");
Console.WriteLine("Key Pressed: " + key.KeyChar.ToString());
}
}
}
}
Finally found what i do need :
Threads and Thread Synchronization in C#

Same sound overlapping making it very loud. Tips/Tricks?

I've got multiple object in a game I'm making, and I'm having major issues figuring out how to play sounds without playing the same sound twice or more. I'm wondering if you have any tricks/tips on how to make the sound play only once no matter how many instances of it is made and be balanced, rather than having it played 50 times being mega loud.
I'm using the XNA.Framework.Audio.SoundEffectInstance to play sounds.
This is more of a mixing issue than a programming issue. Playing a sample twice will always result in a fuller effect.
From a programmatic perspective, you can make sure the sound is never playing twice at the same time. To accomplish this, set a boolean value every time a sound is about to play. Before you play the sound, make sure the boolean value is false or cancel the event. Set the boolean value to false once the sound is played.
This is a pretty generic answer, but maybe you can create different sound classes (for example, shooting sounds, moving sounds, environment sounds).
When you play your sounds, you could play the current sound of each class while muting all the other sounds of that class.
For example, for every gunshot, it might be the case that the time in between each shot is shorter than the time it takes to play the sound. For each new gunshot, just mute all the other sounds in the pool of shooting sounds.
To do this, you might add a shooting sound object into a shooting sounds array, and for every game frame, check to make sure that there is no new sound. If there's a new sound, iterate through the array of sounds to mute everything before playing your new sound.
You can then make multiple arrays of sounds (walking/environment) so that your shooting sounds don't cut out walking sounds/environment sounds.
In the instance class you could make a static variable that is a boolean.
When an instance goes to make the sound, first have it check the static variable. If the variable is true, don't play the sound. If it is false, play the sound.
When the sound is done playing, turn the static variable to false so the next instance can play the sound.
example:
public static bool is_playing = false;

Naudio: How to play MP3 and WAV file?

Okay, I know this sounds like a very easy question to some but I am really stuck here. Indeed, I am building an audio player using Naudio and I have realized that in many tutorials people always show easy ways to get you started. However, in my opinion, they always forget to show how things are actually done in a real application. For example, when playing music with Naudio, I would do something like:
Void PlayAudioMusic(string FilePath)
{
using (var ms = File.OpenRead(FilePath))
using (var rdr = new Mp3FileReader(ms))
using (var wavStream = WaveFormatConversionStream.CreatePcmStream(rdr))
using (var baStream = new BlockAlignReductionStream(wavStream))
using (var waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
{
waveOut.Init(baStream);
waveOut.Play();
}
}
This is great for testing in a simple console application. This however isn't useful if you're actually building a serious application. For example, what many tutorials never say is for example how to handle the most critical things such as:
Disposing resource and when to do it
The best ways to handle different exceptions
What to do before you pause, stop, rewind or even exit the application
Other stuffs I don't even know exist.
Since I am going through this process and have notice that my application has way too many exceptions thrown, can someone please share like a wrapper class around Naudio that he used to handle this. I am sure this will answer many of the trouble some of us have been going through when trying to use Naudio.
Thanks.
To Dispose the unmanaged resources, you call the Close method of the WaveStreams. The "when to do it" part is rather obvious... Do you really don't know when it is the right time to Dispose unmanaged resources? You Dispose them when you are not going to use them anymore.
I can't answer this one. Sorry.
To Pause, you call the Pause method of the WaveOut object. To rewind, you call the Seek method of the WaveStream. To Stop, don't call the Stop method of the WaveOut. You must call Pause and then call the Seek method of the WaveStream to go to the beginning of the buffer.
The most probable cause of all the Exceptions being thrown is because most of the code you shown is actually unnecessary. All you should need to do to play a MP3 file is:
WaveStream mainOutputStream = new Mp3FileReader(path_of_the_file_you_want_to_play);
WaveChannel32 volumeStream = new WaveChannel32(mainOutputStream);
WaveOutEvent player = new WaveOutEvent();
player.Init(volumeStream);
player.Play();
I personally prefer to use WaveOutEvent instead of WaveOut because it does not require you to be using Windows Forms or WPF, enabling you to use NAudio for absolutely any kind of application you want make with C#, even XNA games. Also, WaveOutEvent has a very fire-and-forget usability, and it's constructor does not even ask for a callback.
All these WaveStreams meant for changing stuff about the buffer (such as Sample Rate of Bit Depth) are just ways of asking for NAudio to throw an exception. They rarely work when used like this. If you want to convert some stuff of the buffers, you have to call some Static methods of the WaveFormatConversionStream (their names are self-explanatory, at least.)

FMOD gapless loop and sequence playback

I started using FMOD library, because I need to play sounds without gaps in C# application (both one sound in a loop and many sounds in a sequence). Can anyone show me the correct way to do it? I tried make something based on examples, but it's not working as I would like it to work.
Firstly, when I try to set if the sound is looped, while it's playing,
if (value)
sound1.setMode(FMOD.MODE.LOOP_NORMAL);
else
sound1.setMode(FMOD.MODE.LOOP_OFF);
nothing is going on. It only works fine, when I set th mode, before I start playback.
The second issue is: how can I be notified that the sound has reached the end? I tried to do it this way:
channel.setCallback(eofCallback);
where eofCallback is a reference to SoundEndCallback
private FMOD.RESULT SoundEndCallback(IntPtr channelraw, FMOD.CHANNEL_CALLBACKTYPE type, IntPtr commanddata1, IntPtr commanddata2)
{
FMOD.RESULT result;
if (type == FMOD.CHANNEL_CALLBACKTYPE.END)
{
//logic here
}
return FMOD.RESULT.OK;
}
But this callback is reached only when I manually invoke stop() on channel, not when the track ends.
Or eventually do you know any other library that would give me easily what I need? I chose FMOD, because it's quite popular, but I don't like its oldschool C++-like way of coding (no events, no exceptions, etc.).
And I have teh answer for my second question: to get notified you have to firstly set callback as mentioned before, and after that you've got to use System.update() method (it must be called periodically in a loop). This is a kind of polling,
To set the loop mode of a sound at runtime use Channel::setMode, Sound::setMode is like setting the defaults for any channels played from that sound (it won't affect currently playing sounds).
As for Channel::setCallback, make sure you are calling System::update regularly to have the callbacks fire for events like the sound playing to the end.

Categories