This is a part of the Kinetiszer project.
envelope.c@1:8ae4ab73ca6a, 2014-10-28 (annotated)
- Committer:
- Clemo
- Date:
- Tue Oct 28 20:09:12 2014 +0000
- Revision:
- 1:8ae4ab73ca6a
- Parent:
- 0:cb80470434eb
First publication (untested)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Clemo | 0:cb80470434eb | 1 | /* |
Clemo | 0:cb80470434eb | 2 | Copyright 2013 Paul Soulsby www.soulsbysynths.com |
Clemo | 0:cb80470434eb | 3 | This file is part of Atmegatron. |
Clemo | 0:cb80470434eb | 4 | |
Clemo | 0:cb80470434eb | 5 | Atmegatron is free software: you can redistribute it and/or modify |
Clemo | 0:cb80470434eb | 6 | it under the terms of the GNU General Public License as published by |
Clemo | 0:cb80470434eb | 7 | the Free Software Foundation, either version 3 of the License, or |
Clemo | 0:cb80470434eb | 8 | (at your option) any later version. |
Clemo | 0:cb80470434eb | 9 | |
Clemo | 0:cb80470434eb | 10 | Atmegatron is distributed in the hope that it will be useful, |
Clemo | 0:cb80470434eb | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
Clemo | 0:cb80470434eb | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
Clemo | 0:cb80470434eb | 13 | GNU General Public License for more details. |
Clemo | 0:cb80470434eb | 14 | |
Clemo | 0:cb80470434eb | 15 | You should have received a copy of the GNU General Public License |
Clemo | 0:cb80470434eb | 16 | along with Atmegatron. If not, see <http://www.gnu.org/licenses/>. |
Clemo | 0:cb80470434eb | 17 | */ |
Clemo | 0:cb80470434eb | 18 | |
Clemo | 0:cb80470434eb | 19 | //******UNIPOLAR ENVELOPE - for amplitude*********** |
Clemo | 0:cb80470434eb | 20 | |
Clemo | 0:cb80470434eb | 21 | #include "atmegatron.h" |
Clemo | 0:cb80470434eb | 22 | |
Clemo | 0:cb80470434eb | 23 | //lets and gets |
Clemo | 0:cb80470434eb | 24 | int aenv_A = 0; //attack (in ticks) |
Clemo | 0:cb80470434eb | 25 | int aenv_D = 0; //decay (in ticks) |
Clemo | 0:cb80470434eb | 26 | byte aenv_S = 255; //sustain (0-255) |
Clemo | 0:cb80470434eb | 27 | int aenv_R = 0; //release (in ticks) |
Clemo | 0:cb80470434eb | 28 | byte aenv_level = 0; //current output level (0-255) |
Clemo | 0:cb80470434eb | 29 | |
Clemo | 0:cb80470434eb | 30 | //local variables |
Clemo | 0:cb80470434eb | 31 | unsigned long aenv_curtick; //current tick through env shape |
Clemo | 0:cb80470434eb | 32 | unsigned long aenv_starttick; //tick that env started at |
Clemo | 0:cb80470434eb | 33 | byte aenv_curstate = 0; //0 = off, 1 = triggering, 2 = holding, 3 = releasing |
Clemo | 0:cb80470434eb | 34 | boolean aenv_changed = true; //used to only calc Env when it's been triggered |
Clemo | 0:cb80470434eb | 35 | byte aenv_Rstart = 0; //incase key up before decay finishes |
Clemo | 0:cb80470434eb | 36 | |
Clemo | 0:cb80470434eb | 37 | // lets and gets |
Clemo | 0:cb80470434eb | 38 | |
Clemo | 0:cb80470434eb | 39 | //set attack (in ticks) |
Clemo | 0:cb80470434eb | 40 | void Aenv_Let_A(int newA){ |
Clemo | 0:cb80470434eb | 41 | if (newA!=aenv_A){ |
Clemo | 0:cb80470434eb | 42 | aenv_A = newA; |
Clemo | 0:cb80470434eb | 43 | aenv_changed = true; |
Clemo | 0:cb80470434eb | 44 | } |
Clemo | 0:cb80470434eb | 45 | } |
Clemo | 0:cb80470434eb | 46 | |
Clemo | 0:cb80470434eb | 47 | |
Clemo | 0:cb80470434eb | 48 | int Aenv_Get_A(void) |
Clemo | 0:cb80470434eb | 49 | { |
Clemo | 0:cb80470434eb | 50 | return aenv_A; |
Clemo | 0:cb80470434eb | 51 | } |
Clemo | 0:cb80470434eb | 52 | |
Clemo | 0:cb80470434eb | 53 | |
Clemo | 0:cb80470434eb | 54 | //set decay (in ticks) |
Clemo | 0:cb80470434eb | 55 | void Aenv_Let_D(int newD) |
Clemo | 0:cb80470434eb | 56 | { |
Clemo | 0:cb80470434eb | 57 | if (newD!=aenv_D){ |
Clemo | 0:cb80470434eb | 58 | aenv_D = newD; |
Clemo | 0:cb80470434eb | 59 | aenv_changed = true; |
Clemo | 0:cb80470434eb | 60 | } |
Clemo | 0:cb80470434eb | 61 | } |
Clemo | 0:cb80470434eb | 62 | |
Clemo | 0:cb80470434eb | 63 | |
Clemo | 0:cb80470434eb | 64 | int Aenv_Get_D(void) |
Clemo | 0:cb80470434eb | 65 | { |
Clemo | 0:cb80470434eb | 66 | return aenv_D; |
Clemo | 0:cb80470434eb | 67 | } |
Clemo | 0:cb80470434eb | 68 | |
Clemo | 0:cb80470434eb | 69 | |
Clemo | 0:cb80470434eb | 70 | //set sustain (0-255) |
Clemo | 0:cb80470434eb | 71 | void Aenv_Let_S(byte newS) |
Clemo | 0:cb80470434eb | 72 | { |
Clemo | 0:cb80470434eb | 73 | if (newS!=aenv_S){ |
Clemo | 0:cb80470434eb | 74 | aenv_S = newS; |
Clemo | 0:cb80470434eb | 75 | aenv_changed = true; |
Clemo | 0:cb80470434eb | 76 | } |
Clemo | 0:cb80470434eb | 77 | } |
Clemo | 0:cb80470434eb | 78 | |
Clemo | 0:cb80470434eb | 79 | |
Clemo | 0:cb80470434eb | 80 | byte Aenv_Get_S(void) |
Clemo | 0:cb80470434eb | 81 | { |
Clemo | 0:cb80470434eb | 82 | return aenv_S; |
Clemo | 0:cb80470434eb | 83 | } |
Clemo | 0:cb80470434eb | 84 | |
Clemo | 0:cb80470434eb | 85 | |
Clemo | 0:cb80470434eb | 86 | //set release (in ticks) |
Clemo | 0:cb80470434eb | 87 | void Aenv_Let_R(int newR) |
Clemo | 0:cb80470434eb | 88 | { |
Clemo | 0:cb80470434eb | 89 | if (newR!=aenv_R){ |
Clemo | 0:cb80470434eb | 90 | aenv_R = newR; |
Clemo | 0:cb80470434eb | 91 | aenv_changed = true; |
Clemo | 0:cb80470434eb | 92 | } |
Clemo | 0:cb80470434eb | 93 | } |
Clemo | 0:cb80470434eb | 94 | |
Clemo | 0:cb80470434eb | 95 | |
Clemo | 0:cb80470434eb | 96 | int Aenv_Get_R(void) |
Clemo | 0:cb80470434eb | 97 | { |
Clemo | 0:cb80470434eb | 98 | return aenv_R; |
Clemo | 0:cb80470434eb | 99 | } |
Clemo | 0:cb80470434eb | 100 | |
Clemo | 0:cb80470434eb | 101 | |
Clemo | 0:cb80470434eb | 102 | //get current state of env (0 = off, 1 = triggering, 2 = holding, 3 = releasing) |
Clemo | 0:cb80470434eb | 103 | byte Aenv_Get_State() |
Clemo | 0:cb80470434eb | 104 | { |
Clemo | 0:cb80470434eb | 105 | return aenv_curstate; |
Clemo | 0:cb80470434eb | 106 | } |
Clemo | 0:cb80470434eb | 107 | |
Clemo | 0:cb80470434eb | 108 | |
Clemo | 0:cb80470434eb | 109 | //get current level of env (0-255) |
Clemo | 0:cb80470434eb | 110 | byte Aenv_Get_Level(void) |
Clemo | 0:cb80470434eb | 111 | { |
Clemo | 0:cb80470434eb | 112 | return aenv_level; |
Clemo | 0:cb80470434eb | 113 | } |
Clemo | 0:cb80470434eb | 114 | |
Clemo | 0:cb80470434eb | 115 | |
Clemo | 0:cb80470434eb | 116 | //ENVELOPE MEAT |
Clemo | 0:cb80470434eb | 117 | //trigger the (start of) envelope |
Clemo | 0:cb80470434eb | 118 | void AEnv_Trigger(void) |
Clemo | 0:cb80470434eb | 119 | { |
Clemo | 0:cb80470434eb | 120 | aenv_curtick = 0; //reset curtick |
Clemo | 0:cb80470434eb | 121 | aenv_starttick = master_tick; //set starttick = master tick |
Clemo | 0:cb80470434eb | 122 | aenv_curstate = 1; //set state to attack |
Clemo | 0:cb80470434eb | 123 | aenv_changed = true; //so calcval does something |
Clemo | 0:cb80470434eb | 124 | } |
Clemo | 0:cb80470434eb | 125 | |
Clemo | 0:cb80470434eb | 126 | |
Clemo | 0:cb80470434eb | 127 | //trigger release stage of envelope |
Clemo | 0:cb80470434eb | 128 | void AEnv_Release(void) |
Clemo | 0:cb80470434eb | 129 | { |
Clemo | 0:cb80470434eb | 130 | aenv_curtick = 0; //reset curtick |
Clemo | 0:cb80470434eb | 131 | aenv_starttick = master_tick; //set starttick = master tick |
Clemo | 0:cb80470434eb | 132 | aenv_curstate = 3; //set state to release |
Clemo | 0:cb80470434eb | 133 | aenv_Rstart = aenv_level; //set release start level = current level. This may NOT be sustain level, if still in decay stage |
Clemo | 0:cb80470434eb | 134 | aenv_changed = true; //so calcval does something |
Clemo | 0:cb80470434eb | 135 | } |
Clemo | 0:cb80470434eb | 136 | |
Clemo | 0:cb80470434eb | 137 | |
Clemo | 0:cb80470434eb | 138 | //calculate env output level |
Clemo | 0:cb80470434eb | 139 | void AEnv_CalcVal(void) |
Clemo | 0:cb80470434eb | 140 | { |
Clemo | 0:cb80470434eb | 141 | if (aenv_changed==true){ //is envelope actually doing something? |
Clemo | 0:cb80470434eb | 142 | switch (aenv_curstate){ |
Clemo | 0:cb80470434eb | 143 | case 0: //idle |
Clemo | 0:cb80470434eb | 144 | aenv_level = 0; |
Clemo | 0:cb80470434eb | 145 | aenv_changed = false; |
Clemo | 0:cb80470434eb | 146 | break; |
Clemo | 0:cb80470434eb | 147 | case 1: //triggering |
Clemo | 0:cb80470434eb | 148 | aenv_curtick = master_tick - aenv_starttick; //update tick |
Clemo | 0:cb80470434eb | 149 | if (aenv_curtick>=aenv_A+aenv_D){ //if attack + decay ticks passed, then onto sustain |
Clemo | 0:cb80470434eb | 150 | aenv_level = aenv_S; |
Clemo | 0:cb80470434eb | 151 | aenv_curstate = 2; |
Clemo | 0:cb80470434eb | 152 | } |
Clemo | 0:cb80470434eb | 153 | else if (aenv_curtick>=aenv_A){ //if attack ticks passed, then onto decay |
Clemo | 0:cb80470434eb | 154 | aenv_level = map(aenv_curtick,aenv_A,aenv_A+aenv_D,255,aenv_S); |
Clemo | 0:cb80470434eb | 155 | } |
Clemo | 0:cb80470434eb | 156 | else{ |
Clemo | 0:cb80470434eb | 157 | aenv_level = map(aenv_curtick,0,aenv_A,0,255); //otherwise must be doing attack |
Clemo | 0:cb80470434eb | 158 | } |
Clemo | 0:cb80470434eb | 159 | break; |
Clemo | 0:cb80470434eb | 160 | case 2: //holding |
Clemo | 0:cb80470434eb | 161 | aenv_level = aenv_S; //make sure level = sustain level |
Clemo | 0:cb80470434eb | 162 | aenv_changed = false; //only need to do this once |
Clemo | 0:cb80470434eb | 163 | break; |
Clemo | 0:cb80470434eb | 164 | case 3: |
Clemo | 0:cb80470434eb | 165 | aenv_curtick = master_tick - aenv_starttick; //releasing |
Clemo | 0:cb80470434eb | 166 | if (aenv_curtick>=aenv_R){ //if release ticks passed, then go back to idle |
Clemo | 0:cb80470434eb | 167 | aenv_level = 0; |
Clemo | 0:cb80470434eb | 168 | aenv_curstate = 0; |
Clemo | 0:cb80470434eb | 169 | } |
Clemo | 0:cb80470434eb | 170 | else{ //otherwise must be releasing |
Clemo | 0:cb80470434eb | 171 | aenv_level = map(aenv_curtick,0,aenv_R,aenv_Rstart,0); |
Clemo | 0:cb80470434eb | 172 | } |
Clemo | 0:cb80470434eb | 173 | break; |
Clemo | 0:cb80470434eb | 174 | } |
Clemo | 0:cb80470434eb | 175 | } |
Clemo | 0:cb80470434eb | 176 | } |