Lors de l'utilisation de la classe SoundPool pour la lecture de sons sur Android, un problème courant est l'absence de son émis, même si le code semble correct.
Code problématique
/**
* Lecture du son
*/
private void lancerAudio() {
SoundPool audioPool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
audioPool.load(this, R.raw.beep, 1); // Charge la ressource, retourne 1
audioPool.play(1, 1, 1, 0, 0, 1); // Tente de jouer, retourne 0
}
Cause du problème
SoundPool effectue le chargement des fichiers audio dans un thread séparé. Dans le code ci-dessus, la méthode play est appelée immédiatement après load, alors que le fichier n'est pas encore complètement chargé en mémoire, ce qui entraîne l'absence de son.
Solution
Pour corriger cela, il faut soit intégrer un délai suffisant pour permettre le chargement du fichier audio, soit utiliser un écouteur de chargement complet via l'interface SoundPool.OnLoadCompleteListener, spécifiquement sa méthode onLoadComplete(SoundPool soundPool, int sampleId, int status) pour vérifier la fin du processus.
Code corrigé avec préchagrement :
private SoundPool audioPool; // Instance du pool audio
protected void onCreate(Bundle savedInstanceState) {
// Préchargement du son dans onCreate
audioPool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
audioPool.load(this, R.raw.beep, 1);
}
/**
* Lecture du son
*/
private void lancerAudio() {
audioPool.play(1, 1, 1, 0, 0, 1);
}
Comparaison avec d'autres classes de lecture audio
Sur Android, deux classes principales sont utilisées pour la lecture audio : MediaPlayer et SoundPool.
- MediaPlayer : conçu pour les fichiers audio ou vidéo longs, et les flux en continu. Il ne peut lire qu'un seul fichier à la fois et offre des méthodes de contrôle avancées comme pause, arrêt, etc.
- SoundPool : adapté pour les sons courts et en temps réel, tels que les effets sonores dans les jeux. Il supporte la lecture simultanée de plusieurs sons, avec une faible latence.
Paramètres clés de la classe SoundPool
Voici une analyse des paramètres courants, basée sur l'exemple précédent :
- Constructeur SoundPool(int maxStream, int streamType, int srcQuality) :
- maxStream : nombre maximum de flux audio pouvant être lus simultanément (ex. : 10).
- streamType : type de flux, comme AudioManager.STREAM_SYSTEM pour les sons système, ou STREAM_MUSIC pour la musique.
- srcQuality : qualité de conversion, par défaut 0. Pour les sons courts, cet impact est généralement négligeable.
- load(Context context, int resId, int priority) :
- context : le contexte de l'application.
- resId : l'identifiant de la ressource audio (ex. : R.raw.beep).
- priorité : priorité de chargement, habituellement 1.
- Retourne un entier représentant l'index du fichier chargé, à partir de 1, incrémenté à chaque appel.
- play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) :
- soundID : identifiant du son, correspondant à la valeur retournée par load.
- leftVolume et rightVolume : volumes pour les canaux gauche et droit, typiquement 1.0 pour un volume maximal.
- priorité : priorité de lecture, souvent 0 par défaut.
- loop : mode de répétition, 0 pour aucune boucle, 1 ou plus pour le nombre de répétitions.
- rate : vitesse de lecture, comrpise entre 0.5 (ralentissement de 50%) et 2.0 (accélération de 100%).