L'échantillon de Soundpool n'est pas prêt

J'ai un fichier .wav que j'aimerais utiliser dans mon jeu, je charge actuellement le son dans onCreate() de chaque activité dans le jeu.

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

Le son sera lue une fois l'activité démarrée.

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

Le problème est parfois que je vais frapper l'erreur "sample x not ready" . Est-il possible de charger le fichier .wav une fois lors du démarrage du jeu et de le garder en mémoire et l'utiliser plus tard dans le jeu? Ou est-il possible d'attendre 1-2 secondes pour que le son soit chargé?

  • Problèmes avec Android Soundpool
  • Android MediaPlayer setNextMediaPlayer () alternative
  • Savoir si le chargement d'un son avec SoundPool a été réussi sur Android 1.6 / 2.0 / 2.1
  • Comment jouer des sons à des périodes précises sur différents appareils dans Android
  • Comment puis-je savoir si un son a terminé de jouer dans Android?
  • AudioFlinger n'a pas pu créer de piste. Statut: -12
  • Android SoundPool: soyez informé à la fin de la lecture
  • Soundpool ne joue que les 5 premières secondes du fichier. Pourquoi?
  • 8 Solutions collect form web for “L'échantillon de Soundpool n'est pas prêt”

    Vous devrez attendre qu'il finisse en ajoutant un auditeur via SoundPool.setOnLoadCompleteListener .

    Puisque mon projet est compatible avec Android 1.5 et que je n'ai pas pu utiliser setOnLoadCompleteListener, j'ai résolu de reporter la lecture du son. Mon code source suit:

      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(); } 

    Vous devriez utiliser setOnLoadCompleteListener si possible … sinon, enveloppez une boucle while autour de votre appel à 'play'. quelque chose comme:

     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);} 

    Cela reviendra 'play' 1000 fois sur un intervalle de 10 ms. Cela devrait être exécuté sur un fil non-ui bien sûr, et n'est toujours pas idéal. Mais peut-être un peu plus fort que d'attendre un temps arbitraire et s'attendre à ce que la piscine soit prête.

    La bibliothèque SoundPool utilise le service MediaPlayer pour décoder l'audio dans un flux mono ou stéréo PCM brisé de 16 bits que nous pouvons simplement appeler la préparation du Stream, ce qui prend certaines fois en fonction de la taille du fichier audio. Et si nous essayons de jouer le son avant que le processus ne soit terminé, nous obtenons une erreur «échantillon x non prêt».

    Il existe deux solutions pour cela

    1. Implémente setOnLoadCompleteListener ou
    2. Attendre un temps arbitraire pour que la préparation soit terminée

    Et ensuite jouez-le Notez qu'il n'y a pas d'exception pour cette condition ou que l'application ne se bloque pas sans tentative de capture

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

    // Dans le constructeur

     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; } }); 

    // alors, où que vous vouliez jouer le son, tapez

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

    J'ai résolu avec un problème de simple cycle de do-while. La méthode play () renvoie l'ID courant non-nul s'il est réussi, zéro s'il échoue. Donc, il suffit de vérifier la valeur de retour.

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

    Cela fonctionnerait pour vous définitivement!

     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(); } 

    Cela semble fou, mais ne jouez pas immédiatement. Donnez à votre application quelques secondes pour initialiser SoundPool. Dans mon application, c'était exactement le problème; J'ai ajouté un faux écran "chargement" de ~ 3 secondes, et tout a fonctionné. (Je n'avais même pas besoin de précharger les sons.)

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.