1 // Copyright 2012 Olivier Gillet.
2 //
3 // Author: Olivier Gillet (ol.gillet@gmail.com)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 //
23 // See http://creativecommons.org/licenses/MIT/ for more information.
24 //
25 // -----------------------------------------------------------------------------
26 //
27 // Oscillator - digital style waveforms.
28 
29 #ifndef BRAIDS_DIGITAL_OSCILLATOR_H_
30 #define BRAIDS_DIGITAL_OSCILLATOR_H_
31 
32 #include "stmlib/stmlib.h"
33 
34 #include "braids/excitation.h"
35 #include "braids/svf.h"
36 
37 #include <cstring>
38 
39 namespace braids {
40 
41 static const size_t kWGBridgeLength = 1024;
42 static const size_t kWGNeckLength = 4096;
43 static const size_t kWGBoreLength = 2048;
44 static const size_t kWGJetLength = 1024;
45 static const size_t kWGFBoreLength = 4096;
46 static const size_t kCombDelayLength = 8192;
47 
48 static const size_t kNumFormants = 5;
49 static const size_t kNumPluckVoices = 3;
50 static const size_t kNumOverlappingFof = 3;
51 static const size_t kNumBellPartials = 11;
52 static const size_t kNumDrumPartials = 6;
53 static const size_t kNumAdditiveHarmonics = 12;
54 
55 enum DigitalOscillatorShape {
56   OSC_SHAPE_TRIPLE_RING_MOD,
57   OSC_SHAPE_SAW_SWARM,
58   OSC_SHAPE_COMB_FILTER,
59   OSC_SHAPE_TOY,
60 
61   OSC_SHAPE_DIGITAL_FILTER_LP,
62   OSC_SHAPE_DIGITAL_FILTER_PK,
63   OSC_SHAPE_DIGITAL_FILTER_BP,
64   OSC_SHAPE_DIGITAL_FILTER_HP,
65   OSC_SHAPE_VOSIM,
66   OSC_SHAPE_VOWEL,
67   OSC_SHAPE_VOWEL_FOF,
68 
69   OSC_SHAPE_HARMONICS,
70 
71   OSC_SHAPE_FM,
72   OSC_SHAPE_FEEDBACK_FM,
73   OSC_SHAPE_CHAOTIC_FEEDBACK_FM,
74 
75   OSC_SHAPE_STRUCK_BELL,
76   OSC_SHAPE_STRUCK_DRUM,
77 
78   OSC_SHAPE_KICK,
79   OSC_SHAPE_HAT,
80   OSC_SHAPE_SNARE,
81 
82   OSC_SHAPE_PLUCKED,
83   OSC_SHAPE_BOWED,
84   OSC_SHAPE_BLOWN,
85   OSC_SHAPE_FLUTED,
86 
87   OSC_SHAPE_WAVETABLES,
88   OSC_SHAPE_WAVE_MAP,
89   OSC_SHAPE_WAVE_LINE,
90   OSC_SHAPE_WAVE_PARAPHONIC,
91 
92   OSC_SHAPE_FILTERED_NOISE,
93   OSC_SHAPE_TWIN_PEAKS_NOISE,
94   OSC_SHAPE_CLOCKED_NOISE,
95   OSC_SHAPE_GRANULAR_CLOUD,
96   OSC_SHAPE_PARTICLE_NOISE,
97 
98   OSC_SHAPE_DIGITAL_MODULATION,
99 
100   OSC_SHAPE_QUESTION_MARK_LAST
101 };
102 
103 struct ResoSquareState {
104   uint32_t modulator_phase_increment;
105   uint32_t modulator_phase;
106   uint32_t square_modulator_phase;
107   int32_t integrator;
108   bool polarity;
109 };
110 
111 struct VowelSynthesizerState {
112   uint32_t formant_increment[3];
113   uint32_t formant_phase[3];
114   uint32_t formant_amplitude[3];
115   uint16_t consonant_frames;
116   uint16_t noise;
117 };
118 
119 struct SawSwarmState {
120   uint32_t phase[6];
121   int32_t filter_state[2][2];
122   int32_t dc_blocked;
123   int32_t lp;
124   int32_t bp;
125 };
126 
127 struct HarmonicsState {
128   int32_t amplitude[kNumAdditiveHarmonics];
129 };
130 
131 struct AdditiveState {
132   uint32_t partial_phase[kNumBellPartials];
133   uint32_t partial_phase_increment[kNumBellPartials];
134   int32_t partial_amplitude[kNumBellPartials];
135   int32_t target_partial_amplitude[kNumBellPartials];
136   int16_t previous_sample;
137   size_t current_partial;
138   int32_t lp_noise[3];
139 };
140 
141 struct PluckState {
142   size_t size;
143   size_t write_ptr;
144   size_t shift;
145   size_t mask;
146   size_t pluck_position;
147   size_t initialization_ptr;
148   uint32_t phase;
149   uint32_t phase_increment;
150   uint32_t max_phase_increment;
151   int16_t previous_sample;
152   uint8_t polyphony_assigner;
153 };
154 
155 struct FeedbackFmState {
156   uint32_t modulator_phase;
157   int16_t previous_sample;
158 };
159 
160 struct ParticleNoiseState {
161   uint16_t amplitude;
162   int32_t filter_state[3][2];
163   int32_t filter_scale[3];
164   int32_t filter_coefficient[3];
165 };
166 
167 struct PhysicalModellingState {
168   uint16_t delay_ptr;
169   uint16_t excitation_ptr;
170   int32_t lp_state;
171   int32_t filter_state[2];
172   int16_t previous_sample;
173 };
174 
175 struct Grain {
176   uint32_t phase;
177   uint32_t phase_increment;
178   uint32_t envelope_phase;
179   uint32_t envelope_phase_increment;
180 };
181 
182 struct FofState {
183   int32_t next_saw_sample;
184   int16_t previous_sample;
185   int32_t svf_lp[kNumFormants];
186   int32_t svf_bp[kNumFormants];
187 };
188 
189 struct ToyState {
190   uint8_t held_sample;
191   uint16_t decimation_counter;
192 };
193 
194 struct SvfState {
195   int32_t bp;
196   int32_t lp;
197 };
198 
199 struct DigitalModulationState {
200   uint32_t symbol_phase;
201   uint16_t symbol_count;
202   int32_t filter_state;
203   uint8_t data_byte;
204 };
205 
206 struct ClockedNoiseState {
207   uint32_t cycle_phase;
208   uint32_t cycle_phase_increment;
209   uint32_t rng_state;
210   int32_t seed;
211   int16_t sample;
212 };
213 
214 struct HatState {
215   uint32_t phase[6];
216   uint32_t rng_state;
217 };
218 
219 union DigitalOscillatorState {
220   ResoSquareState res;
221   VowelSynthesizerState vow;
222   SawSwarmState saw;
223   PluckState plk[4];
224   FeedbackFmState ffm;
225   ParticleNoiseState pno;
226   PhysicalModellingState phy;
227   Grain grain[4];
228   FofState fof;
229   ToyState toy;
230   SvfState svf;
231   AdditiveState add;
232   DigitalModulationState dmd;
233   ClockedNoiseState clk;
234   HatState hat;
235   HarmonicsState hrm;
236   uint32_t modulator_phase;
237 };
238 
239 class DigitalOscillator {
240  public:
241   typedef void (DigitalOscillator::*RenderFn)(const uint8_t*, int16_t*, size_t);
242 
DigitalOscillator()243   DigitalOscillator() { }
~DigitalOscillator()244   ~DigitalOscillator() { }
245 
Init()246   inline void Init() {
247     memset(&state_, 0, sizeof(state_));
248     pulse_[0].Init();
249     pulse_[1].Init();
250     pulse_[2].Init();
251     pulse_[3].Init();
252     svf_[0].Init();
253     svf_[1].Init();
254     svf_[2].Init();
255     phase_ = 0;
256     strike_ = true;
257     init_ = true;
258   }
259 
set_shape(DigitalOscillatorShape shape)260   inline void set_shape(DigitalOscillatorShape shape) {
261     shape_ = shape;
262   }
263 
set_pitch(int16_t pitch)264   inline void set_pitch(int16_t pitch) {
265     // Smooth HF noise when the pitch CV is noisy.
266     if (pitch_ > (90 << 7) && pitch > (90 << 7)) {
267       pitch_ = (static_cast<int32_t>(pitch_) + pitch) >> 1;
268     } else {
269       pitch_ = pitch;
270     }
271   }
272 
set_parameters(int16_t parameter_1,int16_t parameter_2)273   inline void set_parameters(
274       int16_t parameter_1,
275       int16_t parameter_2) {
276     parameter_[0] = parameter_1;
277     parameter_[1] = parameter_2;
278   }
279 
phase_increment()280   inline uint32_t phase_increment() const {
281     return phase_increment_;
282   }
283 
Strike()284   inline void Strike() {
285     strike_ = true;
286   }
287 
288   void Render(const uint8_t* sync, int16_t* buffer, size_t size);
289 
290  private:
291   void RenderTripleRingMod(const uint8_t*, int16_t*, size_t);
292   void RenderSawSwarm(const uint8_t*, int16_t*, size_t);
293   void RenderComb(const uint8_t*, int16_t*, size_t);
294   void RenderToy(const uint8_t*, int16_t*, size_t);
295 
296   void RenderDigitalFilter(const uint8_t*, int16_t*, size_t);
297   void RenderVosim(const uint8_t*, int16_t*, size_t);
298   void RenderVowel(const uint8_t*, int16_t*, size_t);
299   void RenderVowelFof(const uint8_t*, int16_t*, size_t);
300 
301   void RenderHarmonics(const uint8_t*, int16_t*, size_t);
302 
303   void RenderFm(const uint8_t*, int16_t*, size_t);
304   void RenderFeedbackFm(const uint8_t*, int16_t*, size_t);
305   void RenderChaoticFeedbackFm(const uint8_t*, int16_t*, size_t);
306 
307   void RenderStruckBell(const uint8_t*, int16_t*, size_t);
308   void RenderStruckDrum(const uint8_t*, int16_t*, size_t);
309   void RenderPlucked(const uint8_t*, int16_t*, size_t);
310   void RenderBowed(const uint8_t*, int16_t*, size_t);
311   void RenderBlown(const uint8_t*, int16_t*, size_t);
312   void RenderFluted(const uint8_t*, int16_t*, size_t);
313 
314   void RenderWavetables(const uint8_t*, int16_t*, size_t);
315   void RenderWaveMap(const uint8_t*, int16_t*, size_t);
316   void RenderWaveLine(const uint8_t*, int16_t*, size_t);
317   void RenderWaveParaphonic(const uint8_t*, int16_t*, size_t);
318 
319   void RenderTwinPeaksNoise(const uint8_t*, int16_t*, size_t);
320   void RenderFilteredNoise(const uint8_t*, int16_t*, size_t);
321   void RenderClockedNoise(const uint8_t*, int16_t*, size_t);
322   void RenderGranularCloud(const uint8_t*, int16_t*, size_t);
323   void RenderParticleNoise(const uint8_t*, int16_t*, size_t);
324 
325   void RenderDigitalModulation(const uint8_t*, int16_t*, size_t);
326   void RenderKick(const uint8_t*, int16_t*, size_t);
327   void RenderSnare(const uint8_t*, int16_t*, size_t);
328   void RenderCymbal(const uint8_t*, int16_t*, size_t);
329   void RenderQuestionMark(const uint8_t*, int16_t*, size_t);
330 
331   // void RenderYourAlgo(const uint8_t*, int16_t*, size_t);
332 
333   uint32_t ComputePhaseIncrement(int16_t midi_pitch);
334   uint32_t ComputeDelay(int16_t midi_pitch);
335   int16_t InterpolateFormantParameter(
336       const int16_t table[][kNumFormants][kNumFormants],
337       int16_t x,
338       int16_t y,
339       uint8_t formant);
340 
341   uint32_t phase_;
342   uint32_t phase_increment_;
343   uint32_t delay_;
344 
345   int16_t parameter_[2];
346   int16_t previous_parameter_[2];
347   int32_t smoothed_parameter_;
348   int16_t pitch_;
349 
350   uint8_t active_voice_;
351 
352   bool init_;
353   bool strike_;
354 
355   DigitalOscillatorShape shape_;
356   DigitalOscillatorShape previous_shape_;
357   DigitalOscillatorState state_;
358 
359   Excitation pulse_[4];
360   Svf svf_[3];
361 
362   union {
363     int16_t comb[kCombDelayLength];
364     int16_t ks[1025 * 4];
365     struct {
366       int8_t bridge[kWGBridgeLength];
367       int8_t neck[kWGNeckLength];
368     } bowed;
369     int16_t bore[kWGBoreLength];
370     struct {
371       int8_t jet[kWGJetLength];
372       int8_t bore[kWGFBoreLength];
373     } fluted;
374   } delay_lines_;
375 
376   static RenderFn fn_table_[];
377 
378   DISALLOW_COPY_AND_ASSIGN(DigitalOscillator);
379 };
380 
381 }  // namespace braids
382 
383 #endif // BRAIDS_DIGITAL_OSCILLATOR_H_
384