I. SoundPool vs. MediaPlayer▲
Tout d'abord, il faut savoir que sur Android, il existe deux classes pour jouer des sons :
- la classe SoundPool ;
- la classe MediaPlayer.
Je vous conseille grandement de jeter un coup d'œil à leur documentation afin d'avoir un bref aperçu de ce que nous allons traiter dans cet article.
En examinant bien la description de chacune des classes, on remarquera vite que la classe SoundPool ne nous intéressera pas dans notre cas. En effet, l'objectif de ce dernier est de pouvoir charger en mémoire des sons et ainsi de pouvoir les jouer autant qu'on veut dans l'application sans devoir souffrir d'une latence de chargement et de décompression du fichier audio. Bien sûr il a d'autres avantages, mais je vous laisse les découvrir par vous-même.
À savoir que ce que nous entendons par sons, ce sont des clips, bruitages ou effets, majoritairement très courts, que l'on rencontre souvent dans les jeux (explosion, laser, porte…).
Ainsi, le SoundPool est pratique mais impose une taille limite pour le chargement de fichiers audio. En cas de dépassement, rapidement atteint si le son dure plus de cinq secondes, cela n'influencera en rien l'exécution du programme, mais simplement que le son en question ne sera jamais entendu par l'utilisateur. Cependant, si vous faites attention à la sortie LogCat de l'appareil, vous constaterez plusieurs messages d'erreur venant de la part de cette classe.
Pour la création de soundboards, il est très probable que l'on veuille jouer des sons qui risquent de dépasser cette taille limite. De plus, pour une application de ce type, le chargement du fichier à chaque lecture aura très peu d'impact sur l'exécution du programme. Ainsi voilà pourquoi nous utiliserons la classe MediaPlayer fournie par la librairie Android.
Dans le projet que nous allons réaliser, on développera une simple soundboard avec ces deux sons :
- Mario - 1up (Miroir);
- Mario - Coin (Miroir).
À noter que la classe MediaPlayer est capable de lire toute sorte de formats tels que le mp3, ogg, wav, mid… et permet donc aussi bien de jouer des sons que des musiques entières.
II. Création du projet▲
On va tout d'abord créer et préparer l'interface de l'application. Commencez par créer un simple projet Android (du nom et de l'API que vous voulez) dans votre environnement, puis allez éditer le layout principal (res/layout/main.xml) pour y ajouter deux boutons qu'on nommera respectivement btn_sound_1up et btn_sound_coin avec comme label (texte) 1-up et Coin.
Pour les plus paresseux, voici le XML de notre layout à copier/coller dans votre main.xml :
< ?xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<linearlayout
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
orientation
=
"vertical"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"fill_parent"
android
:
gravity
=
"center"
>
<textview
android
:
layout_height
=
"wrap_content"
android
:
text
=
"Soundboard"
android
:
layout_width
=
"wrap_content"
/>
<button
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
id
=
"@+id/btn_sound_1up"
android
:
text
=
"1-up"
></button>
<button
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
text
=
"Coin"
android
:
id
=
"@+id/btn_sound_coin"
></button>
</linearlayout>
III. Ajout des sons dans le projet▲
Pour pouvoir jouer les sons, ces derniers devront forcément être présents quelque part. Dans notre cas, nous allons les inclure dans l'APK de l'application. Pour cela, créez un nouveau dossier dans le répertoire res et nommez-le raw. Copiez-y les deux sons fournis auparavant. Ainsi, ils vont donc être ajoutés en tant que ressources à l'application, et seront accessibles depuis la classe R, comme une image placée dans le dossier drawable.
IV. Lire les sons dans l'application▲
Nous voici maintenant dans la partie la plus intéressante : nous allons écrire le code permettant de jouer un son disponible en tant que ressource et associer un bouton à un son.
Ouvrez donc tout d'abord le code de votre Activity principale, et vérifiez que le layout créé auparavant a bien été associé à celle-ci :
setContentView
(
R.layout.main);
Ensuite, déclarons tout d'abord comme attribut à cette classe un objet de type MediaPlayer :
private
MediaPlayer mPlayer =
null
;
Puis écrivons la méthode permettant de jouer la ressource passée en paramètre :
private
void
playSound
(
int
resId) {
if
(
mPlayer !=
null
) {
mPlayer.stop
(
);
mPlayer.release
(
);
}
mPlayer =
MediaPlayer.create
(
this
, resId);
mPlayer.start
(
);
}
La classe MediaPlayer possède une méthode statique create, prenant comme paramètres le contexte et l'identifiant de la ressource à jouer, puis renvoyant une instance d'elle-même avec le son chargé et prêt à être joué. Il suffit alors d'appeler la méthode start à partir de cette dernière afin de pouvoir enfin écouter le clip.
Il n'est pas nécessaire d'appeler la méthode prepare de l'instance
renvoyée par la méthode create, ce qui d'ailleurs provoquerait une exception, puisqu'elle se
charge elle-même d'y faire l'appel.
http://developer.android.com/reference/android/media/MediaPlayer.html#create(android.content.Context, int)
Par la suite, il est aussi recommandé d'appeler la méthode release afin de libérer la ressource et donc de l'espace mémoire. Pour faire cela proprement, on surchargera aussi la méthode onPause de l'Activity pour libérer la ressource avant la fermeture de l'application :
@Override
public
void
onPause
(
) {
super
.onPause
(
);
if
(
mPlayer !=
null
) {
mPlayer.stop
(
);
mPlayer.release
(
);
}
}
Et pour finir, appelons la méthode à chaque clic sur un bouton en lui attribuant la ressource à jouer :
Button btn_sound_1up =
(
Button) findViewById
(
R.id.btn_sound_1up);
btn_sound_1up.setOnClickListener
(
new
OnClickListener
(
) {
@Override
public
void
onClick
(
View v) {
playSound
(
R.raw.up);
}
}
);
Button btn_sound_coin =
(
Button) findViewById
(
R.id.btn_sound_coin);
btn_sound_coin.setOnClickListener
(
new
OnClickListener
(
) {
@Override
public
void
onClick
(
View v) {
playSound
(
R.raw.coin);
}
}
);
Voici le code entier de l'Activity :
package
com.jidul.android.mysoundboard;
import
android.app.Activity;
import
android.media.MediaPlayer;
import
android.os.Bundle;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
public
class
MySoundboard extends
Activity {
private
MediaPlayer mPlayer =
null
;
/** Called when the activity is first created. */
@Override
public
void
onCreate
(
Bundle savedInstanceState) {
super
.onCreate
(
savedInstanceState);
setContentView
(
R.layout.main);
Button btn_sound_1up =
(
Button) findViewById
(
R.id.btn_sound_1up);
btn_sound_1up.setOnClickListener
(
new
OnClickListener
(
) {
@Override
public
void
onClick
(
View v) {
playSound
(
R.raw.up);
}
}
);
Button btn_sound_coin =
(
Button) findViewById
(
R.id.btn_sound_coin);
btn_sound_coin.setOnClickListener
(
new
OnClickListener
(
) {
@Override
public
void
onClick
(
View v) {
playSound
(
R.raw.coin);
}
}
);
}
@Override
public
void
onPause
(
) {
super
.onPause
(
);
if
(
mPlayer !=
null
) {
mPlayer.stop
(
);
mPlayer.release
(
);
}
}
private
void
playSound
(
int
resId) {
if
(
mPlayer !=
null
) {
mPlayer.stop
(
);
mPlayer.release
(
);
}
mPlayer =
MediaPlayer.create
(
this
, resId);
mPlayer.start
(
);
}
}
Maintenant, vous n'avez plus qu'à lancer et tester votre application dans l'émulateur ou sur votre téléphone pour vérifier que tout fonctionne correctement en appuyant sur les boutons.
À partir de maintenant, vous êtes donc aussi capable de créer votre propre soundboard et ainsi d'enrichir à votre tour l'Android Market !
V. Remerciements▲
Je tiens particulièrement à remercier ClaudeLELOUP et jacques_jean pour leur relecture attentive, ainsi que Feanorin pour sa relecture technique.