andrewm@0
|
1 /*
|
andrewm@0
|
2 * OscillatorBank.h
|
andrewm@0
|
3 *
|
andrewm@0
|
4 * Created on: May 23, 2014
|
andrewm@0
|
5 * Author: Victor Zappi and Andrew McPherson
|
andrewm@0
|
6 */
|
andrewm@0
|
7
|
andrewm@0
|
8 #ifndef OSCILLATORBANK_H_
|
andrewm@0
|
9 #define OSCILLATORBANK_H_
|
andrewm@0
|
10
|
andrewm@0
|
11
|
andrewm@0
|
12 #include <string>
|
andrewm@0
|
13
|
andrewm@0
|
14 #include "spear_parser.h"
|
andrewm@0
|
15 #include "ADSR.h"
|
andrewm@0
|
16 #include "config.h"
|
andrewm@0
|
17
|
andrewm@0
|
18 using namespace std;
|
andrewm@0
|
19
|
andrewm@0
|
20 enum OscBankstates {bank_stopped, bank_playing, bank_toreset};
|
andrewm@0
|
21
|
andrewm@0
|
22 class OscillatorBank
|
andrewm@0
|
23 {
|
andrewm@0
|
24 public:
|
andrewm@0
|
25 OscillatorBank();
|
andrewm@0
|
26 OscillatorBank(string filename, int hopsize=-1, int samplerate=44100);
|
andrewm@0
|
27 OscillatorBank(char *filename, int hopsize=-1, int samplerate=44100);
|
andrewm@0
|
28 ~OscillatorBank();
|
andrewm@0
|
29 float *oscillatorPhases;
|
andrewm@0
|
30 float *oscillatorNormFrequencies;
|
andrewm@0
|
31 float *oscillatorNormFreqDerivatives;
|
andrewm@0
|
32 float *oscillatorAmplitudes;
|
andrewm@0
|
33 float *oscillatorAmplitudeDerivatives;
|
andrewm@0
|
34 float *oscStatNormFrequenciesMean;
|
andrewm@0
|
35 float *oscStatNumHops;
|
andrewm@0
|
36 OscBankstates state;
|
andrewm@0
|
37 bool note;
|
andrewm@0
|
38 int actPartNum;
|
andrewm@0
|
39 unsigned int *actPart;
|
andrewm@0
|
40 int hopCounter;
|
andrewm@0
|
41 int lookupTableSize;
|
andrewm@0
|
42 float *lookupTable;
|
andrewm@0
|
43 float ampTh;
|
andrewm@0
|
44 int hopNumTh;
|
andrewm@0
|
45 float pitchMultiplier;
|
andrewm@0
|
46 float freqMovement;
|
andrewm@0
|
47 int filterNum;
|
andrewm@0
|
48 float filterFreqs[5];
|
andrewm@0
|
49 float filterQ[5];
|
andrewm@0
|
50 float filterMaxF;
|
andrewm@0
|
51 float filterAmpMinF;
|
andrewm@0
|
52 float filterAmpMaxF;
|
andrewm@0
|
53 float filterAmpMul;
|
andrewm@0
|
54
|
andrewm@0
|
55 bool loadFile(string filename, int hopsize=-1, int samplerate=44100);
|
andrewm@0
|
56 bool loadFile(char *filename, int hopsize=-1, int samplerate=44100);
|
andrewm@0
|
57 bool initBank(int oversamp=1);
|
andrewm@0
|
58 void resetOscillators();
|
andrewm@0
|
59 int getHopSize() { return hopSize; }
|
andrewm@0
|
60 void nextHop();
|
andrewm@0
|
61 void setLoopHops(int start, int end);
|
andrewm@0
|
62 void play(float vel);
|
andrewm@0
|
63 void stop();
|
andrewm@0
|
64 void afterTouch(float vel);
|
andrewm@0
|
65 int getEnvelopeState();
|
andrewm@0
|
66 float getFrequencyScaler();
|
andrewm@0
|
67 void setSpeed(float sp);
|
andrewm@0
|
68 float getSpeed();
|
andrewm@0
|
69 float getMaxSpeed();
|
andrewm@0
|
70 float getMinSpeed();
|
andrewm@0
|
71 void setJumpHop(int hop);
|
andrewm@0
|
72 int getLastHop();
|
andrewm@0
|
73 int getCurrentHop() { return currentHop; }
|
andrewm@0
|
74
|
andrewm@0
|
75 private:
|
andrewm@0
|
76
|
andrewm@0
|
77 bool loaded;
|
andrewm@0
|
78 int numOfPartials;
|
andrewm@0
|
79 int numOfOscillators;
|
andrewm@0
|
80 int partialsHopSize;
|
andrewm@0
|
81 int overSampling;
|
andrewm@0
|
82 int hopSize;
|
andrewm@0
|
83 int hopSizeReminder;
|
andrewm@0
|
84 int oscBankHopSize;
|
andrewm@0
|
85 float frequencyScaler;
|
andrewm@0
|
86 float nyqNorm;
|
andrewm@0
|
87 int lastHop;
|
andrewm@0
|
88 int currentHop;
|
andrewm@0
|
89 int loopDir;
|
andrewm@0
|
90 int loopDirShift;
|
andrewm@0
|
91 int loopStartHop;
|
andrewm@0
|
92 int loopEndHop;
|
andrewm@0
|
93 int *indicesMapping;
|
andrewm@0
|
94 float *phaseCopies;
|
andrewm@0
|
95 float *oscillatorNextNormFreq;
|
andrewm@0
|
96 float *oscillatorNextAmp;
|
andrewm@0
|
97 float *nextNormFreqCopies;
|
andrewm@0
|
98 float *nextAmpCopies;
|
andrewm@0
|
99 float *freqFixedDeltas;
|
andrewm@0
|
100 float *ampFixedDeltas;
|
andrewm@0
|
101 bool *nyquistCut;
|
andrewm@0
|
102 Spear_parser parser;
|
andrewm@0
|
103 Partials *partials;
|
andrewm@0
|
104 ADSR adsr;
|
andrewm@0
|
105 float minAttackTime;
|
andrewm@0
|
106 float deltaAttackTime;
|
andrewm@0
|
107 float minReleaseTime;
|
andrewm@0
|
108 float deltaReleaseTime;
|
andrewm@0
|
109 int envState;
|
andrewm@0
|
110 int rate;
|
andrewm@0
|
111 float speed;
|
andrewm@0
|
112 float nextSpeed;
|
andrewm@0
|
113 float maxSpeed;
|
andrewm@0
|
114 float minSpeed;
|
andrewm@0
|
115 int jumpHop;
|
andrewm@0
|
116 float adsrVal;
|
andrewm@0
|
117 float prevAdsrVal;
|
andrewm@0
|
118 float prevAmpTh;
|
andrewm@0
|
119 int prevHopNumTh;
|
andrewm@0
|
120 float prevPitchMultiplier;
|
andrewm@0
|
121 float prevFreqMovement;
|
andrewm@0
|
122 int prevFilterNum;
|
andrewm@0
|
123 float prevFilterFreqs[5];
|
andrewm@0
|
124 float prevFilterQ[5];
|
andrewm@0
|
125
|
andrewm@0
|
126 bool loader(char *filename, int hopsize=-1, int samplerate=44100);
|
andrewm@0
|
127 void addFakeOsc();
|
andrewm@0
|
128 void nextOscBankHop();
|
andrewm@0
|
129 void nextPartialHop();
|
andrewm@0
|
130 int jumpToHop();
|
andrewm@0
|
131 void setDirection(int dir);
|
andrewm@0
|
132 int nextEnvState();
|
andrewm@0
|
133 void checkDirection();
|
andrewm@0
|
134 void checkSpeed();
|
andrewm@0
|
135 int checkJump();
|
andrewm@0
|
136 bool checkOversampling();
|
andrewm@0
|
137 void updatePrevControls();
|
andrewm@0
|
138 float calculateParDamping(int parIndex, int hopNTh, float adsrVl, float nextFreq,
|
andrewm@0
|
139 int filNum, float *filFreq, float *filQ);
|
andrewm@0
|
140 };
|
andrewm@0
|
141
|
andrewm@0
|
142 inline bool OscillatorBank::loadFile(string filename, int hopsize, int samplerate)
|
andrewm@0
|
143 {
|
andrewm@0
|
144 return loader((char *)filename.c_str(), hopsize, samplerate);
|
andrewm@0
|
145 }
|
andrewm@0
|
146
|
andrewm@0
|
147 inline bool OscillatorBank::loadFile(char *filename, int hopsize, int samplerate)
|
andrewm@0
|
148 {
|
andrewm@0
|
149 return loader(filename, hopsize, samplerate);
|
andrewm@0
|
150 }
|
andrewm@0
|
151
|
andrewm@0
|
152 inline void OscillatorBank::setLoopHops(int start, int end)
|
andrewm@0
|
153 {
|
andrewm@0
|
154 if(start > end)
|
andrewm@0
|
155 end = start;
|
andrewm@0
|
156
|
andrewm@0
|
157 if(start<0)
|
andrewm@0
|
158 start = 0;
|
andrewm@0
|
159 else if(start>lastHop)
|
andrewm@0
|
160 start = 0;
|
andrewm@0
|
161 if(end < 1)
|
andrewm@0
|
162 end = 1;
|
andrewm@0
|
163 end = (end<=lastHop) ? end : lastHop;
|
andrewm@0
|
164
|
andrewm@0
|
165 // set it, take into consideration hop oversampling
|
andrewm@0
|
166 loopStartHop = start*overSampling;
|
andrewm@0
|
167 loopEndHop = end*overSampling;
|
andrewm@0
|
168 }
|
andrewm@0
|
169
|
andrewm@0
|
170 inline void OscillatorBank::stop()
|
andrewm@0
|
171 {
|
andrewm@0
|
172 note = false;
|
andrewm@0
|
173 adsr.gate(0);
|
andrewm@0
|
174 }
|
andrewm@0
|
175
|
andrewm@0
|
176 inline float OscillatorBank::getFrequencyScaler()
|
andrewm@0
|
177 {
|
andrewm@0
|
178 return frequencyScaler;
|
andrewm@0
|
179 }
|
andrewm@0
|
180
|
andrewm@0
|
181 inline void OscillatorBank::afterTouch(float vel)
|
andrewm@0
|
182 {
|
andrewm@0
|
183 hopNumTh = log((1-vel)+1)/log(2)*20000;
|
andrewm@0
|
184 if(adsr.getState()==env_attack)
|
andrewm@0
|
185 adsr.setAttackRate( (minAttackTime + ( (1-vel)*deltaAttackTime )) * rate );
|
andrewm@0
|
186 adsr.setReleaseRate( (minReleaseTime+(1-vel)*deltaReleaseTime)* rate );
|
andrewm@0
|
187 }
|
andrewm@0
|
188
|
andrewm@0
|
189 inline int OscillatorBank::getEnvelopeState()
|
andrewm@0
|
190 {
|
andrewm@0
|
191 return envState;
|
andrewm@0
|
192 }
|
andrewm@0
|
193
|
andrewm@0
|
194 inline void OscillatorBank::setSpeed(float sp)
|
andrewm@0
|
195 {
|
andrewm@0
|
196 nextSpeed = sp;
|
andrewm@0
|
197 }
|
andrewm@0
|
198
|
andrewm@0
|
199 inline float OscillatorBank::getSpeed()
|
andrewm@0
|
200 {
|
andrewm@0
|
201 return speed;
|
andrewm@0
|
202 }
|
andrewm@0
|
203
|
andrewm@0
|
204 inline float OscillatorBank::getMaxSpeed()
|
andrewm@0
|
205 {
|
andrewm@0
|
206 return maxSpeed;
|
andrewm@0
|
207 }
|
andrewm@0
|
208
|
andrewm@0
|
209 inline float OscillatorBank::getMinSpeed()
|
andrewm@0
|
210 {
|
andrewm@0
|
211 return minSpeed;
|
andrewm@0
|
212 }
|
andrewm@0
|
213
|
andrewm@0
|
214 inline void OscillatorBank::setJumpHop(int hop)
|
andrewm@0
|
215 {
|
andrewm@0
|
216 if(hop<0)
|
andrewm@0
|
217 return;
|
andrewm@0
|
218 hop = (hop<=lastHop) ? hop : lastHop;
|
andrewm@0
|
219 jumpHop = hop;
|
andrewm@0
|
220 }
|
andrewm@0
|
221
|
andrewm@0
|
222 inline void OscillatorBank::setDirection(int dir)
|
andrewm@0
|
223 {
|
andrewm@0
|
224 if(dir>=0)
|
andrewm@0
|
225 {
|
andrewm@0
|
226 loopDir = 1;
|
andrewm@0
|
227 loopDirShift = 0;
|
andrewm@0
|
228 }
|
andrewm@0
|
229 else
|
andrewm@0
|
230 {
|
andrewm@0
|
231 loopDir = -1;
|
andrewm@0
|
232 loopDirShift = 1;
|
andrewm@0
|
233 }
|
andrewm@0
|
234 }
|
andrewm@0
|
235
|
andrewm@0
|
236 inline int OscillatorBank::getLastHop()
|
andrewm@0
|
237 {
|
andrewm@0
|
238 return lastHop;
|
andrewm@0
|
239 }
|
andrewm@0
|
240 #endif /* OSCILLATORBANK_H_ */
|