![]() |
Mozzi
alpha 0.01.1t
sound synthesis library for Arduino
|
00001 /* 00002 * Portamento.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 PORTAMENTO_H_ 00024 #define PORTAMENTO_H_ 00025 00026 #include "mozzi_midi.h" 00027 #include "fixedMath.h" 00028 #include "Line.h" 00029 00032 template <unsigned int CONTROL_UPDATE_RATE> 00033 class 00034 Portamento { 00035 00036 public: 00037 00040 Portamento(): 00041 MICROS_PER_CONTROL_STEP(1000000/CONTROL_UPDATE_RATE) 00042 { 00043 } 00044 00048 inline 00049 void setTime(unsigned int milliseconds){ 00050 //control_steps_per_portamento = ((long)milliseconds*1000)/MICROS_PER_CONTROL_STEP; // more accurate but slower 00051 control_steps_per_portamento = convertMsecToControlSteps(milliseconds); 00052 } 00053 00057 inline 00058 void start(unsigned char note) { 00059 target_freq = Q16n16_mtof(Q8n0_to_Q16n16(note)); 00060 aPortamentoLine.set(target_freq, control_steps_per_portamento); 00061 countdown = control_steps_per_portamento; 00062 portamento_on=true; 00063 } 00064 00068 inline 00069 void start(Q16n16 note) { 00070 target_freq = Q16n16_mtof(note); 00071 aPortamentoLine.set(target_freq, control_steps_per_portamento); 00072 countdown = control_steps_per_portamento; 00073 portamento_on=true; 00074 } 00075 00076 00081 inline 00082 Q16n16 next() { 00083 if (portamento_on==true){ 00084 if(--countdown < 0) { 00085 // stay level when portamento has finished 00086 aPortamentoLine.set(target_freq, target_freq, control_steps_per_portamento); 00087 portamento_on=false; 00088 } 00089 } 00090 return aPortamentoLine.next(); 00091 } 00092 00093 private: 00094 00095 int countdown; 00096 int control_steps_per_portamento; 00097 Q16n16 target_freq; 00098 bool portamento_on; 00099 const unsigned int MICROS_PER_CONTROL_STEP; 00100 Line <Q16n16> aPortamentoLine; 00101 00102 00103 // copied from ADSR.h 00104 inline 00105 static const unsigned int convertMsecToControlSteps(unsigned int msec){ 00106 return (uint) (((ulong)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift 00107 } 00108 00109 }; 00110 00111 #endif /* PORTAMENTO_H_ */