Les sons sous Android

 

Il s'agit de jouer un effet sonore (une sonnerie, une explosion, un beep) directement depuis votre application.

Image non trouvée ! Il s'agit bien d'effets sonores, pas de jouer une musique en arrière plan. Il existe une autre classe pour cela: MediaPlayer().

La différence entre ces deux classes ? Et bien SoundPool servira à jouer des sons qui n'occupent pas trop de place, car ils seront chargés entièrement en mémoire (la taille de ce tampon étant limitée, si le son est trop volumineux, il sera tronqué). Alors que la classe MediaPlayer() charge par blocs de petites tailles en mémoire un fichier qu'il interprète pendant ce temps donc à utiliser pour des fichiers de musique qui sont généralement plus volumineux.

 

La classe SoundPool

Nous utiliserons la classe SoundPool() qui passe par le service MediaPlayer pour décoder des flux audios 16-bit PCM mono ou stéréo (MP3, ogg ou wav).

SoundPool(int maxStreams, int streamType, int srcQuality)

Son constructeur a besoin de paramètres qui sont:

maxStreams indiquant le nombre maximum de flux audios que le spool pourra gérer en même temps.

streamType le type de flux audio (AudioManager.STREAM_MUSIC)

srcQuality à 0 pour le moment, car sans effet !

 

Vous le coderez généralement ainsi:

SoundPool soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);

 

Charger un son

La classe SoundPool propose une méthode load() pour charger un fichier son. Il existe plusieurs solutions pour charger un son.

Cette méthode va retourner un identifiant vers ce fichier son. Il sera utilisé ensuite pour le jouer, ou pour modifier des paramètres.

Cette méthode aura au moins un paramètre commun:

priority qui est le niveau de priorité pour jouet le son. Cette valeur n'a pas d'effet pour le moment est doit être positionnée à 1.

 

Soit votre son est stocké dans votre projet sous asset

Dans ce cas, la signature de la méthode est: public int load (AssetFileDescriptor afd, int priority)

// Il faut alors récupérer une instance assetManager

AssetManager assetManager = getAssets();

AssetFileDescriptor descriptor=null;
try {

// Construire descriptor

descriptor = assetManager.openFd(FICHIERSON); // FICHIERSON étant le nom du fichier son à charger (si possible, placez ses sons dans un sous répertoire: raw/monson.ogg par exemple)

explosionId = soundPool.load(descriptor, 1);

} catch (IOException e) {

// TODO Auto-generated catch block
e.printStackTrace();

}

Soit votre son est stocké dans votre projet comme ressource

La signature est alors public int load (Context context, int resId, int priority)

resId étant la ressource de votre fichier son composé de la manière suivante:

Si vous avez un fichier son monson.ogg dans res/raw, le resId sera R.raw.monson

Image non trouvée !Le répertoire raw n'existe pas forcement dans un projet. Dans ce cas, ce sera à vous de le créer et pensez à faire un clean sur le projet pour qu'il soit reconnu dans eclipse !

Image non trouvée !Le nom du fichier doit être unique, car vous constaterez que l'extension du fichier n'est pas utilisé dans l'identifiant de ressource ! Donc pb. si monson.ogg et monson.mp3 !

explosionId = soundPool.load (this, R.raw.monson, 1);

Soit il s'agit d'un fichier

public int load (String path, int priority) avec path le chemin d'accès au fichier audio (cf. environnement).

 

Patientez le temps du chargement...

Vous risquez d'avoir un message du style "Soundpool sample not ready" dans la log. Il apparaît lorsque vous voulez jouer le son alors que celui-ci n'a pas encore été ou fini d'être chargé.

Pour éviter ce problème des plus désagréable, il faudra utiliser un listener sur le load

Exemple de code, avec loaded définit à false initialement:

soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {

public void onLoadComplete(SoundPool soundPool, int sampleId,int status) {
loaded = true;
}

});

Si la variable passe à vrai, alors le/les chargements sont finis.

 

Jouer le son

Pour jouer un son, il suffit d'utiliser la méthode play ()

Image non trouvée !N'oubliez pas de vérifier que le chargement du son est bien terminé !

public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

Avec en entrée:

soundID L'id du son retourné par la méthode load()
leftVolume volume gauche de 0.0 (muet) à 1.0 (max.)
rightVolume volume droite 0.0 à 1.0
priority priorité sur le flux (0 = pour la priorité la plus basse)
loop type de boucle - pour rejouet le même son en boucle n ou plutôt "loop" fois (0 = pas de boucle, -1 = boucle infinie, 1 rejouet le son 1 fois, 2 pour 2 fois, ...)
rate vitesse pour jouet le son(1.0 = normal, 0.5 rapide à 2.0 lentement)

En sortie

0 si échec, sinon un streamID qui pourra servir avec d'autres méthodes pendant que le son est joué.

Pendant que le son est joué, il sera possible (via le streamID) de changer les paramètres passés à la méthode play():

Modifier le volume gauche/droite final void setVolume(int streamID, float leftVolume, float rightVolume)

Changer la priorité: public final void setPriority (int streamID, int priority)

modifier le type de boucle: public final void setLoop (int streamID, int loop)

public final void setRate (int streamID, float rate)

Mais aussi:

Faire une pause : final void pause(int streamID). Intéressant dans le cycle de vie d'une activité cf. onPause sur Activité

Relancer un flux: final void resume(int streamID). Intéressant dans le cycle de vie d'une activité cf. onResume sur Activité

Stopper un flux : final void stop(int streamID). Intéressant dans le cycle de vie d'une activité cf. onStop sur Activité

Contrôles de tous les flux

final void autoPause() pour mettre en pause tous les flux

final void autoResume() pour les relancer

Clôture

Il sera possible de libérer de la ressource mémoire en clôturant un flux via la méthode final boolean unload(int soundID)

Mais aussi de libérer toute la mémoire prise par un SoundPool via final void release()

Exemple de code

 

Annexe

Dans le cas d'utilisation de notifications pour informer l'utilisateur, il faudra la méthode correspondante pour jouer un son !