可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a .wav file that I'd like to use across my game, currently I am loading the sound in onCreate()
of each activity in the game.
soundCount = soundpool.load(this,R.raw.count, 1);
The sound will be played once the activity starts.
soundpool.play(soundCount, 0.9f, 0.9f, 1, -1, 1f);
Problem is at times I will hit the error "sample x not ready"
.
Is it possible to load the .wav file once upon starting the game and keep it in memory and use it later across the game? Or is it possible to wait for 1-2 seconds for the sound to load finish?
回答1:
You'll need to wait for it to finish by adding a listener via SoundPool.setOnLoadCompleteListener
.
回答2:
Since my project is compatible with Android 1.5 and I couldn't use setOnLoadCompleteListener, I resolved making the play of sound delayed.
My source code follows:
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();
}
回答3:
you should use setOnLoadCompleteListener if possible ... if not, wrap a while loop around your call to 'play'. something like:
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);}
this will retry 'play' 1000 times on a 10ms interval. this should be run on a non-ui thread of course, and is still not ideal. but maybe a little stronger than waiting an arbitrary time and expecting the pool to be ready.
回答4:
The SoundPool library uses the MediaPlayer service to decode the audio into a raw 16-bit PCM mono or stereo stream which we simply can call preparation of Stream, that takes some times depending on size of sound file. And if we try to play the sound before that process is over, we get "sample x not ready" error.
There are two solutions for this
- implement setOnLoadCompleteListener or
- wait arbitrary amount of time so that preparation is over
and then play it
Note that there is no exception for this condition or application is not crashing without any try-catch
回答5:
private SoundPool soundPool;
private int my_sound;
boolean loaded = false;
// In the constructor
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;
}
});
// then where ever you want to play the sound, type
if (loaded) {
soundPool.play(my_sound, 0.9f, 0.9f, 1, 0, 1f);
}
回答6:
I solved with problem with simple do-while cicle. The method play() return non-zero streamID if successful, zero if failed. So, it's sufficient to check the return value.
int streamID = -1;
do {
streamID = soundPool.play(soundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
} while(streamID==0);
回答7:
This would work for you definitely !
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();
}
回答8:
This sounds crazy, but don't play sounds right away. Give your app a couple of seconds to initialize the SoundPool. In my app, this was exactly the issue; I added a fake "loading" screen of ~3 seconds, and then everything worked. (I didn't even need to preload the sounds.)