Mozzi  alpha 0.01.1t
sound synthesis library for Arduino
 All Classes Functions Typedefs
StateVariable.h
00001 /*
00002  * StateVariable.h
00003  *
00004  * This implementation 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 
00032 #ifndef STATEVARIABLE_H_
00033 #define STATEVARIABLE_H_
00034 
00035 #include "Arduino.h"
00036 #include "util/atomic.h"
00037 #include "fixedMath.h"
00038 #include "math.h"
00039 #include "utils.h"
00040 #include "meta.h"
00041 
00042 
00043 enum filter_types {LOWPASS,BANDPASS,HIGHPASS,NOTCH};
00044 
00053 template <char FILTER_TYPE>
00054 class StateVariable
00055 {
00056 
00057 public:
00058 
00059 
00062                 StateVariable()
00063                 {
00064                 }
00065 
00066 
00067 
00075                 void setResonance(Q0n8 resonance){
00076                                 // qvalue goes from 255 to 0, representing .999 to 0 in fixed point
00077                                 // lower q, more resonance
00078                                 q = resonance;
00079                                 //ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00080                                 //{
00081                                 scale = (Q0n8)sqrt((unsigned int) resonance<<8);
00082                                 //}
00083                 }
00084 
00085 
00086 
00093                 /*
00094                 void setCentreFreq(unsigned int centre_freq){
00095                                 // simple frequency tuning with error towards nyquist
00096                                 // F is the filter's center frequency
00097                                 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00098                                 {
00099                                                 f = (Q1n15)(((Q16n16_2PI*centre_freq)>>AUDIO_RATE_AS_LSHIFT)>>1);
00100                                 }
00101                 }
00102 */
00103                 void setCentreFreq(unsigned int centre_freq){
00104                                 // simple frequency tuning with error towards nyquist
00105                                 // F is the filter's center frequency
00106                                 //ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00107                                 //{
00108                                                 //f = (Q1n15)(((Q16n16_2PI*centre_freq)>>AUDIO_RATE_AS_LSHIFT)>>1);
00109                                                 f = (Q1n15)((Q16n16_2PI*centre_freq)>>(AUDIO_RATE_AS_LSHIFT+1));
00110                                 //}
00111                 }
00112 
00113 
00119                 inline
00120                 int next(int input)
00121                 {
00122                                 // chooses a different next() function depending on whether the
00123                                 // filter is declared as LOWPASS, BANDPASS, HIGHPASS or NOTCH.
00124                                 // See meta.h.
00125                                 return next(input, Int2Type<FILTER_TYPE>());
00126                 }
00127 
00128 
00129 
00130 
00131 private:
00132                 int low, band;
00133                 Q0n8 q,scale;
00134                 volatile Q1n15 f;
00135 
00136 
00142                 inline
00143                 int next(int input, Int2Type<LOWPASS>)
00144                 {
00145                                 //SET_PIN13_HIGH;
00146                                 low += (((long)band * f)>>15);
00147                                 int high = (((long)input - low - (((long)band * q)>>8))*scale)>>8;
00148                                 band += (((long)high * f)>>15);
00149                                 //int notch = high + low;
00150                                 //SET_PIN13_LOW;
00151                                 return low;
00152                 }
00153 
00154 
00160                 inline
00161                 int next(int input, Int2Type<BANDPASS>)
00162                 {
00163                                 //SET_PIN13_HIGH;
00164                                 low += (((long)band * f)>>15);
00165                                 int high = (((long)input - low - (((long)band * q)>>8))*scale)>>8;
00166                                 band += (((long)high * f)>>15);
00167                                 //int notch = high + low;
00168                                 //SET_PIN13_LOW;
00169                                 return band;
00170                 }
00171 
00172 
00173 
00179                 inline
00180                 int next(int input, Int2Type<HIGHPASS>)
00181                 {
00182                                 //SET_PIN13_HIGH;
00183                                 low += (((long)band * f)>>15);
00184                                 int high = (((long)input - low - (((long)band * q)>>8))*scale)>>8;
00185                                 band += (((long)high * f)>>15);
00186                                 //int notch = high + low;
00187                                 //SET_PIN13_LOW;
00188                                 return high;
00189                 }
00190 
00191 
00192 
00198                 inline
00199                 int next(int input, Int2Type<NOTCH>)
00200                 {
00201                                 //SET_PIN13_HIGH;
00202                                 low += (((long)band * f)>>15);
00203                                 int high = (((long)input - low - (((long)band * q)>>8))*scale)>>8;
00204                                 band += (((long)high * f)>>15);
00205                                 int notch = high + low;
00206                                 //SET_PIN13_LOW;
00207                                 return notch;
00208                 }
00209 
00210 };
00211 
00212 #endif /* STATEVARIABLE_H_ */