/* Copyright (C) 2007 Julien Pauty
*
* This file is part of Nomad.
*
* Nomad 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 2 of the License, or
* (at your option) any later version.
*
* Nomad 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 Nomad; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.sf.nmedit.jtheme.clavia.nordmodular.graphics;
public class MultiEnvelope extends Envelope{
protected int sustainSeg = 2;
protected int curveType = 0;
protected MultiEnvelope(int nbPoints)
{
super(nbPoints);
setNbSegment(6);
// attack
setTime(0, 0);
setLevel(0, 0);
setTime(1, RANGE_MAX);
setLevel(1, 64);
setTime(2, RANGE_MAX);
setLevel(2, 63);
setTime(3,RANGE_MAX);
setLevel(3, RANGE_MAX);
setTime(4,RANGE_MAX);
setLevel(4, 0);
setTime(5,RANGE_MAX);
setLevel(5, 0);
setTime(6,RANGE_MAX);
setLevel(6, 0);
}
public MultiEnvelope()
{
this( 7);
}
/*
* This function update the curve type when the level of a point is changed
*/
private void update_curve(){
setModified(true);
for (int i = 1; i <= nbSegment; i++){
// we must iterate over ALL segments, so we use the getLevel method
// of the Enveloppe class and not the method of the multiEnvClass
if (curveType == 0) { //set all linear
setCurveType(i, LIN);
}
else {
if (super.getLevel(i) > super.getLevel(i-1)){
setCurveType(i, LOG);
} else {
if (curveType == 1)
setCurveType(i, EXP);
else if (curveType == 2)
setCurveType(i, LIN);
}
}
}
}
public void setLevel(int segment, int level){
//inverse level so that level = 0 corresponds to the top of the graph
level = 127 - level;
if(segment < sustainSeg) {
super.setLevel(segment, level);
}
else if (segment == sustainSeg)
{
super.setLevel(segment, level);
super.setLevel(segment+1, level);
} else {
super.setLevel(segment + 1, level);
}
update_curve();
}
public int getLevel(int segment){
if(segment <= sustainSeg)
return super.getLevel(segment);
else {
return super.getLevel(segment+1);
}
}
private int getPointIndex(int point){
if (point <= sustainSeg) return point;
else return point+1;
}
public void setTime(int point, int time){
int pointIndex = getPointIndex(point);
super.setTime(pointIndex, time);
//calculate the total length of all segments except the sustaint segment
int sum=0;
for(int i = 1; i < nbSegment; i ++) {
sum += getTime(i);
}
// update length of sustain segment
super.setTime(sustainSeg+1, nbSegment*RANGE_MAX-sum);
// since we changed several segemnt times, we update all the segments:
for(int i = 1; i <= nbSegment; i++) {
super.setTime(i, super.getTime(i));
}
//System.out.println(nbSegment + " " + super.getTime(sustainSeg+1) + " "+ sum + " "+(sum+super.getTime(sustainSeg+1)) );
}
public void refresh(){
for(int i = 1; i <= nbSegment; i++) {
super.setTime(i, super.getTime(i));
if(i != sustainSeg)
setLevel(i, getLevel(i));
}
setLevel(sustainSeg, getLevel(sustainSeg));
}
/* getTime never returns the time of the second point of the sustain
* segment (point sustainSeg+1). Indeed this point is not considered
* in the segement numbering. So iterating over segment 1 to 5 should
* not access to this point.
*
* When a segment following the sustain segment is modified, the time of the point
* sustainSeg+1 is set to fill the space see setTime
* */
public int getTime(int segment){
if(segment <= sustainSeg)
return super.getTime(segment);
else {
return super.getTime(segment+1);
}
}
public int getSustainSeg() {
// in the NM editor the -- value actually corresponds to the 5th segment
if (sustainSeg == 5)
return 0;
else return sustainSeg;
}
public void setSustainSeg(int sustainSeg) {
System.out.println(sustainSeg);
// in the NM editor the -- value actually corresponds to the 5th segment
if(sustainSeg == 0)
sustainSeg = 5;
int levels[] = new int[6];
int times[] = new int[6];
int sustainTime = super.getTime(this.sustainSeg+1);
//save the old times and levels
for(int i = 0 ; i <= 5; i++ ) {
levels[i] = getLevel(i);
times[i] = getTime(i);
}
// update them with respect to the new sustain segment
for(int i = 0 ; i <= nbSegment ; i++){
if(i < sustainSeg ){
super.setLevel(i,levels[i]);
super.setTime(i, times[i]);
} else if(i == sustainSeg) {
super.setLevel(i,levels[i]);
super.setLevel(i+1,levels[i]);
super.setTime(i, times[i]);
super.setTime(i+1, sustainTime);
i++;
} else{
super.setLevel(i,levels[i-1]);
super.setTime(i,times[i-1]);
}
}
update_curve();
this.sustainSeg = sustainSeg;
}
public int getCurve(){
return this.curveType;
}
public void setCurve(int curve){
this.curveType = curve;
switch (curve) {
case 0:
super.setLevel(0,64);
super.setLevel(nbSegment,64);
break;
case 1:
case 2:
super.setLevel(0,127);
super.setLevel(nbSegment,127);
break;
}
update_curve();
}
}