Page 1 of 1

Sound Reloading issue.

Posted: Wed Mar 14, 2007 10:56 pm
by TheC
If you modify the hello world example to read this in the mail loop:

Code: Select all

do
	{
		printf("Press any key to play some sound, press 'q' to quit.\n");

		// play a single sound
		ISoundSource* Snd = engine->addSoundSource("../../media/bell.wav");
		engine->play2D(Snd);
		Snd->drop();
	}
	while(getch() != 'q');
You get a corrupt pointer when trying to play the sound again. This code may seem stupid, but my application works much differently, thats just the underlying concept :)

Does anyone know why this might be happening?

not sure

Posted: Wed Mar 14, 2007 11:35 pm
by lonesock
I'm not sure what the proper protocol is. I know I need to drop ISound after it is used, if I get a pointer to it, but I couldn't find anything about ISoundSource one way or the other in the documentation. I imagine that if the sound is still playing, then the sound source is probably still needed. Maybe check that by returning a pointer to the playing sound (track it) and check the isFinished() function before dropping both the sound and the sound source. Also, if you just need the sound source to be reloaded you can use the forceReloadAtNextUse() function so kindly provided by irrKlang's author!

Posted: Thu Mar 15, 2007 12:29 pm
by TheC
My system is designed in such a way that it doesn't know it needs to reload it, it just does.

I would assume that engine->playxD would grab the sound. If I wait for it to end, it still crashes.

Posted: Thu Mar 15, 2007 6:08 pm
by vitek
You are only supposed to drop() things for which you've explicitly called grab() or were returned by a create method. You are dropping a sound that you don't own. The engine owns it.

It appears from the documentation that the sound engine keeps all sound sources in a cache to avoid needing to repeatedly load the same sound files unnecessarily. I see no way to remove sources from the cache, but you can use Snd->forceReloadAtNextUse() to force it to be re-read from disk. This will essentially bypass the caching scheme, and might lead to unnecessary stuttering or delays when playing sounds.

Travis

Posted: Thu Mar 15, 2007 7:34 pm
by TheC
There should be an option to remove caching, since it is a serious problem with meshes and textures. You think you've changed level, but the old level still exists in the RAM. The same must not be happening for sounds.

If I remove the drop() call, it won't play the sound again if I try to re-use it, it'll give a warning that the sound is in use.

Posted: Fri Mar 16, 2007 5:01 am
by vitek
The caching in Irrlicht is fine, the caches are exposed so that you can add and remove things from the cache [the IMeshCache and IVideoDriver allow you to do some cache control]. Unfortunately with IrrKlang you can't really access the cache and manipulate it.

I haven't played enough with IrrKlang to be able to tell you how to solve your problem, but I'd be willing to bet that there is support for playing the same sound sample multiple times or simultaneously.

Travis

Posted: Fri Mar 16, 2007 7:42 am
by niko
Hi, you are simply using the engine a bit wrong here :)
addSoundSource only returns the pointer of the added sound source when it was added the first time. It also should only be called once. Second: There is no need to drop() the pointer. More exactly: you must not drop() the pointer there, it will crash the engine.

So what you want to do is

Code: Select all

do {
engine->play2D("../../media/bell.wav");
} while(getch() != 'q');
which would work, or if you really want to use sound sources do something like this:

Code: Select all

ISoundSource* Snd = engine->addSoundSource("../../media/bell.wav");
do {
engine->play2D(Snd);
} while(getch() != 'q');
And if you need to reload your sound after every playing, add this:

Code: Select all

ISoundSource* Snd = engine->addSoundSource("../../media/bell.wav");
do {
engine->play2D(Snd);
if (Snd)
   Snd->forceReloadAtNextUse();
} while(getch() != 'q');
Hope this helped.

Posted: Fri Mar 16, 2007 6:42 pm
by TheC
The issue is, my application is going to load different sounds when it changed level.

If the same sound is in the level file, it won't work.

Also, if I cannot remove sounds, after a while of playing, the amount of RAM used will be huge.

Posted: Mon Mar 26, 2007 11:01 am
by niko
Yep, so the last code snipplet I wrote should help you out :)

Posted: Mon Mar 26, 2007 7:06 pm
by TheC
It doesn't, since I have no way of telling that the sound is already loaded. I wouldn't need to worry about that if I could free the sound in the first place.

I don't understand why there isn't an option to free the sound? When making a demo its fine without it, but in an actual game its important.

Posted: Tue Mar 27, 2007 5:51 am
by niko
Ah, ok, you are totally right, that's missing. going to add this for the next release.

Posted: Fri Apr 13, 2007 6:37 am
by niko
Update: This is now possible in irrKlang 0.7, use ISoundEngine::removeSoundSource() or ISoundEngine::removeAllSoundSources().