Search code examples
androidaudiosoundpool

Sounds do not play when loops set to -1 on Android


I'm using a SoundPool to play sounds for my Android app. All of the sounds are loaded up at the beginning of the app to prevent any lagging during the app itself. All sounds play fine as long as they are not set to looping. When i set looping to be true (set as -1) then the sound does not play.

There are 6 different sounds that are stopping and starting depending on the user's input. It plays the first sound fine but then sounds afterwards fail to play.

I have tried various ways around it, such as pausing rather than stopping, setting volume to 0 and loops to 0 rather than pausing, setting loops to an arbitrary large-ish number rather than true repeating, making the sounds much shorter and none of these have worked.

My code is as follows:

public int loadSound(int soundFile)
{
    int soundID;

    try
    {
        if (m_loadedSounds.containsKey(soundFile))
        {
            soundID = m_loadedSounds.get(soundFile);
        }
        else
        {           
            soundID = m_soundPool.load(m_context, soundFile, 1);
            m_loadedSounds.put(soundFile, soundID);
        }
    }
    catch (Exception e)
    {
        soundID = -1;
    }

    return soundID;
}

public void playSound(int soundFile, boolean loop)
{
    // Grab it from the map
    int soundID = loadSound(soundFile);

    int loops = loop ? -1 : 0;
    float streamVolume = m_audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    streamVolume /= m_audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

    // If succeeded then play the sound
    if (soundID != -1)
    {
        if (m_soundStreams.containsKey(soundID))
        {
            int streamID = m_soundStreams.get(soundID);
            m_soundPool.setLoop(streamID, loops);
            m_soundPool.resume(streamID);
        }
        else
        {
            int streamID = m_soundPool.play(soundID, streamVolume, streamVolume, 1, loops, 1.0f);
            Log.d("SOUNDS", "Sound played! ID: " + soundID + " At volume: " + streamVolume + " Looping: " + (loop ? "Yes": "No") + " Success: " + (streamID != 0 ? "Yes" : "No"));

            if (streamID != 0) 
            {
                m_soundStreams.put(soundID, streamID);
            }
        }
    }
}

public void stopSound(int soundFile)
{
    int soundID = loadSound(soundFile);

    Integer streamID = m_soundStreams.get(soundID);

    if (streamID != null)
    {
        m_soundPool.pause(streamID); 
    }
}

And the error given in LogCat at run time is:

01-03 16:03:20.142: ERROR/AudioFlinger(2359): not enough memory for AudioTrack size=670096
01-03 16:03:20.142: DEBUG/MemoryDealer(2359):   AudioTrack (0x389a0, size=1048576)
01-03 16:03:20.142: DEBUG/MemoryDealer(2359):     0: 0005b090 | 0x00000000 | 0x00010080 | F 
01-03 16:03:20.142: DEBUG/MemoryDealer(2359):     1: 0006db58 | 0x00010080 | 0x0007B8A0 | A 
01-03 16:03:20.142: DEBUG/MemoryDealer(2359):     2: 0005af70 | 0x0008B920 | 0x0005C280 | A 
01-03 16:03:20.142: DEBUG/MemoryDealer(2359):     3: 000752c0 | 0x000E7BA0 | 0x00018460 | F 
01-03 16:03:20.142: DEBUG/MemoryDealer(2359):   size allocated: 883488 (862 KB)
01-03 16:03:20.142: ERROR/AudioTrack(11584): AudioFlinger could not create track, status: -12
01-03 16:03:20.142: ERROR/SoundPool(11584): Error creating AudioTrack

Does anybody know of any solutions to this annoying problem, or any workarounds that I haven't tried?


Solution

  • The best solution I could come up with is to put a special case in for the sounds that are doing this and use a MediaPlayer for these sounds. Then I have to stop & release them when they're not used and then reload them when I want to play them again. Has a noticeable, yet slight, loading time when the sounds change but it's the best I can do. Any other answers would still be much appreciated.