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; } } }