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
104
105
106
107
108
109
110
111
112
113
114
|
void initSynth() // Initialisation du synthétiseur
{
Synthesizer synth = null;
try { synth = MidiSystem.getSynthesizer(); }
catch (MidiUnavailableException e) { exit(); }
try { synth.open(); }
catch (MidiUnavailableException e) { exit(); }
channel = synth.getChannels()[midiChannelNumber];
}
int processNote(int activatedKey, boolean white, boolean on, boolean autoplay) // Détection de la note cliquée (activatedKey : code de la touche, white : touche blanche ou touche noire, on : activer ou désactiver, autoplay : jouée par l'utilisateur ou par l'ordinateur)
{
int keyNumber;
int octave;
if(autoplay)
{
if(on)
keysPressed[white ? 1 : 0][activatedKey-1] = -1;
else
keysPressed[white ? 1 : 0][activatedKey-1] = 0;
}
else if(on && keysPressed[white ? 1 : 0][activatedKey-1] > 0) // Si déjà activée
return -1;
if (white)
{
keyNumber = (activatedKey-1)%7; // Calcul du numéro de touche dans l'octave
octave = (activatedKey-1-keyNumber)/7; // Calcul de l'octave
if (keyNumber < 3)
keyNumber *= 2;
else
keyNumber = (keyNumber*2)-1;
}
else
{
keyNumber = (activatedKey-1)%5;
octave = (activatedKey-1-keyNumber)/5;
if (keyNumber < 2)
keyNumber = (keyNumber*2)+1;
else
keyNumber = (keyNumber*2)+2;
}
octave -= (numOctaves-numOctaves%2)/2; // Ajustement de l'octave
keyNumber = octave*12+baseNote+keyNumber; // Calcul du code MIDI de la note à jouer
if(on)
{
channel.noteOn(keyNumber, midiVelocity); // Joue la note
keysPressed[white ? 1 : 0][activatedKey-1] = 1; // La place dans le tableau des notes activées pour la colorer et ne pas la rejouer
}
else
{
channel.noteOff(keyNumber, midiVelocity);
keysPressed[white ? 1 : 0][activatedKey-1] = 0;
}
if (on && events[RECORDINGSTARTED])
{
if(numnote >= notePressed.length) // Arrête l'enregistrement si le nombre de note dépasse la longueur du tableau
events[RECORDINGSTOPPED] = true;
else
{
notePressed[numnote][0] = keyNumber; // Enregistre le code de la note
if (numnote != 0) notePressed[numnote][1] = millis() - notePressed[0][1]; // Enregistre la durée de la note
else notePressed[numnote][1] = millis();
numnote++;
}
}
return keyNumber;
}
void playNotes() // Joue les notes de notes[][], appelé lors du clic sur le bouton lecture et jusqu'à la fin du tableau
{
if (timer == 0) // Si le chronomètre n'est pas lancé
{
if (events[PLAYPRESSED]) // Et que la touche lecture est cliquée
{
timer = millis(); // Lancer le chronomètre
events[MUSICSTARTED] = true;
if(!events[MUSICPLAYED]) events[MUSICPLAYED] = true;
}
}
else if (numnote < notes.length) // Si la note suivante existe
{
if ( numnote == 0 || timer + notes[numnote-1][2]*(60000/bpm) < millis() ) // et que c'est la première note ou la durée de la note précédente est écoulée
{
if(numnote > 0) processNote(notes[numnote-1][0], notes[numnote-1][1]%2!=0, false, true);
int keyNumber = processNote(notes[numnote][0], notes[numnote][1]%2!=0, true, true);
/* Remplit un tableau temporaire comportant le timestamp de chaque note. */
tmpNotes[numnote][0] = keyNumber;
if (numnote != 0) tmpNotes[numnote][1] = millis()-tmpNotes[0][1];
else tmpNotes[0][1] = millis();
//channel.noteOn(notes[numnote][0], midiVelocity); // Jouer la note
numnote++; // Passer à la note suivante
timer = millis(); // Réinitialiser le chronomètre
}
}
else // Si la lecture est terminée
{
if ( numnote == 0 || timer + notes[numnote-1][2]*(60000/bpm) < millis() ) // et que c'est la première note ou la durée de la note précédente est écoulée
{
processNote(notes[numnote-1][0], notes[numnote-1][1]%2!=0, false, true);
tmpNotes[0][1] = 0; // Le timestamp de la première note est 0.
timer = 0;
numnote = 0;
events[MUSICFINISHED] = true;
}
}
}
|