l'API Java Sound
Exemple: Un simple lecteur audio
L'ensemble des sources de cette présentation est disponible ici.Écrire un simple lecteur audio, permettant de lire les formats audio de base est très simple et nous détaillerons ici les étapes de la réalisation d'un tel lecteur. Le code ci-après est extrait et remanié à partir des classes
AudioPlayer
et AudioPlayerGUI
disponible dans les sources.
Construction du flux audio à partir d'un fichier
AudioInputStream audioInputStream = null;
try{
//obtention d'un flux audio à partir d'un fichier (objet File)
audioInputStream = AudioSystem.getAudioInputStream(file);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
La classe
AudioSystem
offre nombre méthode permettant d'interagir avec le système. Ici on récupère le flux audio
créé à partir d'un fichier (objet File). Si le format audio n'est pas supporté une exception est levée.
L'objet AudioInputStream
est une implémentation de l'interface InputStream
de java.io
Récupération du format Audio
//Il est nécessaire de connaître le format audio du fichier
// d'entrée
// pour permettre à java de créer l'objet DataLine adéquat
AudioFormat audioFormat = audioInputStream.getFormat();
Le format audio est défini par le fichier que l'on souhaite lire. Il est nécessaire de le connaître .
Construction d’un Objet DataLine.Info
Afin de récupérer la ligne il va falloir spécifier au système le type de ligne que l'on veut. Pour cela il est nécessaire de construire un objetDataLine.info
// En plus du format du flux audio d'entrée il est nécessaire de
// spécifier le type de DataLine qu'on veut
// ici le DataLine qu'on souhaite est un SourceDataLine qui permet
// la
// lecture (targetDataLine permet l'enregistrement).
DataLine.Info info = new DataLine.Info(SourceDataLine.class,
audioFormat);
Récupération de l’objet Line
souhaité
A partir de l'objet Info
créé, on va pouvoir récupérer une ligne de type SourceDataLine
puisque l'on veut restituer un son
// On récupère le DataLine adéquat et on l'ouvre
SourceDataLine line;
try {
line = (SourceDataLine) AudioSystem.getLine(info);
} catch (LineUnavailableException e) {
e.printStackTrace();
return;
}
On voit qu'il est nécessaire de caster la ligne obtenue dans le type de ligne que l'on souhaite .
Ouverture de la ligne avec le bon format audio
try {
line.open(audioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
return;
}
Démarrage de la ligne
Pour que le flux soit effectivement redirigé sur la carte son il faut démarrer la ligne.
line.start();
Lecture sur le flux entrant et écriture sur la ligne
La lecture et l'écriture se fait comme pour n'importe quel flux.
try {
byte bytes[] = new byte[1024];
int bytesRead=0;
while (((bytesRead = audioInputStream.read(bytes, 0, bytes.length)) != -1)
&& !stop) {
line.write(bytes, 0, bytesRead);
}
} catch (IOException io) {
io.printStackTrace();
return;
}
Fermeture de la ligne
on ferme la ligne à la fin.
line.close();
Utilisation des événements dans une interface graphique
Dans le cas par exemple d'une interface graphique telle que celle disponible dans les sourcesAudioPlayerGUI
où l'on veut pouvoir être notifié de la fin de la lecture du fichier pour activer/désactiver des boutons, on peut enregistrer des écouteurs sur ces événements.
En supposant qu'on ai défini deux Action
associées à des boutons start et stop, on peut utiliser ces événements de la manière suivante :
play= new AbstractAction() {
public void actionPerformed(ActionEvent arg0) {
//On initialise notre player (c.f AudioPlayer.java)
player.init();
audioPlayerThread = new Thread(player);
audioPlayerThread.start();
//On ajoute un écouteur sur la Line de notre player
player.getLine().addLineListener(new LineListener(){
public void update(LineEvent le) {
//Écoute de l'evenement STOP envoyé par la ligne lorsque la lecture est terminée
if(le.getType()==LineEvent.Type.STOP){
play.setEnabled(true);
stop.setEnabled(false);
}
//Écoute de l' événement START envoyé par la ligne lorsque la ligne est démarrée
if(le.getType()==LineEvent.Type.START){
play.setEnabled(false);
stop.setEnabled(true);
}
}
});
}
};