Mozzi  version v2.0
sound synthesis library for Arduino
StateVariable.h
1 /*
2  * StateVariable.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10  */
11 
43 #ifndef STATEVARIABLE_H_
44 #define STATEVARIABLE_H_
45 
46 #include "Arduino.h"
47 #include "math.h"
48 #include "meta.h"
49 #include "mozzi_fixmath.h"
50 #include "mozzi_utils.h"
51 #include "ResonantFilter.h"
52 
53 //enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
54 
65 template <int8_t FILTER_TYPE> class StateVariable {
66 
67 public:
71 
79  void setResonance(Q0n8 resonance) {
80  // qvalue goes from 255 to 0, representing .999 to 0 in fixed point
81  // lower q, more resonance
82  q = resonance;
83  scale = (Q0n8)sqrt((unsigned int)resonance << 8);
84  }
85 
94  void setCentreFreq(unsigned int centre_freq) {
95  // simple frequency tuning with error towards nyquist (reference? where did
96  // this come from?)
97  // f = (Q1n15)(((Q16n16_2PI*centre_freq)>>AUDIO_RATE_AS_LSHIFT)>>1);
98  f = (Q15n16)((Q16n16_2PI * centre_freq) >>
99  (AUDIO_RATE_AS_LSHIFT)); // this works best for now
100  // f = (Q15n16)(((Q16n16_2PI*centre_freq)<<(16-AUDIO_RATE_AS_LSHIFT))>>16);
101  // // a small shift left and a round 16 right is faster than big
102  // non-byte-aligned right in one go float ff =
103  // Q16n16_to_float(((Q16n16_PI*centre_freq))>>AUDIO_RATE_AS_LSHIFT); f =
104  // float_to_Q15n16(2.0f *sin(ff));
105  }
106 
112  inline int next(int input) {
113  // chooses a different next() function depending on whether the
114  // filter is declared as LOWPASS, BANDPASS, HIGHPASS or NOTCH.
115  // See meta.h.
116  return next(input, Int2Type<FILTER_TYPE>());
117  }
118 
119 private:
120  int low, band;
121  Q0n8 q, scale;
122  volatile Q15n16 f;
123 
129  inline int next(int input, Int2Type<LOWPASS>) {
130  // setPin13High();
131  low += ((f * band) >> 16);
132  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
133  band += ((f * high) >> 16);
134  // int notch = high + low;
135  // setPin13Low();
136  return low;
137  }
138 
144  inline int next(int input, Int2Type<BANDPASS>) {
145  // setPin13High();
146  low += ((f * band) >> 16);
147  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
148  band += ((f * high) >> 16);
149  // int notch = high + low;
150  // setPin13Low();
151  return band;
152  }
153 
159  inline int next(int input, Int2Type<HIGHPASS>) {
160  // setPin13High();
161  low += ((f * band) >> 16);
162  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
163  band += ((f * high) >> 16);
164  // int notch = high + low;
165  // setPin13Low();
166  return high;
167  }
168 
174  inline int next(int input, Int2Type<NOTCH>) {
175  // setPin13High();
176  low += ((f * band) >> 16);
177  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
178  band += ((f * high) >> 16);
179  int notch = high + low;
180  // setPin13Low();
181  return notch;
182  }
183 };
184 
190 #endif /* STATEVARIABLE_H_ */
State Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www....
Definition: StateVariable.h:65
int next(int input)
Calculate the next sample, given an input signal.
void setCentreFreq(unsigned int centre_freq)
Set the centre or corner frequency of the filter.
Definition: StateVariable.h:94
void setResonance(Q0n8 resonance)
Set how resonant the filter will be.
Definition: StateVariable.h:79
StateVariable()
Constructor.
Definition: StateVariable.h:70
uint8_t Q0n8
unsigned fractional number using 8 fractional bits, represents 0.0 to 0.996
Definition: mozzi_fixmath.h:33
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767....
Definition: mozzi_fixmath.h:46
#define Q16n16_2PI
2*PI in Q16n16 format
Definition: mozzi_fixmath.h:75
Enables you to instantiate a template based on an integer value.
Definition: meta.h:41