void initSynth() { // MIDI.loadPlugin({instrument: "acoustic_grand_piano"}); } int processNote(int activatedKey, boolean white, boolean on, boolean autoplay) // Détection de la note cliquée { 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) return -1; if (white) { keyNumber = (activatedKey-1)%7; octave = (activatedKey-1-keyNumber)/7; 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; keyNumber = octave*12+baseNote+keyNumber; if(on) { MIDI.noteOn(0, keyNumber, midiVelocity, 0); keysPressed[white ? 1 : 0][activatedKey-1] = 1; } else { MIDI.noteOff(0, keyNumber, 0); keysPressed[white ? 1 : 0][activatedKey-1] = 0; } if (on && events[RECORDINGSTARTED]) { if(numnote >= notePressed.length) events[RECORDINGSTOPPED] = true; else { notePressed[numnote][0] = keyNumber; if (numnote != 0) notePressed[numnote][1] = millis() - notePressed[0][1]; 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; } } }