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