/* 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 conteneurs; import java.util.ArrayList; /** * Created by Gabriel on 16/04/2014. * Gamme qui ne garde que les fréquences qui correspondent à des notes utilisées dans les gammes classiques tempérées */ public class NoteGamme extends Gamme { static final float MAX_FREQ = 2100; static final float MIN_FREQ = 18.354002f; private ArrayList freqID; private NoteGamme(){ this.freqID = new ArrayList(); } private static NoteGamme noteGamme = new NoteGamme(); public static NoteGamme gamme(){ return noteGamme; } /** public void computeFreqNote(){ /**for(float freq = 440; freq < this.MAX_FREQ; freq = freq*(float)Math.pow(2, 1/12.0) ){ this.freqID.addNote(freq); System.out.println(freqID.get(freqID.size()-1)); } for(float freq = 440; freq > MIN_FREQ; freq = freq/(float)Math.pow(2,1/12.0)){ this.freqID.addNote(0,freq); System.out.println(freqID.get(0)); } System.out.println(freqID.size()); for(float f = MIN_FREQ; f < MAX_FREQ; f = f*(float)Math.pow(2, 1/12.0)){ freqID.addNote(f); System.out.println(f); } } */ @Override public ArrayList getIndex(float freq) { return getStatIndex(freq); } public static ArrayList getStatIndex(float freq){ ArrayList res = new ArrayList<>(); // Gère le cas où on demande une fréquence qui n'est pas comprise entre le minimum et le maximum des fréquences de cette gamme. if(freq < MIN_FREQ ||freq > MAX_FREQ){ res.add(-1); return res; } //Cherche l'indice du dessus float f = MIN_FREQ; int index = 0; while(f <= freq){ f = f * (float)Math.pow(2, 1/12.0); index++; } //Calcul du coefficient d'interpolation: 0 si freq = fréquence inférieure, 1 si freq = freq supérieure float coeff = (freq - (f/(float)Math.pow(2,1/12.0)))/(f - (f/(float)Math.pow(2,1/12.0))); res.add(index-1); res.add(index); res.add(coeff); return res; } /** Renvoie l'indice de la note a partir de son nom * @param name son nom en tant que chaine de caractere * @return l'indice de la note */ public static int getIndex(String name){ int id = ('0'+name.charAt(name.length()-1))*12; if(name.startsWith("RE#")) id+=1; else if(name.startsWith("MI")) id+=2; else if(name.startsWith("FA")) id+=3; else if(name.startsWith("FA#")) id+=4; else if(name.startsWith("SOL")) id+=5; else if(name.startsWith("SOL#")) id+=6; else if(name.startsWith("LA")) id+=7; else if(name.startsWith("LA#")) id+=8; else if(name.startsWith("SI")) id+=9; else if(name.startsWith("DO")) id+=10; else if(name.startsWith("DO#")) id+=11; return id; } @Override public float getFreq(int index) { return getStatFreq(index); } public static float getStatFreq(int index){ return MIN_FREQ * (float)Math.pow(2,index/12.0); } @Override public int gammeSize() { return gammeStatSize(); } public static int gammeStatSize(){ int size = 0; for(float f = MIN_FREQ; f < MAX_FREQ; f = f*(float)Math.pow(2,1/12.0)){ size ++; } return size; } /** Renvoie le nom d'une note en fonction de la fréquence * Si la fréquence n'est pas proche d'une note (coeff < 5%), l'indice renvoyé est -1 * @param freq la fréquence dont on cherche la note qui correspond * @return le nom de la note */ public static String getNoteName(float freq){ ArrayList res = getStatIndex(freq); int index = -1; float coeff = (float)res.get(2); if(coeff < 0.05){ index = (int)res.get(0); } else if (coeff > 0.95){ index = (int)res.get(1); } if(index != -1) return getNoteName(index); return null; } /** Renvoie la note en fonction de l'indice de la note, (indice 0 : RE) */ public static String getNoteName(int index){ String noteName = ""; if (index >= gammeStatSize() || index <0) return null; int octave = (index/12); index = index%12; switch(index){ case 0: noteName = "RE"; break; case 1: noteName = "RE#"; break; case 2: noteName = "MI"; break; case 3: noteName = "FA"; break; case 4: noteName = "FA#"; break; case 5: noteName = "SOL"; break; case 6: noteName = "SOL#"; break; case 7: noteName = "LA"; break; case 8: noteName = "LA#"; break; case 9: noteName = "SI"; break; case 10: noteName = "DO"; octave++; break; case 11: noteName = "DO#"; octave++; break; } noteName = noteName + octave; return noteName; } /** Renvoie le nom de la note en version anglaise */ public static String getEnglishNoteName(int index){ String noteName = ""; if (index >= gammeStatSize() || index <0) return null; int octave = (index/12); index = index%12; switch(index){ case 0: noteName = "d"; break; case 1: noteName = "dis"; break; case 2: noteName = "e"; break; case 3: noteName = "f"; break; case 4: noteName = "fis"; break; case 5: noteName = "g"; break; case 6: noteName = "gis"; break; case 7: noteName = "a"; break; case 8: noteName = "ais"; break; case 9: noteName = "b"; break; case 10: noteName = "c"; octave++; break; case 11: noteName = "cis"; octave++; break; } for (int i = 3; i < octave; i++) noteName+="\'"; return noteName; } /** Renvoie la frequence maximale de la NoteGamme */ public static float getMaxFreq() { return MAX_FREQ; } /** Renvoie la frequence minimale de la NoteGamme */ public static float getMinFreq() { return MIN_FREQ; } @Override public ArrayList toStringList(){ ArrayList r = new ArrayList<>(gammeSize()); for (int i = 0; i < gammeSize(); i++) r.add(String.valueOf(getNoteName(i))); return r; } }