Soundpool样本没准备好

时间:2011-03-05 08:00:32

标签: android soundpool

我有一个.wav文件,我想在我的游戏中使用它,目前我正在加载游戏中每项活动onCreate()的声音。

 soundCount = soundpool.load(this,R.raw.count, 1);

活动开始后将播放声音。

  soundpool.play(soundCount, 0.9f, 0.9f, 1, -1, 1f);

问题有时我会遇到错误"sample x not ready"。 是否可以在开始游戏时加载.wav文件并将其保存在内存中并在以后的游戏中使用它?或者是否可以等待1-2秒以使声音加载完成?

8 个答案:

答案 0 :(得分:33)

您需要通过SoundPool.setOnLoadCompleteListener添加一个监听器来等待它完成。

答案 1 :(得分:5)

由于我的项目与Android 1.5兼容,我无法使用setOnLoadCompleteListener,因此我解决了延迟播放声音的问题。 我的源代码如下:

    playSound_Delayed(soundId, 100);

//(..)

private void playSound_Delayed (final int soundId, final long millisec) {
    // TIMER
    final Handler mHandler = new Handler();
    final Runnable mDelayedTimeTask = new Runnable() {
    int counter = 0;
    public void run() {
        counter++;

        if (counter == 1) {
            boolean ret = mHandler.postDelayed(this, millisec); 
            if (ret==false) Log.w("playSound_Delayed", "mHandler.postAtTime FAILED!");
       } else {
           playSound(soundId);
       }
    }
    };
    mDelayedTimeTask.run();
}

答案 2 :(得分:4)

如果可能的话,你应该使用setOnLoadCompleteListener ......如果没有,请在你的'play'调用周围打一个while循环。类似的东西:

int waitLimit = 1000;
int waitCounter = 0;
int throttle = 10;
while(soundPool.play(soundId, 1.f, 1.f, 1, 0, 1.f) == 0 && waitCounter < waitLimit)
 {waitCounter++; SystemClock.sleep(throttle);}

这将以10毫秒的间隔重试“播放”1000次。这当然应该在非ui线程上运行,并且仍然不理想。但也许比等待任意时间并期望游泳池准备好一点强。

答案 3 :(得分:2)

SoundPool库使用MediaPlayer服务将音频解码为原始的16位PCM单声道或立体声流,我们可以简单地调用Stream的准备,这需要一些时间取决于声音文件的大小。如果我们在该过程结束之前尝试播放声音,我们会得到“sample x not ready”错误。

这个有两个解决方案

  1. 实施setOnLoadCompleteListener或
  2. 等待任意时间以便准备结束
  3. 然后播放它 请注意,此条件没有例外,或者应用程序在没有任何try-catch

    的情况下不会崩溃

答案 4 :(得分:2)

private SoundPool soundPool;
private int my_sound;
boolean loaded = false;

//在构造函数

soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
my_sound = soundPool.load(this, R.raw.blast_sound, 1);

soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
    public void onLoadComplete(SoundPool soundPool, int sampleId,int status) {
       loaded = true;
    }
});

//然后在哪里播放声音,输入

if (loaded) {
soundPool.play(my_sound,  0.9f, 0.9f, 1, 0, 1f);
}

答案 5 :(得分:2)

我用简单的do-while cicle解决了问题。方法play()如果​​成功则返回非零streamID,如果失败则返回零。因此,检查返回值就足够了。

int streamID = -1;
do {
    streamID = soundPool.play(soundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
} while(streamID==0);

答案 6 :(得分:2)

这绝对适用于您!

public void playWavFile() {

    Thread streamThread = new Thread(new Runnable() {           

        @Override
        public void run() {                 
            SoundPool soundPool;
            final int wav;
            String path = "/mnt/sdcard/AudioRecorder/record.wav";
            soundPool = new SoundPool(5,AudioManager.STREAM_MUSIC, 0);
            wav = soundPool.load(path, 1);
            soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
                @Override
                public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                    // TODO Auto-generated method stub
                    soundPool.play(wav,100, 100, 0, 0, 1f);
                }
            });

        }        
    });

    streamThread.start();
}   

答案 7 :(得分:1)

这听起来很疯狂,但不要马上播放声音。给你的应用程序几秒钟初始化SoundPool。在我的应用程序中,这正是问题所在;我添加了一个假的“加载”屏幕~3秒,然后一切正常。 (我甚至不需要预加载声音。)