/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package geneticmusic.genes;
import geneticmusic.domain.Note;
import java.io.Serializable;
import org.jgap.BaseGene;
import org.jgap.Configuration;
import org.jgap.Gene;
import org.jgap.InvalidConfigurationException;
import org.jgap.RandomGenerator;
import org.jgap.UnsupportedRepresentationException;
/**
* Each chorale gene represents a quarcher note in terms of rithm
* each gene represents a part set of notes for the current tempo in the measure
*
* the notes can be quarcher 4 or
* semiquarcher 8, so each gene can have 2 notes maximum
*
* //NOTE for simplicity reasons the notes are all quarchers for now
*
* @author Davide Nunes
*/
public class ChoraleGene extends BaseGene implements Gene, Serializable{
private Note soprano;
private Note alto;
private Note tenor;
private Note bass;
//constructor, creates a random note randomizer over all the parameters
public ChoraleGene(Configuration conf) throws InvalidConfigurationException{
this(conf,
NoteGenerator.getRandomNote(4, 5, 4, 4),
NoteGenerator.getRandomNote(3, 5, 4, 4),
NoteGenerator.getRandomNote(3, 4, 4, 4),
NoteGenerator.getRandomNote(2, 4, 4, 4));
}
/**
* Setup a new note withe the given values
* conf - Configuration - default configuration object
* pitch - Note - note pitch must be one from the enumerate Note
* octave - Integer - the octave in which the note is set mid = 0
* alt - Alteration - alterations on the note (SHARP or FLAT), can be
* null if you want to represent a natural note(without alterations)
* duration Integer - the duration of the note, starting at 1
*
* @throws InvalidConfigurationException
*/
public ChoraleGene(Configuration conf, Note soprano,
Note alto,
Note tenor,
Note bass ) throws InvalidConfigurationException{
super(conf);
this.soprano = soprano;
this.alto = alto;
this.tenor = tenor;
this.bass = bass;
}
@Override
protected Object getInternalValue() {
return new Note[] {soprano, alto, tenor, bass};
}
/**
* Provides an implementation-independent means for creating new Gene
* instances
*/
@Override
protected Gene newGeneInternal() {
try {
// Construct a NoteGene with the values from the currently created gene
// -------------------------------------------------------------
return new ChoraleGene(getConfiguration(),soprano,alto,tenor,bass);
} catch (InvalidConfigurationException ex) {
throw new IllegalStateException(ex.getMessage());
}
}
@Override
public void setAllele(Object o) {
Note[] notes = (Note []) o;
this.soprano = notes[0];
this.alto = notes[1];
this.tenor = notes[2];
this.bass = notes[3];
}
//for persistence in XML
@Override
public String getPersistentRepresentation() throws UnsupportedOperationException {
return "( "+soprano.toString()+" | "+
alto.toString()+" | "+
tenor.toString()+" | "+
bass.toString()+
") ";
}
@Override
public String toString(){
return getPersistentRepresentation();
}
//note parse from XML persistence
@Override
public void setValueFromPersistentRepresentation(String string) throws UnsupportedOperationException, UnsupportedRepresentationException {
//TODO implements this if needed
}
@Override
public void setToRandomValue(RandomGenerator rg) {
if(!(rg instanceof NoteGenerator))
throw new IllegalArgumentException("needs a Note generator in the configuration");
NoteGenerator generator = (NoteGenerator) rg;
int noteChoosen = generator.nextInt(4);
switch(noteChoosen){
case 0: this.soprano = generator.nextNote(4, 5, 4, 4);
break;
case 1: this.alto = generator.nextNote(3, 5, 4, 4);
break;
case 2: this.tenor = generator.nextNote(3, 4, 4, 4);
break;
case 3: this.bass = generator.nextNote(2, 4, 4, 4);
break;
}
}
@Override
public void applyMutation(int i, double d) {
setToRandomValue(new NoteGenerator());
}
@Override
public int compareTo(Object t) {
ChoraleGene other = (ChoraleGene) t;
Note[] otherNotes = (Note[]) other.getAllele();
return (int) soprano.distance(otherNotes[0]);
}
}