So I’m experimenting with adding sound effects in my game, and I thought I’d ask advice before going too deep into the rabbit hole.
So let’s take an example: I want 4 instances of the same sample to play at regular intervals, namely depth charges exploding around the U-boat. I like to change the volume and panning for each to suggest the explosions getting closer.
So my instinct is to create a sample object for the explosion sample and 4 sampleplayers at launch and keep them all in memory, in order to avoid object creation/flush. And then Call play() on each sampleplayer as needed. Obviously that means preloading all my sounds, which could lead to longer loading times and also filling the memory, since I love me samples in stereo.
Now for giggles I tried to create a local sampleplayer and call play() every time I have an explosion. I don’t have many explosions. 2 or 3 goups of 4 separated by 30 seconds, then a long time before that sequence happens again (it’s a turn based game).
To my surprise this showed no lag, and didn’t seem to affect memory. The obvious advantage is that I can save all that memory, loading each explosion only as needed. Now my understanding is that every time I create a local sampleplayer, the sample is loaded in memory, and then flushed. So would that affect battery consumption of the game over time? Would that cause any risk of memory leak or fragmentation, or performance degradation over time?
Basically my question is: the second method goes against my instincts but seems perfectly fine. Am I missing something? Is it okay to do that?
Afaik the sample and the sampleplayer are separate things in memory, so you can instantiate a bunch of sampleplayers that reference the same sample. I.e. just load the sample once and use a local player to play it the way you like.
On-demand loading might work fine too, but note that your sound won't actually play immediately as it has to be read from storage first. GC should take care of the trash after a short delay and stopped players only cost memory space.
I think Outgunned is correct about the memory consumption but I would advise against loading it on demand, simply because I don't think it is necessary. My advise would be to create a preloader class that holds all the loaded samples and that you can call whenever you have some spare time. Like when showing a start screen for example. On every invocation of the ‘loadSomething()’ method, the preloader would load a single asset that was not loaded before.
Then you would have the method ‘getOrLoad(sample Path)’. Ideally the sample you want was already loaded, otherwise the sample will be loaded at that time, incurring a load time at that moment.
Also you say you like stereo samples for a point sound source that is positioned using volume and pan. Does it still make sense to have stereo sound for such a use case?
Ok thanks. Obviously if I didn’t care about memory I know it would make more sense to preload all samples. The problem is memory. That was my point. I can have more high quality sounds if I don’t have to preload them all. As for stereo samples, yes it does because they always sound much more spatial. I would never hard pan on one side. Panning is lowering the level of one side, but you still get stereo information from both sides.