9

I am using SoundPool to play sfx sounds in a game on Android. In most cases it works perfectly, except sometimes I need to stop all sounds at once not pause (doesn't matter if they are set to loop or not). I can't figure out how to stop a sound from playing without knowing the StreamID of that sound. What I know:

  • soundpool.load(...some sound...) returns a soundID
  • soundpool.play(soundID) plays the sound and returns a streamID
  • soundpool.stop(streamID) stops the sound

My question is, how can I stop a sound without knowing the streamID ? I tried tracking all streamIDs in a list, but sometimes there are so many short streams playing at once, that it won't work. And I can't find any method in SoundPoolto get the active streamIDs. Does anyone know how to stop all sounds? Any hint is appreciated! thanks

rae1
  • 6,066
  • 4
  • 27
  • 48
GameDroids
  • 5,584
  • 6
  • 40
  • 59
  • Isnt' there a stop all kind of call ? – Howard Pautz Sep 13 '13 at 19:42
  • SoundPool.autoPause() is the only method in the class meant to stop all streams at once. You're saying this doesn't fit your needs? – Prmths Sep 13 '13 at 19:44
  • When I pause the sounds, they would still be flagged as paused and thus resumed on autoResume(). But I can't have the stopped sounds to be resumed (I am using the autoResume() method on a different occasion) @HowardPautz unfortunately not. autoPause() seems to be the only method to handle all active sounds – GameDroids Sep 13 '13 at 19:48
  • ok I'm not clear why your running through your list of ids won't stop them. Are you looping some of them ? – Howard Pautz Sep 13 '13 at 20:51
  • Yes, that too. Some sounds are in a loop, some are not. Maybe I should try the list again, but it is so hard to keep track of all the ids. When a sound stops because it is finished, then the id will become invalid or just useless - but I won't know when that happens and the invalid id will still be in the list. So the list is growing really fast. Or do you have a better idea to track the active ids? – GameDroids Sep 13 '13 at 21:21
  • 1
    Remember that when you set the size of your sound pool, you define how many you have, so you know how to size an array or a list (virtually no dif. in performance), just flag the sound on or off. Or you can do what I do and use the array or list elements like 'slots' that hold the ID's - the slot holds only active IDs, so you can for loop over them. Maybe you should post your list code ? Are you controlling the sounds from a different thread ? – Howard Pautz Sep 13 '13 at 21:33
  • I thought about your slot idea and when monitoring the streamIDs a little closer, I realized that the streamID increments each time a stream gets played. When I start my app, the first streamID is 1 and only 2 minutes later the streamID reached 1000. So, I guess I only need to keep track of the last streamID, which will be the highest and when stopping the sounds, just iterate through the last streamIDs. This may be redundant, but as you said, there can be only a certain amount of sounds playing at the same time! So thank you for the brainstorming :) – GameDroids Sep 13 '13 at 22:30

3 Answers3

4

I'd recommend using autoPause() and autoResume() to pause and restart your sounds. This function is part of the soundpool:

http://developer.android.com/reference/android/media/SoundPool.html#autoPause()

Shygar
  • 1,213
  • 10
  • 10
2

What about using .release() ? Accourding to the documentation:

Release the SoundPool resources. Release all memory and native resources used by the SoundPool object. The SoundPool can no longer be used and the reference should be set to null.

I think it also stops everything. (Actually it was causing a bug at one of my apps, that's why I say it)

However, I believe that if you want to play any sounds later, you may have to load them again.

anestv
  • 543
  • 6
  • 28
  • 2
    thank you for your answer. In a way, this is what I do now. I keep the sounds in different SoundPools, so I can release the SoundPool if the sounds need to stop. That way the sounds in other Pools can still play. It actually works and together with a list of active soundIDs (that can be stopped individually) it is sufficient for my problem. Still, I don't really understand why there is no more direct way of checking the soundIDs and stopping or resuming them as I want to. (It is like I'm sitting in front of my CD-Player and eject the whole CD every time I want to stop one single track ;) – GameDroids Dec 17 '13 at 16:09
0

SoundPool doesn't have a method to retrieve the streamID from the index of the stream, like it should. So even when you know the maximum number of streams, you can't just iterate through like the following:

for(int index=0;index<MAXSTREAMS;index++){
 int streamid = SoundPool.getStreamID(index);//getStreamID action doesn't exist :(
 soundpool.stop(streamid);
}

As you mentioned, the coder has to manage this himself with a list. I implement the declaration as follows:

List<Integer> streams = new ArrayList<Integer>();

You can add and remove soundIDs to this list as you play and stop sounds as follows:

streams.add(batattack_soundID);
streams.remove(Integer.valueOf(batattack_soundID));//NOT streams.remove(batattack_soundID);

Be sure to use Integer.valueOf() or .remove() will interpret your parameter as an index position, likely giving you an IndexOutOfBoundsException.

To clean everything up you can code as follows:

for (Integer stream : streams) {
   soundPool.stop(stream);
}
streams.clear();
Androidcoder
  • 4,389
  • 5
  • 35
  • 50