问题
I am working with an android media application for that i want play a sound file simultaneously for a specific period of time. So i've created a Class and i am using SoundPool
and Thread
concepts inside this class to play the sound but when i run my application it is going to an ANR state and showing a warning in log-cat
sample 2130968576 not READY
anyone please help me to fix this...
Class
package com.kodspider.funk;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
public class CustomPlayer implements Runnable{
int song_id;
long time;
int button_id;
Context ctx;
SoundPool soundpool;
public CustomPlayer(int s_id, long Time, Context ct){
song_id = load(ctx, s_id, 0);
time = Time;
ctx = ct;
}
public void run(){
long start = System.currentTimeMillis();
System.out.println("set_time:"+time+"Song_id:"+song_id+"current_time:"+start);
long end = start + time;
while (System.currentTimeMillis() < end){
//Initialization
soundpool = new SoundPool(8, AudioManager.STREAM_MUSIC, 0);
soundpool.play(song_id, 1.0f, 1.0f, 1, -1, 1.0f);
}
}
public int load (Context context, int resId, int priority){
return resId;
}
}
logcat
07-07 10:57:51.828: I/ApplicationPackageManager(13625): cscCountry is not German : INS
07-07 10:57:57.656: I/ApplicationPackageManager(13625): cscCountry is not German : INS
07-07 10:57:59.343: W/KeyCharacterMap(13625): Can't open keycharmap file
07-07 10:57:59.343: W/KeyCharacterMap(13625): Error loading keycharmap file
07-07 10:57:59.343: W/KeyCharacterMap(13625): Using default keymap
07-07 10:58:44.820: I/ApplicationPackageManager(13625): cscCountry is not German : INS
07-07 10:58:49.718: I/System.out(13625): TAG------->60000---->2130968576
07-07 10:58:49.726: W/SoundPool(13625): sample 2130968576 not READY
回答1:
I'm doing something similar with my app Beat Shaker and I was having the same problem. I solved it using the onLoadCompleteListener:
// Sound pool new instance
SoundPool spool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
// Sound pool on load complete listener
spool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
Log.i("OnLoadCompleteListener","Sound "+sampleId+" loaded.");
boolean loaded = true;
}
});
// Load the sample IDs
int soundId = new int[3];
soundId[0] = spool.load(this, R.raw.sound1, 1);
soundId[1] = spool.load(this, R.raw.sound2, 1);
soundId[2] = spool.load(this, R.raw.sound3, 1);
Later before playing the sound you can check if it is properly loaded using the boolean "loaded".
回答2:
You need to first load()
your sounds. This loads them into memory ready for play()
. This returns an id that you will need to store and pass to play()
From the SoundPool docs:
Let's examine a typical use case: A game consists of several levels of play. For each level, there is a set of unique sounds that are used only by that level. In this case, the game logic should create a new SoundPool object when the first level is loaded. The level data itself might contain the list of sounds to be used by this level. The loading logic iterates through the list of sounds calling the appropriate SoundPool.load() function. This should typically be done early in the process to allow time for decompressing the audio to raw PCM format before they are needed for playback.
http://developer.android.com/reference/android/media/SoundPool.html#load(android.content.res.AssetFileDescriptor, int)
Have a look at the SoundPool section in this example: http://www.vogella.com/articles/AndroidMedia/
回答3:
you can see code
public class SoundManager {
public static int SOUNDPOOLSND_MENU_BTN = 0;
public static int SOUNDPOOLSND_WIN = 1;
public static int SOUNDPOOLSND_LOOSE = 2;
public static int SOUNDPOOLSND_DRAW = 3;
public static int SOUNDPOOLSND_TICK1 = 4;
public static int SOUNDPOOLSND_TICK2 = 5;
public static int SOUNDPOOLSND_OUT_OF_TIME = 6;
public static int SOUNDPOOLSND_HISCORE = 7;
public static int SOUNDPOOLSND_CORRECT_LETTER = 8;
public static boolean isSoundTurnedOff;
private static SoundManager mSoundManager;
private SoundPool mSoundPool;
private SparseArray<Integer> mSoundPoolMap;
private AudioManager mAudioManager;
public static final int maxSounds = 4;
public static SoundManager getInstance(Context context) {
if (mSoundManager == null) {
mSoundManager = new SoundManager(context);
}
return mSoundManager;
}
public SoundManager(Context mContext) {
mAudioManager = (AudioManager) mContext
.getSystemService(Context.AUDIO_SERVICE);
mSoundPool = new SoundPool(maxSounds, AudioManager.STREAM_MUSIC, 0);
mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
boolean loaded = true;
}
});
mSoundPoolMap = new SparseArray<Integer>();
mSoundPoolMap.put(SOUNDPOOLSND_MENU_BTN,
mSoundPool.load(mContext, R.raw.rain, 0));
mSoundPoolMap.put(SOUNDPOOLSND_WIN,
mSoundPool.load(mContext, R.raw.nature, 1));
mSoundPoolMap.put(SOUNDPOOLSND_LOOSE,
mSoundPool.load(mContext, R.raw.piano, 2));
mSoundPoolMap.put(SOUNDPOOLSND_TICK1,
mSoundPool.load(mContext, R.raw.relax, 3));
mSoundPoolMap.put(SOUNDPOOLSND_TICK2,
mSoundPool.load(mContext, R.raw.storm, 4));
// testing simultaneous playing
int streamVolume = mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
mSoundPool.play(mSoundPoolMap.get(0), streamVolume, streamVolume, 1,
0, 1f);
mSoundPool.play(mSoundPoolMap.get(1), streamVolume, streamVolume, 1, 0,
1f);
mSoundPool.play(mSoundPoolMap.get(2), streamVolume, streamVolume, 1, 0,
1f);
}
public void playSound(int index) {
if (isSoundTurnedOff)
return;
int streamVolume = mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume,
1, 0, 1f);
}
public static void clear() {
if (mSoundManager != null) {
mSoundManager.mSoundPool = null;
mSoundManager.mAudioManager = null;
mSoundManager.mSoundPoolMap = null;
}
mSoundManager = null;
}
}
来源:https://stackoverflow.com/questions/17509608/how-to-play-a-sound-simultaneously-using-soundpool-for-a-specific-period-of-time