import javax.sound.midi.MidiSystem; import javax.sound.midi.Synthesizer; import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiUnavailableException; void calcScore() { score = 0; float tmpScore = 0; for (int i=0; i<=numnote; i++) // Pour chaque note cliquée { for (int j=0; j < tmpNotes.length; j++) // La comparer à chaque note de la partition { if (notePressed[i][0] != tmpNotes[j][0]) // Si la note est différente continue; // Passer à la note suivante if(i == 0 && j == 0) // Si c'est la toute première note tmpScore = 1; // Donner d'office un score de 1000 if(i == 0 || j == 0) // Si on est à la première note d'un des deux tableaux continue; // Passer à la note suivante float deltaTime = sqrt(abs((notePressed[i][1]-notePressed[i-1][1]) - (tmpNotes[j][1]-tmpNotes[j-1][1]))); // Calcul de la différence de durée de la note de la partition et de la note cliquée passé à la racine carrée pour donner un résultat plus adapté if (deltaTime == 0) // Si les notes ont exactement la même durée tmpScore = 1; // Donner un score de 1000 else if (1/((float)deltaTime) > tmpScore) // Si le score est le plus élevé pour une note cliquée comparée à plusieurs note de la partition tmpScore = 1/((float)deltaTime); // Enregistrer ce score (l'inverse, puisque que plus la différence de temps est grande, moins le score est important) } score += tmpScore*1000; tmpScore = 0; } } void setup() { PartitionLune = loadImage(imagePartition); // Charge l'image de la partition initSynth(); defineKeys(); size(windowSize[0], windowSize[1]); background(255); PFont SuperPoliceDuPoneyQuiTousse = loadFont(font); // Importation de la police. textFont(SuperPoliceDuPoneyQuiTousse, tailleTexte); // Appel de la police et de sa taille. drawKeyboard(); drawDisplay(); image(PartitionLune, imageCoordinates[0], imageCoordinates[1], imageSize[0], imageSize[1]); } void draw() { if (events[MOUSEPRESSED] || events[KEYPRESSED]) // Si un clic a eu lieu, mettre à jour { playNotes(); drawKeyboard(); drawDisplay(); } else if (events[MUSICSTARTED]) // Ou si la musique est lancée { if (events[MUSICFINISHED]) { events[MUSICSTARTED] = false; events[MUSICFINISHED] = false; drawDisplay(); } else { playNotes(); drawKeyboard(); } } if (events[RECORDINGSTARTED]) { if (events[RECORDINGSTOPPED]) { events[RECORDINGSTARTED] = false; notePressed[0][1] = 0; // La première note commence à 0ms calcScore(); numnote = 0; drawDisplay(); } } events[MOUSEPRESSED] = false; events[KEYPRESSED] = false; events[PLAYPRESSED] = false; } int whiteKeys() // Détection du clic sur une touche blanche { int activatedKey = 0; for (int j=0; j= xPos*windowSize[0]) && (mouseX <= (xPos+(keyWidth[1]/(numOctaves)))*windowSize[0]) && (mouseY <= (keyboardYCoordinate+keyHeight[1])*windowSize[1])) activatedKey = (j*7)+(i+1); // Numéro de la touche cliquée } } return activatedKey; } int blackKeys() // Détection du clic sur une touche noire { int activatedKey = 0; for (int j=0; j= xPos*windowSize[0]) && (mouseX <= (xPos+(keyWidth[0]/(numOctaves)))*windowSize[0]) && (mouseY <= (keyboardYCoordinate+keyHeight[0])*windowSize[1])) activatedKey = (j*5)+(i+1); // Numéro de la touche cliquée } } return activatedKey; } void mousePressed() { events[MOUSEPRESSED] = true; if (mouseY >= keyboardYCoordinate*windowSize[1]) // Si le clic est effectué au niveau du clavier { int activatedKey = blackKeys(); // Numéro de la touche si touche noire cliquée, sinon 0 if (activatedKey == 0) // Si ce n'est pas une touche noire { activatedKey = whiteKeys(); // Numéro de la touche si touche blanche cliquée, sinon 0 if (activatedKey == 0) // Aucune touche cliquée, ne devrait pas survenir ici return; processNote(activatedKey, true, true, false); } else processNote(activatedKey, false, true, false); } else { if (!events[RECORDINGSTARTED] && sqrt(pow((playButtonCoordinates[0]*windowSize[0] - (float)mouseX), 2) + pow((playButtonCoordinates[1]*windowSize[1] - (float)mouseY), 2)) <= buttonRadius*windowSize[0]) // Si la touche lecture est cliquée (distance entre le centre du cercle et l'endroit cliqué inférieur au rayon) events[PLAYPRESSED] = true; if (!events[MUSICSTARTED] && sqrt(pow((recordButtonCoordinates[0]*windowSize[0] - (float)mouseX), 2) + pow((recordButtonCoordinates[1]*windowSize[1] - (float)mouseY), 2)) <= buttonRadius*windowSize[0]) // Si la touche enregistrer est cliquée (distance entre le centre du cercle et l'endroit cliqué inférieur au rayon) { if (events[RECORDINGSTARTED]) events[RECORDINGSTOPPED] = true; else if (events[RECORDINGSTOPPED]) { events[RECORDINGSTARTED] = true; events[RECORDINGSTOPPED] = false; score = -1; } else events[RECORDINGSTARTED] = true; } } } void mouseReleased() // Pareil que mousePressed() mais lorsque la touche est relachée { events[MOUSEPRESSED] = true; if (mouseY >= keyboardYCoordinate*windowSize[1]) { int activatedKey = blackKeys(); if (activatedKey == 0) { activatedKey = whiteKeys(); if (activatedKey == 0) return; processNote(activatedKey, true, false, false); } else processNote(activatedKey, false, false, false); } } void keyPressed() { // Pareil que mousePressed() mais pour le clavier events[KEYPRESSED] = true; if (keyCode < 523) // Pas de touche associée à un code supérieur à 523 { int activatedKey = touchesNoires[keyCode]; if (activatedKey == 0) { activatedKey = touchesBlanches[keyCode]; if (activatedKey == 0) return; processNote(activatedKey, true, true, false); } else processNote(activatedKey, false, true, false); } } void keyReleased() // Pareil que keyPressed() mais lorsque la touche est relachée { events[KEYPRESSED] = true; if (keyCode < 523) { int activatedKey = touchesNoires[keyCode]; if (activatedKey == 0) { activatedKey = touchesBlanches[keyCode]; if (activatedKey == 0) return; processNote(activatedKey, true, false, false); } else processNote(activatedKey, false, false, false); } }