1

我正在使用 SoundPool 为我的 Android 应用程序播放声音。所有声音都在应用程序开始时加载,以防止应用程序本身出现任何滞后。只要未设置为循环播放,所有声音都可以正常播放。当我将循环设置为真(设置为-1)时,声音不会播放。

根据用户的输入,有 6 种不同的声音会停止和启动。它播放第一个声音很好,但随后的声音无法播放。

我已经尝试了各种方法,例如暂停而不是停止,将音量设置为 0 并将循环设置为 0 而不是暂停,将循环设置为任意大的数字而不是真正的重复,使声音更短,并且没有这些已经工作了。

我的代码如下:

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); 
    }
}

LogCat 在运行时给出的错误是:

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

有人知道这个烦人的问题的任何解决方案,或者我没有尝试过的任何解决方法吗?

4

4 回答 4

1

我能想出的最佳解决方案是为正在执行此操作的声音设置一个特殊情况,并为这些声音使用 MediaPlayer。然后我必须在它们不使用时停止并释放它们,然后在我想再次播放它们时重新加载它们。当声音发生变化时,有一个明显但轻微的加载时间,但这是我能做的最好的。任何其他答案仍将不胜感激。

于 2012-01-04T10:37:58.347 回答
0

确保在 onPause() 中释放 SoundPool 资源以防止内存泄漏。你也应该在 onResume() 中加载你的声音。

于 2012-01-04T04:45:23.710 回答
0

我有同样的问题。当您开始播放您想要循环播放的声音时,将声音的优先级设置为 99 并降低其余的。值越高,优先级越高。但是,我在播放声音时遇到了很大的延迟问题。如果您有任何解决方案,请通知我。(我也使用 soundpool 和 int 数组作为 ID 池。)

Which I mean:
int streamID = m_soundPool.play(soundID, streamVolume, streamVolume, 99, loops, 1.0f);
于 2012-10-04T20:25:51.360 回答
0
SoundPool soundPool;
int soundID;
boolean plays = false, loaded = false;
float actVolume, maxVolume, volume;
AudioManager audioManager;       

audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
actVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
volume = actVolume / maxVolume;

this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
    @Override
    public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {

    }
});
soundID = soundPool.load(this, R.raw.audiofile, 1);


new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        soundPool.play(soundID, volume, volume, 1, -1, 1f);
    }
},1000);

试试这个解决方案。它应该工作。

于 2019-08-02T09:50:06.410 回答