1

Android アプリのサウンドを再生するために SoundPool を使用しています。すべてのサウンドはアプリの開始時にロードされ、アプリ自体の遅延を防ぎます。ループに設定されていない限り、すべてのサウンドが正常に再生されます。ループを true (-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に設定し、残りを下げます。値が大きいほど優先度が高くなります。ただし、サウンドを再生するときのレイテンシーに大きな問題があります。何か解決策がありましたら、お知らせください。

Which I mean:
int streamID = m_soundPool.play(soundID, streamVolume, streamVolume, 99, loops, 1.0f);
于 2012-10-04T20:25:51.360 に答える