2010-12-03 37 views
7

J'essaie de jouer deux sons simutaneosly dans android.J'ai créé deux MediaPlayers et j'utilise le code ci-dessous.Ils jouent actuellement l'un après l'autre.Ou pas exactement l'un après l'autre, mais un peu retardés dans l'autre.Jouer deux sons Simutaneosly

private void playSound(){ 
     if (mp1 != null) { 
      mp1.release(); 
     } 
     if (mp2 != null) { 
      mp2.release(); 
     } 


     mp1 = MediaPlayer.create(this, soundArray[0]); 
     mp2 = MediaPlayer.create(this, soundArray[3]); 
     mp1.start(); 
     mp2.start(); 

     } 

Merci

+1

Comment voulez-vous dire "retardé", est que secondes, microsecondes, dix secondes? A quelle distance les uns des autres voulez-vous qu'ils soient joués, * exactement * en même temps, et pas un instant plus tôt? – Patrick

+0

Très court ... microsecondes. Je veux qu'ils soient joués exactement en même temps oui. – james

+0

Je voulais dire quand ils ont joué, ils ont été retardés un peu dans l'autre. Je veux juste qu'ils jouent tous les deux à la même heure. – james

Répondre

2

faire deux choses à exactement en même temps est ..difficult. Dans un environnement à un seul thread, le système d'exploitation doit sauter entre les threads pour les simuler en même temps. Donc, pour pouvoir les exécuter en même temps, vous devez démarrer deux threads et attendre qu'ils arrivent au point où ils doivent être synchronisés, puis laisser les deux threads maintenant qu'ils doivent continuer.

Une autre solution consisterait à fusionner les deux flux sonores de sorte que cela ressemble à deux sons en cours de lecture. Bien que je ne suis pas très compétent dans la manipulation du son, et certainement pas sur Android ...

Une solution pour le premier serait de générer deux threads, démarrez-les tous les deux, puis utilisez un wait() et notify() pour les appeler MediaPlayer.start() en même temps, éventuellement avec la classe Lock.


Ok, donc un long exemple de la façon de synchroniser deux threads (basés sur here sont:

import java.util.concurrent.locks.*; 

class SynchronizeTest implements Runnable { 
    public static void main(String[] args) { 
     final ReentrantLock lock = new ReentrantLock(); 
     final Condition cond = lock.newCondition(); 

     new Thread(new SynchronizeTest(1, lock, cond)).start(); 
     new Thread(new SynchronizeTest(2, lock, cond)).start(); 
    } 

    private final int number; 
    private final ReentrantLock lock; 
    private final Condition cond; 

    public SynchronizeTest(int number, ReentrantLock lock, Condition cond) { 
     this.number = number; 
     this.lock = lock; 
     this.cond = cond; 
    } 

    public void run() { 
     try { 
      if (number == 1) { 
       put(); 
      } 
      else { 
       take(); 
      } 
     } 
     catch (InterruptedException ie) { } 
    } 

    public void put() throws InterruptedException { 
     lock.lock(); 
     try { 
      cond.await(); 
     } finally { 
      lock.unlock(); 
     } 
     System.out.println(number); 
    } 

    public void take() throws InterruptedException { 
     lock.lock(); 
     // wait for put to take the lock 
     Thread.sleep(300); 
     try { 
      cond.signal(); 
     } finally { 
      lock.unlock(); 
     } 
     System.out.println(number); 
    } 
} 

Cela peut probablement être codé beaucoup plus simple, mais je n'ai pas fait beaucoup de Java codage ces derniers temps .. :-(

+0

Si ce n'est pas trop de problèmes ou ne prendra pas trop de temps. Serait-il arrivé d'avoir un code de démo. Si ce n'est pas o.k. J'ai trouvé que l'utilisation de midi est suffisante pour mes besoins. – james

+0

@james: Malheureusement non. Je peux essayer de monter un petit exemple de Java (ce ne sera pas joli) mais je n'ai pas de téléphone Android pour le tester en ce moment. – Patrick

+0

Ok merci pas de problème – james

5

Jouer deux sons numériques simultanément est aussi simple que de les additionner (comme dans le monde réel), donc vous pouvez le faire vous-même tout en remplissant le tampon (et avoir le contrôle sur le temps)

Cela peut entraîner une augmentation de l'amplitude. Il convient donc de ne pas dépasser les limites numériques du type de tableau si vous ne souhaitez pas provoquer d'artefacts de découpage.

This question and answer pourrait également être utile

+1

ne le savais pas. Nice – Patrick

+0

Merci, mais semble avancé pour mes connaissances actuelles! – james

-1

J'ai pu obtenir deux sons à jouer au même moment en utilisant la classe SOUNDPOOL.

+0

si vous les appelez successivement ... alors ils ne sont vraiment pas démarrés en même temps, il y aura très peu de retard. Cela permettra aux sons de se chevaucher, mais le timing de ce qui est important ici. – YetAnotherDeveloper

+2

Si vous avez trouvé une solution, pouvez-vous mettre à jour votre message ou répondre à votre propre question? – YetAnotherDeveloper

0

J'ai été en mesure de modifier ce qui suit pour que cela fonctionne.Il convient de noter que cela n'a pas fonctionné dans l'émulateur (ils ont toujours joué l'un après l'autre), mais après l'avoir mis au téléphone, il a bien fonctionné.

http://www.droidnova.com/creating-sound-effects-in-android-part-1,570.html

+0

désolé pour les questions mais je veux m'assurer que je suis votre solution. donc à la fin vous venez d'appeler; playSound (1); playSound (2); playSound (3); playSound (4); J'ai personnellement trouvé que cela ne fonctionnait toujours pas pour moi. Si vous avez fait autre chose que cela, pouvez-vous expliquer? Merci. – YetAnotherDeveloper

-1

Organiser votre code: Créer les objets et charger les échantillons d'abord. Ensuite, utilisez une méthode pour les lire, et une autre pour les mettre en pause/les relâcher.

public class MainActivity extends Activity { 

MediaPlayer snd1, snd2; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    snd1 = MediaPlayer.create(this, R.raw.s01); 
    snd2 = MediaPlayer.create(this, R.raw.s02); 
} 

public void playSounds(View v) { 
    snd1.start(); 
    snd2.start(); 
} 
public void stopSounds(View v) { 
    snd1.pause(); 
    snd2.pause(); 
} 

}