I'm writing a basic writing app in C# and I wanted to have the program make typewriter sounds as you typed. I've hooked the KeyPress event on my RichTextBox to a function that uses a SoundPlayer to play a short wav file every time a key is pressed, however I've noticed after a while my computer slows to a crawl and checking my processes, audiodlg.exe was using 5 GIGABYTES of RAM.
The code I'm using is as follows:
I initialise the SoundPlayer as a global variable on program start with
SoundPlayer sp = new SoundPlayer("typewriter.wav")
Then on the KeyPress event I simply call
sp.Play();
Does anybody know what's causing the heavy memory usage? The file is less than a second long, so it shouldn't be clogging the thing up too much.
Try disposing the SoundPlayer after playing the sound. Then run the Garbage Collector. If it still consumes additional memory, something really nasty is happening and you should run the tests on another computer.
I've done with this sample. WWFM (aka "Worked Well For Me). Try searching errors in your code (which, i'm almost sure, is pure enough) or another sound file.
Don't use
SoundPlayer
- use thewaveOut...
API instead:http://www.codeproject.com/Articles/4889/A-full-duplex-audio-player-in-C-using-the-waveIn-w
SoundPlayer
is more like a toy than a production-ready component, although I'm sure the MS intern that wrote it meant well. :)Update: if you use the linked sample and get familiar with the code, you'll see what's probably wrong with the
SoundPlayer
implementation. Playing audio with thewaveOut...
functions involves two in-memory buffers: one small one for the header, and one potentially large buffer than contains the actual sample data. The hotfix article you linked to mentions the leak of a few hundred bytes each timePlay
is called, which means the code is probably instantiating a new header each time and then not disposing of it properly. (This is assumingSoundPlayer
wraps thewaveOut...
API - I don't know whether this is the case or not)Programmers take for granted the maxim "don't reinvent the wheel". Well, sometimes the wheel desperately needs reinventing.
You should try using()
when process finish sp.Play() memory return to your system automatics.
This isn't strictly speaking an answer, so I won't confirm this as the accepted answer to my question, but it is a solution for those who have had the same problems (and also confirms it's not my system at fault)
I decided to implement the sound using ManagedDirectX's AudioPlayback library, which is about as easy to use as SoundPlayer, but has successfully solved my problem.
For those who want to know, the code is simple:
1) Add a reference to the audioplayback dll.
2) Create an Audio object (I named mine sound), make it a variable on your form so you can refer to it again, use the constructor to set the filename it should play
3) Play the file with sound.Play();
4) If you need to play the file again, use the following line:
It's fairly fast, and fairly good. There'll be memory issues if you need a lot of different sound effects, because they'll all constantly be in memory, but if you need one sound to play a lot, this one will do it without ballooning your Audiodlg.exe
Try using the
Load
method of the sound player to load the sound, and then call play. Play uses a second thread to load(if not loaded already) and play the file.Maybe the constructor does not load the file initially (which I think is quite possible) , it mearly associates the player with the sound file name.