268 lines
6.7 KiB
Java
268 lines
6.7 KiB
Java
/*
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
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<Float> freqID;
|
|
|
|
private NoteGamme(){
|
|
this.freqID = new ArrayList<Float>();
|
|
|
|
}
|
|
|
|
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<Number> getIndex(float freq) {
|
|
return getStatIndex(freq);
|
|
}
|
|
|
|
public static ArrayList<Number> getStatIndex(float freq){
|
|
ArrayList<Number> 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<Number> 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<String> toStringList(){
|
|
ArrayList<String> r = new ArrayList<>(gammeSize());
|
|
for (int i = 0; i < gammeSize(); i++)
|
|
r.add(String.valueOf(getNoteName(i)));
|
|
|
|
return r;
|
|
}
|
|
}
|