This is a part of the Kinetiszer project.
envelope2.c
- Committer:
- Clemo
- Date:
- 2014-10-28
- Revision:
- 1:8ae4ab73ca6a
- Parent:
- 0:cb80470434eb
File content as of revision 1:8ae4ab73ca6a:
/* Copyright 2013 Paul Soulsby www.soulsbysynths.com This file is part of Atmegatron. Atmegatron 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. Atmegatron 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 Atmegatron. If not, see <http://www.gnu.org/licenses/>. */ //****** BIPOLAR ENVELOPE - for filter and pitch*********** #include "atmegatron.h" //lets and gets int fenv_A = 0; //attack (in ticks) int fenv_DR = 400; //decay AND release (in ticks) (only reason for this is because there's not enough functions on function dial for both) signed char fenv_S = 0; //sustain (-127 - 127) signed char fenv_level = 0; //the current output level of the env. between -127 and 127 boolean fenv_invert = false; //envelope invert mode //local filt env vars unsigned long fenv_curtick; //current tick through env shape unsigned long fenv_starttick; //tick that env started at byte fenv_curstate = 0; //0 = off, 1 = triggering, 2 = holding, 3 = releasing ; boolean fenv_changed = true; //used to only calc Env when it's been triggered signed char fenv_Rstart = 0; //incase key up before decay finishes //lets and gets //set attack (in ticks) void Fenv_Let_A(int newA) { if (newA!=fenv_A) { fenv_A = newA; fenv_changed = true; } } int Fenv_Get_A(void) { return fenv_A; } //set decay and release (in ticks) void Fenv_Let_DR(int newDR) { if (newDR!=fenv_DR) { fenv_DR = newDR; fenv_changed = true; } } int Fenv_Get_DR(void) { return fenv_DR; } //set sustain (0-127) -127 - 0 is obtained by turning on invert mode void Fenv_Let_S(signed char newS) { if (newS!=fenv_S) { fenv_S = newS; fenv_changed = true; } } signed char Fenv_Get_S(void) { return fenv_S; } //set invert mode void Fenv_Let_Invert(boolean newinv) { if (newinv!=fenv_invert) { fenv_invert = newinv; fenv_changed = true; } } boolean Fenv_Get_Invert(void) { return fenv_invert; } //get current level of env (-127 - 127) signed char Fenv_Get_Level(void) { //invert output value if invert mode is on if (fenv_invert==true) { return -fenv_level; } else { return fenv_level; } } //meat //trigger the (start of) envelope void FEnv_Trigger(void) { fenv_curtick = 0; fenv_starttick = master_tick; fenv_curstate = 1; fenv_changed = true; } //trigger release stage of envelope void FEnv_Release(void) { fenv_curtick = 0; fenv_starttick = master_tick; fenv_Rstart = fenv_level; fenv_curstate = 3; fenv_changed = true; } //calculate env output level void FEnv_CalcVal(void) { if (fenv_changed==true){ //is envelope actually doing something? switch (fenv_curstate){ case 0: //idle fenv_level = 0; fenv_changed = false; break; case 1: fenv_curtick = master_tick - fenv_starttick; //triggering if (fenv_curtick>=fenv_A+fenv_DR){ //update tick fenv_level = fenv_S; //if attack + decay ticks passed, then onto sustain fenv_curstate = 2; } else if (fenv_curtick>=fenv_A){ //if attack ticks passed, then onto decay fenv_level = map(fenv_curtick,fenv_A,fenv_A+fenv_DR,127,fenv_S); } else{ //otherwise must be doing attack fenv_level = map(fenv_curtick,0,fenv_A,0,127); } break; case 2: //holding fenv_level = fenv_S; //make sure level = sustain level fenv_changed = false; //only need to do this once break; case 3: //releasing fenv_curtick = master_tick - fenv_starttick; if (fenv_curtick>=fenv_DR){ //if release ticks passed, then go back to idle fenv_level = 0; fenv_curstate = 0; } else{ //otherwise must be releasing fenv_level = map(fenv_curtick,0,fenv_DR,fenv_Rstart,0); } break; } } }