/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package geneticmusic.choraleRules;
import geneticmusic.domain.Alteration;
import geneticmusic.domain.Note;
import geneticmusic.domain.Pitch;
import geneticmusic.fitness.AbstractCompositionRule;
import org.jgap.Gene;
import org.jgap.IChromosome;
/**
* Vertical Equilibrium Rule
*
* each voice has 1.5 octaves of range aproximatly
*
*
* @author Davide Nunes
*/
public class VEVoiceExtension extends AbstractCompositionRule {
//create reference notes
private static final Note MIN_SOPRANO = new Note(Pitch.C, 4, Alteration.N, 4);
private static final Note MAX_SOPRANO = new Note(Pitch.G, 5, Alteration.N, 4);
private static final Note MIN_ALTO = new Note(Pitch.G, 3, Alteration.N, 4);
private static final Note MAX_ALTO = new Note(Pitch.C, 5, Alteration.N, 4);
private static final Note MIN_TENOR = new Note(Pitch.A, 3, Alteration.N, 4);
private static final Note MAX_TENOR = new Note(Pitch.G, 4, Alteration.N, 4);
private static final Note MIN_BASS = new Note(Pitch.D, 2, Alteration.N, 4);
private static final Note MAX_BASS = MIN_SOPRANO;
public VEVoiceExtension(double weight) {
super(weight);
}
@Override
protected double evaluation(IChromosome ic) {
double result = 0.0;
//for each note within range, the note gets a score
Gene[] genes = ic.getGenes();
double totalChords = genes.length;
for (int i = 0; i < genes.length; i++) {
Note[] currentNotes = (Note[]) genes[i].getAllele(); //get the current chord
if (withinRange(0, currentNotes[0])){
result += 1 / (totalChords * 4.0);
}
if (withinRange(0, currentNotes[0])) {
result += 1 / (totalChords * 4.0);
}
if (withinRange(0, currentNotes[0])) {
result += 1 / (totalChords * 4.0);
}
if (withinRange(0, currentNotes[0])) {
result += 1 / (totalChords * 4.0);
}
}
return result;
}
private static boolean withinRange(int position, Note note) {
boolean result = false;
switch (position) {
case 0:
result = (note.distance(MIN_SOPRANO) <= 0 && //soprano witin range?
note.distance(MAX_SOPRANO) >= 0);
break;
case 1:
result = (note.distance(MIN_ALTO) <= 0 && //soprano witin range?
note.distance(MAX_ALTO) >= 0);
break;
case 2:
result = (note.distance(MIN_TENOR) <= 0 && //soprano witin range?
note.distance(MAX_TENOR) >= 0);
break;
case 3:
result = (note.distance(MIN_BASS) <= 0 && //soprano witin range?
note.distance(MAX_BASS) >= 0);
break;
}
return result;
}
@Override
public String getName() {
return "Voice Extension Rule";
}
}