/* 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; import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; public class FilterE extends Curve { int type =0; // float cutOff =0.5f; float resAmplitude = 0.45f; float resonance = 0; int slope = 1; // 0 = 12 db, 1 = 24 db int gainControl = 1; public FilterE(){ super(7); points[0].setPoint_type(PathIterator.SEG_MOVETO); points[0].setLocation(-0.1f,1.1f); points[1].setLocation(-0.1f,resAmplitude); points[2].setLocation(0.3f,resAmplitude); points[3].setPoint_type(PathIterator.SEG_CUBICTO); points[3].setCurve_type(EXP); points[4].setPoint_type(PathIterator.SEG_CUBICTO); points[4].setCurve_type(LOG); points[5].setLocation(-0.1f,1.1f); points[6].setLocation(-0.1f,1.1f); // this point is used by the band reject only update(); } public PathIterator getPathIterator( final AffineTransform at ) { return new FilterIterator(at,points,bounds); } private void update() { setModified(true); switch(type){ //high pass case 2: float gainOffset = gainControl == 0 ? 1f:0.5f; points[1].setLocation(cutOff-0.5f+slope*0.25f, 1.1f+ resAmplitude*.5f*resonance*gainControl); points[2].setLocation(cutOff,resAmplitude - resonance*resAmplitude*gainOffset); points[2].setPoint_type(PathIterator.SEG_CUBICTO); points[2].setCurve_type(EXP); float angleSlope = -70+40*slope; float angle = 180f - 80f* resonance; points[2].setBezier(points[1].getX(),points[1].getY(),0.05f,0.2f+0.1f*resonance,angleSlope,angle); points[3].setLocation(cutOff+0.1f+slope*.15f,resAmplitude + resAmplitude*.5f*resonance*gainControl); points[3].setPoint_type(PathIterator.SEG_CUBICTO); points[3].setCurve_type(EXP); angle = 80f * resonance; points[3].setBezier(points[2].getX(),points[2].getY(),0.05f*resonance,0.05f+0.05f*resonance,angle,180f); points[4].setLocation(1.5f,resAmplitude + resAmplitude*.5f*resonance*gainControl); points[4].setPoint_type(PathIterator.SEG_LINETO); points[4].setCurve_type(LIN); points[5].setLocation(1.1f,1.1f); points[6].setLocation(-0.1f,1.1f); break; //low pass case 0: gainOffset = gainControl == 0 ? 1f:0.5f; points[1].setLocation(-0.3f,resAmplitude + resAmplitude*.5f*resonance*gainControl); points[2].setLocation(-0.1f+cutOff-slope*.15f,resAmplitude + resAmplitude*.5f*resonance*gainControl); points[2].setPoint_type(PathIterator.SEG_LINETO); points[2].setCurve_type(LIN); points[3].setLocation(cutOff,resAmplitude - resonance*resAmplitude*gainOffset); points[3].setPoint_type(PathIterator.SEG_CUBICTO); points[3].setCurve_type(EXP); angle = 180f - 80f*resonance; points[3].setBezier(points[2].getX(),points[2].getY(),0.05f+0.05f*resonance,0.05f*resonance,0f,angle); points[4].setLocation(0.5f+cutOff-slope*0.25f, 1.1f + resAmplitude*.5f*resonance*gainControl); points[4].setPoint_type(PathIterator.SEG_CUBICTO); points[4].setCurve_type(LOG); angle = (85f-15f*slope)*resonance; angleSlope = -150+40*slope; points[4].setBezier(points[3].getX(),points[3].getY(),0.2f+0.1f*resonance,0.05f,angle,angleSlope); points[5].setLocation(1.1f,1.1f); points[6].setLocation(-0.1f,1.1f); break; //band pass case 1: gainOffset = gainControl == 0 ? 1f:0.5f; //compute left end of the curve float leftEnd, rightEnd; if(slope == 0) { leftEnd = -0.65f+cutOff+0.12f*resonance; rightEnd = 0.65f+cutOff-0.12f*resonance; } else { leftEnd = -0.45f+ cutOff+0.06f*resonance; rightEnd = .45f+ cutOff-0.06f*resonance; } points[1].setLocation(-0.1f,1.1f+ resAmplitude*.5f*resonance*gainControl); points[2].setLocation(leftEnd,1.1f+ resAmplitude*.5f*resonance*gainControl); points[2].setPoint_type(PathIterator.SEG_LINETO); points[2].setCurve_type(LIN); points[3].setLocation(cutOff,resAmplitude - resonance*resAmplitude*gainOffset); points[3].setPoint_type(PathIterator.SEG_CUBICTO); points[3].setCurve_type(EXP); float lenSegOrig = 0.25f; float lenSegEnd = slope == 1 ? 0.25f : 0.25f+0.15f*resonance; angle = -50f - 40f*resonance - 20*slope; float angle2 = 180f - 80f*resonance; points[3].setBezier(points[2].getX(),points[2].getY(),lenSegOrig,lenSegEnd,angle,angle2); // curve is symetric w.r.t. cutoff = 0.5. points[4].setLocation(rightEnd, 1.1f+ resAmplitude*.5f*resonance*gainControl); points[4].setPoint_type(PathIterator.SEG_CUBICTO); points[4].setCurve_type(EXP); points[4].setBezier(points[3].getX(),points[3].getY(),lenSegEnd,lenSegOrig,180 - angle2, 180 - angle); points[5].setLocation(1.1f,1.1f); points[6].setLocation(-0.1f,1.1f); break; // band reject case 3: gainOffset = gainControl == 0 ? 0.35f:0f; points[1].setLocation(-0.5f,resAmplitude + resAmplitude*gainOffset*resonance); points[2].setLocation(-0.45f+(0.15f-0.1f*slope)*resonance+cutOff-slope*0.05f,resAmplitude + resAmplitude*gainOffset*resonance); points[2].setPoint_type(PathIterator.SEG_LINETO); points[2].setCurve_type(LIN); //adapting the beziez parameter with respect to the slop lenSegOrig = 0.2f; float res; //slope is 12db if(slope == 0){ lenSegOrig = 0.3f; // length of the orinal control segment lenSegEnd = 0.2f; // length of the ending control segment res = 1 ;//+ resAmplitude/2*(1- resonance); // 24db: make to curve steeper => reduce length of segments } else{ lenSegOrig = 0.2f; lenSegEnd = 0.4f; res = 1+ resAmplitude*.8f*(1- resonance); } points[3].setLocation(cutOff,res); points[3].setPoint_type(PathIterator.SEG_CUBICTO); points[3].setCurve_type(EXP); points[3].setBezier(points[2].getX(),points[2].getY(),lenSegOrig,lenSegEnd,0,-90); points[4].setLocation(0.45f-(0.15f-0.1f*slope)*resonance+cutOff+slope*0.05f, resAmplitude + resAmplitude*gainOffset*resonance); points[4].setPoint_type(PathIterator.SEG_CUBICTO); points[4].setCurve_type(EXP); points[4].setBezier(points[3].getX(),points[3].getY(),lenSegEnd,lenSegOrig,-90,180); points[5].setLocation(1.1f,resAmplitude + resAmplitude*gainOffset*resonance); points[6].setLocation(1.1f,1.1f); break; } } public float getResonance() { return resonance; } public void setResonance(float resonance) { this.resonance = resonance; update(); } public float getCutOff() { return cutOff/.8f-.1f; } public void setCutOff(float cutOff) { //cutoff comprised between .1 and .9 this.cutOff = cutOff*.8f+.1f; update(); } public int getType() { return type; } public void setType(int type) { this.type = type; update(); } public int getSlope() { return slope; } public void setSlope(int slope) { this.slope = slope; update(); } public int getGainControl() { return gainControl; } public void setGainControl(int gainControl) { this.gainControl = gainControl; update(); } }