Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: envelope2.c
- Revision:
- 0:cb80470434eb
diff -r 000000000000 -r cb80470434eb envelope2.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/envelope2.c Tue Oct 28 12:19:42 2014 +0000
@@ -0,0 +1,181 @@
+/*
+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;
+ }
+ }
+}