Bonjour,
J'essaie de réaliser un logiciel me permettant de jouer de la batterie provenant de Rock Band sur mon ordinateur.
Pour ce faire, j'ai utilisé JInput pour récupérer les évènements généré par la batterie (qui réagit comme un vulgaire joystick), et je joue les sons avec la bibliothèque javax.sound.
Au point où j'en suis actuellement, dès que je tape sur un des pads, le son associé est joué. Cependant, si j'en joue 2 en même temps, seul un seul s'exprime. Le comportement souhaité serait que les 2 soient joués indépendamment. Seulement, je ne maitrise pas cette API, et j'en appelle donc à votre aide. Que dois-je faire pour que les sons soient joués indépendamment ?
Voici mon code :
Fonction main : écoute les évènements générés par la batterie et ordonne l'exécution des sons associés (si vous n'avez pas de batterie, connectez un joystick de votre choix et modifiez les noms des "components" par ceux correspondant à vos boutons - les récupérer en rajoutant par exemple un else System.out.println(comp.getName()); et en appuyant alors sur les boutons de votre joystick )
Classe DrumPlayer : charge les fichiers sons (pour éviter de les ouvrir/fermer à chaque utilisation) et exécute les sons en utilisant les bons paramètres (le SourceDataLine et les bytes des fichiers à écrire dans le SourceDataLine) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package drums; import net.java.games.input.Component; import net.java.games.input.Controller; import net.java.games.input.Controller.Type; import net.java.games.input.ControllerEnvironment; import net.java.games.input.Event; import net.java.games.input.EventQueue; /** * * @author claythest */ public class Main { /** * @param args the command line arguments */ public static void main(String[] args) { Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers(); Controller drums = null; int i = 0; while (i < controllers.length && drums == null) { if (controllers[i].getType() == Type.STICK) { drums = controllers[i]; } i++; } if (drums == null) { System.err.print("No Drums connected !"); System.exit(0); } DrumsPlayer drumsPlayer = new DrumsPlayer(); while (drums.poll()) { EventQueue queue = drums.getEventQueue(); Event event = new Event(); while (queue.getNextEvent(event)) { Component comp = event.getComponent(); float value = event.getValue(); if (value == 1.0f) { if (comp.getName().equals("C")) { drumsPlayer.red(); } else if (comp.getName().equals("X")) { drumsPlayer.yellow(); } else if (comp.getName().equals("A")) { drumsPlayer.blue(); } else if (comp.getName().equals("B")) { drumsPlayer.green(); } else if (comp.getName().equals("Y")) { drumsPlayer.orange(); } } } } } }
DrumNote : joue la note dans un nouveau thread en utilisant la méthode write du SourceDataLine :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package drums; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.UnsupportedAudioFileException; /** * * @author claythest */ public class DrumsPlayer { public static final int RED_PAD = 0; public static final int YELLOW_PAD = 1; public static final int BLUE_PAD = 2; public static final int GREEN_PAD = 3; public static final int ORANGE_PAD = 4; private static final String[] SOUND_FILES = new String[]{"snare.wav", "hihat.wav", "bass.wav", "crash.wav", "kick.wav"}; private static final int BYTES_BUFFER_SIZE = 524288; // 128Kb private SourceDataLine[] sourcesDataLine; private AudioFormat[] formats; private List<byte[]>[] soundsBytes; public DrumsPlayer() { loadSoundsFiles(); } private void loadSoundsFiles() { soundsBytes = new ArrayList[5]; sourcesDataLine = new SourceDataLine[5]; formats = new AudioFormat[5]; for (int i = 0; i < 5; i++) { AudioInputStream audioInputStream = null; try { soundsBytes[i] = new ArrayList<byte[]>(); File soundFile = new File(SOUND_FILES[i]); audioInputStream = AudioSystem.getAudioInputStream(soundFile); AudioFormat format = audioInputStream.getFormat(); DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); SourceDataLine auline = (SourceDataLine) AudioSystem.getLine(info); System.out.println(auline); formats[i] = format; sourcesDataLine[i] = auline; int nBytesRead = 0; byte[] abData = new byte[BYTES_BUFFER_SIZE]; while (nBytesRead != -1) { nBytesRead = audioInputStream.read(abData, 0, abData.length); if (nBytesRead >= 0) { abData = Arrays.copyOf(abData, nBytesRead); soundsBytes[i].add(abData); } } } catch (LineUnavailableException ex) { Logger.getLogger(DrumsPlayer.class.getName()).log(Level.SEVERE, null, ex); } catch (UnsupportedAudioFileException ex) { Logger.getLogger(DrumsPlayer.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(DrumsPlayer.class.getName()).log(Level.SEVERE, null, ex); } finally { try { audioInputStream.close(); } catch (IOException ex) { Logger.getLogger(DrumsPlayer.class.getName()).log(Level.SEVERE, null, ex); } } } } public void red() { new DrumNote(soundsBytes[RED_PAD], sourcesDataLine[RED_PAD], formats[RED_PAD]); } public void yellow() { new DrumNote(soundsBytes[YELLOW_PAD], sourcesDataLine[YELLOW_PAD], formats[YELLOW_PAD]); } public void blue() { new DrumNote(soundsBytes[BLUE_PAD], sourcesDataLine[BLUE_PAD], formats[BLUE_PAD]); } public void green() { new DrumNote(soundsBytes[GREEN_PAD], sourcesDataLine[GREEN_PAD], formats[GREEN_PAD]); } public void orange() { new DrumNote(soundsBytes[ORANGE_PAD], sourcesDataLine[ORANGE_PAD], formats[ORANGE_PAD]); } }
Pour lancer ce programme, il vous faut télécharger l'API JInput (attention au classpath qui a besoin de localiser le .jar et les dll ou .so). Je mets aussi en pièce jointe les différents sons (au format wav) utilisés.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package drums; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; /** * * @author claythest */ public class DrumNote implements Runnable { private List<byte[]> toRead; private SourceDataLine auline; private AudioFormat format; public DrumNote(List<byte[]> toRead, SourceDataLine auline, AudioFormat format) { this.toRead = toRead; this.auline = auline; this.format = format; new Thread(this).start(); } public void run() { try { auline.open(format); auline.start(); for (int i = 0; i < toRead.size(); i++) { byte[] abData = toRead.get(i); auline.write(abData, 0, abData.length); } auline.drain(); auline.close(); } catch (LineUnavailableException ex) { Logger.getLogger(DrumNote.class.getName()).log(Level.SEVERE, null, ex); } } }
Merci d'avance pour votre aide
Partager