2010-06-14 5 views
8

Si je joue un seul son, cela fonctionne correctement. L'ajout d'un second son provoque un blocage.Lecture de plusieurs sons à l'aide de SoundManager

Quelqu'un sait ce qui cause le problème?

private SoundManager mSoundManager; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.sos); 

    mSoundManager = new SoundManager(); 
    mSoundManager.initSounds(getBaseContext()); 

    mSoundManager.addSound(1,R.raw.dit); 
    mSoundManager.addSound(1,R.raw.dah); 

    Button SoundButton = (Button)findViewById(R.id.SoundButton); 
    SoundButton.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      mSoundManager.playSound(1); 
      mSoundManager.playSound(2); 
     } 
    }); 
} 
+0

Quelle est l'exception qui provoque le blocage? Trace de la pile? –

Répondre

14
mSoundManager.addSound(1,R.raw.dit); 
mSoundManager.addSound(1,R.raw.dah); 

Vous devez changer la deuxième ligne à:

mSoundManager.addSound(2,R.raw.dah); 

Pour jouer plusieurs sons à la fois, vous devez d'abord laisser le SOUNDPOOL savoir que. Dans la déclaration de SoundPool notez que j'ai spécifié 20 flux. J'ai beaucoup de pistolets et de méchants qui font du bruit dans mon jeu, et chacun a une boucle sonore très courte, < 3000ms. Remarquez quand j'ajoute un son ci-dessous je garde la trace de l'index spécifié dans un vecteur appelé, "mAvailibleSounds", de cette façon mon jeu peut essayer de jouer des sons pour des éléments qui n'existent pas et continuer sans s'écraser. Chaque index dans ce cas correspond à un identifiant d'image-objet. Juste pour que vous compreniez comment je fais correspondre des sons particuliers à des sprites spécifiques.

Ensuite, nous mettons en file d'attente des sons, avec playSound(). Chaque fois que cela se produit, un soundId est déposé dans une pile, que j'applique ensuite chaque fois que mon délai d'expiration se produit. Cela me permet de tuer un flux après qu'il a joué, et de le réutiliser à nouveau. Je choisis 20 streams parce que mon jeu est très bruyant. Après cela, les sons sont délavés, de sorte que chaque application nécessite un nombre magique.

J'ai trouvé cette source here, et j'ai ajouté la file d'attente exécutable & moi-même.

private SoundPool mSoundPool; 
private HashMap<Integer, Integer> mSoundPoolMap; 
private AudioManager mAudioManager; 
private Context mContext; 
private Vector<Integer> mAvailibleSounds = new Vector<Integer>(); 
private Vector<Integer> mKillSoundQueue = new Vector<Integer>(); 
private Handler mHandler = new Handler(); 

public SoundManager(){} 

public void initSounds(Context theContext) { 
    mContext = theContext; 
     mSoundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0); 
     mSoundPoolMap = new HashMap<Integer, Integer>(); 
     mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);  
} 

public void addSound(int Index, int SoundID) 
{ 
    mAvailibleSounds.add(Index); 
    mSoundPoolMap.put(Index, mSoundPool.load(mContext, SoundID, 1)); 

} 

public void playSound(int index) { 
    // dont have a sound for this obj, return. 
    if(mAvailibleSounds.contains(index)){ 

     int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
     int soundId = mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f); 

     mKillSoundQueue.add(soundId); 

     // schedule the current sound to stop after set milliseconds 
     mHandler.postDelayed(new Runnable() { 
     public void run() { 
     if(!mKillSoundQueue.isEmpty()){ 
     mSoundPool.stop(mKillSoundQueue.firstElement()); 
     } 
      } 
     }, 3000); 
    } 
} 
+0

J'ai remarqué que cette approche provoque parfois des retards micro. C'est notable quand je joue un ensemble de sons courts l'un après l'autre. Qu'est ce que ça pourrait être? –