/* Reversound is used to get the music sheet of a piece from a music file. Copyright (C) 2014 Gabriel AUGENDRE Copyright (C) 2014 Gabriel DIENY Copyright (C) 2014 Arthur GAUCHER Copyright (C) 2014 Gabriel LEPETIT-AIMON This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package processing; import generictools.Instant; import processing.buffer.NoteBuffer; import javax.swing.*; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; /**Created by gaby on 03/06/14. * Script qui sert à l'exportation vers Lilypond. Regroupe tous les algo de post-traitement nécéssaires à cette exportation. */ public class PostProcessScript implements Runnable{ private NoteBuffer buffer; private float tolerance = 0.08f; private float progress = 0; Runnable callBack; Thread thread = null; private static PostProcessScript script = null; private PostProcessScript(NoteBuffer buffer, Runnable callBack){ this.buffer = buffer; this.callBack = callBack; } /** * Lance le script * @param buffer * @param callBack */ public static void launchScript(NoteBuffer buffer, Runnable callBack){ interrupt(); PostProcessScript script = new PostProcessScript(buffer, callBack); script.thread = new Thread(script); script.thread.start(); script = null; } public static void interrupt(){ if(script!=null && script.thread!=null && script.thread.isAlive()) script.thread.interrupt(); script = null; } @Override public void run() { unifyTempo(); // System.out.println("NOTES:"); // // for (int i = 0; i < buffer.getNotesNbr(); i++) { // System.out.println("\t" + buffer.getNote(i).getNoteName() + " (" + buffer.getNote(i).getUnifiedDuration() + ")"); // } JFileChooser jfc = new JFileChooser(); jfc.setDialogTitle("Choix du dossier de sortie"); jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int ret = jfc.showOpenDialog(null); if(ret != JFileChooser.APPROVE_OPTION) return; File file = new File(jfc.getSelectedFile().getPath()+"/exportLilypond.txt"); System.out.println(jfc.getSelectedFile().getPath()+"/exportLilypond.txt"); try { if(!file.exists()) file.createNewFile(); FileWriter fileWriter = new FileWriter(file); fileWriter.write(toLilyPond()); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); return; } if(callBack!=null) try { callBack.run(); } catch (Exception e) { e.printStackTrace(); } } private String toLilyPond(){ String r = "<< {"; for (int i = 0; i < buffer.getNotesNbr(); i++) { r+=buffer.getNote(i).getEnglishNoteName() + buffer.getNote(i).getUnifiedDuration() + " "; } r+="} >>"; return r; } /** Cherche le tempo du morceau en se basant sur les écarts entre les notes. * A partir de la, il donne a chaque note une duree (ronde, blanche noire, croche, etc) et permet de trouver le rythme */ private void unifyTempo(){ ArrayList listEcarts = calculeEcarts(bufferSortOut(buffer)); ArrayList EcartsReference = new ArrayList<>(); ArrayList nEcartParType = new ArrayList<>(); //Cr�ation des cat�gories de r�f�rence, tri�es par ordre croissant EcartsReference.add(listEcarts.get(0)); nEcartParType.add(1); for (int i = 1; i < listEcarts.size(); i++) { float currentEcart = listEcarts.get(i); boolean newCategoryNeeded = true; for (int j = 0; j < EcartsReference.size(); j++) { //Si on est dans la marge de tolerance d�finie en param�tre, on red�finit la r�f�rence gr�ce � une moyenne pond�r�e if(currentEcart>((1-tolerance)*EcartsReference.get(j)) && currentEcart<((1+tolerance)*EcartsReference.get(j))){ EcartsReference.set(j, ( (nEcartParType.get(j)*EcartsReference.get(j))+ currentEcart) / (nEcartParType.get(j)+1) ); nEcartParType.set(j, nEcartParType.get(j)+1); newCategoryNeeded = false; } } //Sinon cr�ation d'une nouvelle cat�gorie si aucune existante ne convient if(newCategoryNeeded){ int j = 0; while(j à une ronde ArrayList UnifiedEcarts = new ArrayList<>(EcartsReference.size()); int indexEcartMostUsed = 0; int maxUsed = 0; for (int i = 0; i < nEcartParType.size(); i++) { if( nEcartParType.get(i)> maxUsed){ maxUsed = nEcartParType.get(i); indexEcartMostUsed = i; } } for (int i = 0; i < nEcartParType.size(); i++) { UnifiedEcarts.add("0"); } //Cas où on se retrouve avec le max plus grand qu'une ronde while(indexEcartMostUsed < EcartsReference.size()-1 && EcartsReference.get(indexEcartMostUsed)*(4+tolerance)>EcartsReference.get(EcartsReference.size()-1)){ indexEcartMostUsed++; } //Donne à chaque note une durée unified for (int i = 0; i < buffer.getNotesNbr(); i++) { double duration = i!=buffer.getNotesNbr()-1?buffer.getNote(i+1).getStart().substract(buffer.getNote(i).getStart()):buffer.getNote(i).getDuration(); double fac = Math.log(EcartsReference.get(indexEcartMostUsed)*4/ duration)/Math.log(2); buffer.getNote(i).setUnifiedDuration(String.valueOf(Math.round(Math.pow(2, (int) fac))) + (fac % 1 < 0.5 ? "." : "")); } System.out.println("ECARTS:"); for (int i = 0; i < UnifiedEcarts.size(); i++) { System.out.println("\t" + EcartsReference.get(i) + " (" + UnifiedEcarts.get(i) + ")"); } } /** Trie les instants de d�part des notes dans l'ordre croissant * @param buffer le buffer dont les instants sont � trier */ private ArrayList bufferSortOut(NoteBuffer buffer){ ArrayList tmp = new ArrayList<>(); ArrayList res = new ArrayList<>(); // On r�cup�re tous les instans de d�part for (int i = 0; i < buffer.getNotesNbr(); i++) { tmp.add(buffer.getNote(i).getStart()); } //Tri par ordre croissant res.add(tmp.get(0)); for (int i = 1; i < tmp.size(); i++) { int j = 0; while(j calculeEcarts(ArrayList instantList){ ArrayList res = new ArrayList<>(); for (int i = 1; i < instantList.size(); i++) { res.add(instantList.get(i).substract(instantList.get(i - 1))); } return res; } private boolean updateProgress(float progress){ try { Thread.sleep(0); } catch (InterruptedException e) { return true; } this.progress = progress; return false; } public static float getProgress(){ if(script == null) return -1; return script.progress; } }