Sound Reloading issue.

Post your questions, suggestions and experiences regarding game design, integration of external libraries here. For irrEdit, irrXML and irrKlang, see the
ambiera forums
Post Reply
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Sound Reloading issue.

Post 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?
lonesock
Posts: 9
Joined: Sun Jan 14, 2007 12:54 am
Contact:

not sure

Post 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!
lonesock
Piranha are people too.
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post 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.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post 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
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post 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.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post 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
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post 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.
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post 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.
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

Yep, so the last code snipplet I wrote should help you out :)
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post 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.
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

Ah, ok, you are totally right, that's missing. going to add this for the next release.
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

Update: This is now possible in irrKlang 0.7, use ISoundEngine::removeSoundSource() or ISoundEngine::removeAllSoundSources().
Post Reply