![]() |
Mozzi
alpha 0.01.1t
sound synthesis library for Arduino
|
00001 /* 00002 * ADSR.h 00003 * 00004 * Copyright 2012 Tim Barrass. 00005 * 00006 * This file is part of Mozzi. 00007 * 00008 * Mozzi is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * Mozzi is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with Mozzi. If not, see <http://www.gnu.org/licenses/>. 00020 * 00021 */ 00022 00023 #ifndef ADSR_H_ 00024 #define ADSR_H_ 00025 00026 #include "Arduino.h" 00027 //#include <util/atomic.h> 00028 #include "Line.h" 00029 #include "fixedMath.h" 00030 00037 template <unsigned int CONTROL_UPDATE_RATE> 00038 class ADSR 00039 { 00040 private: 00041 00042 const unsigned int AUDIO_TICKS_PER_CONTROL; 00043 00044 unsigned int phase_control_step_counter; 00045 unsigned int phase_num_control_steps; 00046 00047 enum {ATTACK,DECAY,SUSTAIN,RELEASE,IDLE}; 00048 00049 00050 struct phase{ 00051 byte phase_type; 00052 unsigned int control_steps; 00053 unsigned long audio_steps; 00054 Q8n0 level; 00055 }attack,decay,sustain,release,idle; 00056 00057 phase * current_phase; 00058 00059 // Linear audio rate transitions for envelope 00060 Line <unsigned long> transition; 00061 00062 inline 00063 unsigned int convertMsecToControlSteps(unsigned int msec){ 00064 return (uint) (((ulong)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift 00065 } 00066 00067 inline 00068 void setPhase(phase * next_phase) { 00069 phase_control_step_counter = 0; 00070 phase_num_control_steps = next_phase->control_steps; 00071 transition.set(Q8n0_to_Q16n16(next_phase->level),next_phase->audio_steps); 00072 current_phase = next_phase; 00073 } 00074 00075 00076 00077 inline 00078 void checkForAndSetNextPhase(phase * next_phase) { 00079 if (++phase_control_step_counter >= phase_num_control_steps){ 00080 setPhase(next_phase); 00081 } 00082 } 00083 00084 00085 inline 00086 void checkForAndSetIdle() { 00087 if (++phase_control_step_counter >= phase_num_control_steps){ 00088 transition.set(0,0,1); 00089 current_phase = &idle; 00090 } 00091 } 00092 00093 00094 00095 inline 00096 void setTime(phase * p, unsigned int msec) 00097 { 00098 p->control_steps=convertMsecToControlSteps(msec); 00099 p->audio_steps = (ulong) p->control_steps * AUDIO_TICKS_PER_CONTROL; 00100 } 00101 00102 00103 public: 00104 00107 ADSR():AUDIO_TICKS_PER_CONTROL(AUDIO_RATE/CONTROL_UPDATE_RATE) 00108 { 00109 attack.phase_type = ATTACK; 00110 decay.phase_type = DECAY; 00111 sustain.phase_type = SUSTAIN; 00112 release.phase_type = RELEASE; 00113 idle.phase_type = IDLE; 00114 release.level = 0; 00115 } 00116 00117 00121 void update(){ // control rate 00122 00123 switch(current_phase->phase_type) { 00124 00125 case ATTACK: 00126 checkForAndSetNextPhase(&decay); 00127 break; 00128 00129 case DECAY: 00130 checkForAndSetNextPhase(&sustain); 00131 break; 00132 00133 case SUSTAIN: 00134 checkForAndSetNextPhase(&release); 00135 break; 00136 00137 case RELEASE: 00138 checkForAndSetIdle(); 00139 break; 00140 00141 } 00142 } 00143 00148 inline 00149 unsigned int next() 00150 { 00151 return Q16n16_to_Q16n0(transition.next()); 00152 } 00153 00154 00155 00158 inline 00159 void noteOn(){ 00160 setPhase(&attack); 00161 } 00162 00163 00164 00168 inline 00169 void noteOff(){ 00170 setPhase(&release); 00171 } 00172 00173 00174 00175 00176 00180 inline 00181 void setAttackLevel(byte value) 00182 { 00183 attack.level=value; 00184 } 00185 00186 00187 00191 inline 00192 void setDecayLevel(byte value) 00193 { 00194 decay.level=value; 00195 } 00196 00197 00202 inline 00203 void setSustainLevel(byte value) 00204 { 00205 sustain.level=value; 00206 } 00207 00212 inline 00213 void setReleaseLevel(byte value) 00214 { 00215 release.level=value; 00216 } 00217 00218 00219 00225 inline 00226 void setADLevels(byte attack, byte decay) 00227 { 00228 setAttackLevel(attack); 00229 setDecayLevel(decay); 00230 setSustainLevel(decay); 00231 setReleaseLevel(0); 00232 } 00233 00234 00235 00236 00237 00238 00239 00244 inline 00245 void setAttackTime(unsigned int msec) 00246 { 00247 setTime(&attack, msec); 00248 } 00249 00250 00255 inline 00256 void setDecayTime(unsigned int msec) 00257 { 00258 setTime(&decay, msec); 00259 } 00260 00261 00267 inline 00268 void setSustainTime(unsigned int msec) 00269 { 00270 setTime(&sustain, msec); 00271 } 00272 00273 00274 00279 inline 00280 void setReleaseTime(unsigned int msec) 00281 { 00282 setTime(&release, msec); 00283 } 00284 00285 00286 00294 inline 00295 void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms) 00296 { 00297 setAttackTime(attack_ms); 00298 setDecayTime(decay_ms); 00299 setSustainTime(sustain_ms); 00300 setReleaseTime(release_ms); 00301 } 00302 00303 00304 }; 00305 00306 #endif /* ADSR_H_ */