pbm avec setMessage() dans javax.sound.midi
Bonjour,
j'utilise l'API midi de Java pour créer et jouer deux notes de musique (un La suivi d'un Si). Dans le premier code ci-dessous, tout est fait de façon classique et fonctionne.
Code:
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
| import javax.sound.midi.*;
public class PremierCode {
public static void main(String[] args) {
PremierCode premCode = new PremierCode();
premCode.play();
}
public void play(){
try{
Sequencer seq = MidiSystem.getSequencer();
seq.open();
Sequence s = new Sequence(Sequence.PPQ,1); // 120 bpm par défaut et 1 tick par beat donc 2 ticks/s
Track t = s.createTrack();
ShortMessage note1On = new ShortMessage();
note1On.setMessage(ShortMessage.NOTE_ON, 1, 57, 100);
MidiEvent me1 = new MidiEvent(note1On, 1);
t.add(me1);
ShortMessage note1Off = new ShortMessage();
note1Off.setMessage(ShortMessage.NOTE_OFF, 1, 57, 100);
MidiEvent me2 = new MidiEvent(note1Off, 3);
t.add(me2);
ShortMessage note2On = new ShortMessage();
note2On.setMessage(ShortMessage.NOTE_ON, 1, 59, 100);
MidiEvent me3 = new MidiEvent(note2On, 3);
t.add(me3);
ShortMessage note2Off = new ShortMessage();
note2Off.setMessage(ShortMessage.NOTE_OFF, 1, 59, 100);
MidiEvent me4 = new MidiEvent(note2Off, 5);
t.add(me4);
seq.setSequence(s);
seq.start();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
} |
Par contre le deuxième code ci-dessous, qui vise à simplifier le premier en réutilisant deux objets de la classe ShortMessage déjà créés, ne fonctionne plus. Plus exactement on entend deux fois la même note.
Code:
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
|
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
public class DeuxiemeCode {
public static void main(String[] args) {
DeuxiemeCode deuxCode = new DeuxiemeCode();
deuxCode.play();
}
public void play(){
try{
Sequencer seq = MidiSystem.getSequencer();
seq.open();
Sequence s = new Sequence(Sequence.PPQ,1); // 120 bpm par défaut et 1 tick par beat donc 2 ticks/s
Track t = s.createTrack();
ShortMessage note1On = new ShortMessage();
note1On.setMessage(ShortMessage.NOTE_ON, 1, 57, 100);
MidiEvent me1 = new MidiEvent(note1On, 1);
t.add(me1);
ShortMessage note1Off = new ShortMessage();
note1Off.setMessage(ShortMessage.NOTE_OFF, 1, 57, 100);
MidiEvent me2 = new MidiEvent(note1Off, 3);
t.add(me2);
note1On.setMessage(ShortMessage.NOTE_ON, 1, 59, 100);
MidiEvent me3 = new MidiEvent(note1On, 3);
t.add(me3);
note1Off.setMessage(ShortMessage.NOTE_OFF, 1, 59, 100);
MidiEvent me4 = new MidiEvent(note1Off, 5);
t.add(me4);
seq.setSequence(s);
seq.start();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
} |
J'ai tout de suite pensé à un problème de passage d'argument, mais en l'occurence la méthode setMessage() est bien censée modifier le contenu de l'objet ShortMessage. Je sèche vraiment et suis preneur de toute aide!
Merci d'avance,
F.B.
[Résolu] pbm avec setMEssage() dans javax.sound.midi
Merci pour la réponse.
Entre temps j'ai réfléchi à mon problème et je pense avoir compris ce qui se passe.
Un MidiEvent est un objet comprenant deux champs: un MidiMessage (en l'occurence un ShortMessage dans mon cas), donc un objet Java, qui contient une référence vers le contenu de l'objet,
et une variable entière, donc un type primitif, qui contient l'entier lui-même.
Lorsque je réutilise le premier ShortMessage note1On pour faire la deuxième note, ce ShortMessage est effectivement modifié par setMessage (ses champs sont modifiés).
Mais comme les MidiEvent déjà créés me1 et me2 (utilisés pour faire la première note) ne contiennent que des RÉFÉRENCES aux MidiMessage (note1On et note1Off) qui les composent,
ces MidiEvent sont eux aussi modifiés, c'est à dire ils contiennent des références vers le nouveau ShortMessage, c'est à dire vers la deuxième note.
Il faut donc créer autant de ShortMessage que nécesaires.
Merci encore pour l'aide, cdlt,
F.B.