1 /* 2 ** Surge Synthesizer is Free and Open Source Software 3 ** 4 ** Surge is made available under the Gnu General Public License, v3.0 5 ** https://www.gnu.org/licenses/gpl-3.0.en.html 6 ** 7 ** Copyright 2004-2021 by various individuals as described by the Git transaction log 8 ** 9 ** All source at: https://github.com/surge-synthesizer/surge.git 10 ** 11 ** Surge was a commercial product from 2004-2018, with Copyright and ownership 12 ** in that period held by Claes Johanson at Vember Audio. Claes made Surge 13 ** open source in September 2018. 14 */ 15 16 #include "OscillatorBase.h" 17 #include "DspUtilities.h" 18 #include "OscillatorCommonFunctions.h" 19 20 class AliasOscillator : public Oscillator 21 { 22 public: 23 enum ao_params 24 { 25 ao_wave = 0, 26 ao_wrap, 27 ao_mask, 28 ao_threshold, 29 ao_bit_depth, 30 31 ao_unison_detune = 5, 32 ao_unison_voices, 33 }; 34 35 enum ao_waves 36 { 37 aow_sine, 38 aow_ramp, 39 aow_pulse, 40 aow_noise, 41 42 aow_mem_alias, 43 aow_mem_oscdata, 44 aow_mem_scenedata, 45 aow_mem_dawextra, 46 aow_mem_stepseqdata, 47 48 aow_audiobuffer, 49 50 aow_sine_tx2, 51 aow_sine_tx3, 52 aow_sine_tx4, 53 aow_sine_tx5, 54 aow_sine_tx6, 55 aow_sine_tx7, 56 aow_sine_tx8, 57 58 aow_additive, 59 60 ao_n_waves 61 }; 62 63 static constexpr int n_additive_partials = 16; 64 AliasOscillator(SurgeStorage * s,OscillatorStorage * o,pdata * p)65 AliasOscillator(SurgeStorage *s, OscillatorStorage *o, pdata *p) : Oscillator(s, o, p) 66 { 67 for (auto u = 0; u < MAX_UNISON; ++u) 68 { 69 phase[u] = 0; 70 mixL[u] = 1.f; 71 mixR[u] = 1.f; 72 } 73 } 74 75 virtual void init(float pitch, bool is_display = false, bool nonzero_init_drift = true); init_ctrltypes(int scene,int oscnum)76 virtual void init_ctrltypes(int scene, int oscnum) { init_ctrltypes(); }; 77 virtual void init_ctrltypes(); 78 virtual void init_default_values(); init_extra_config()79 virtual void init_extra_config() 80 { 81 oscdata->extraConfig.nData = 16; 82 for (auto i = 0; i < oscdata->extraConfig.nData; ++i) 83 oscdata->extraConfig.data[i] = 1.f / (i + 1); 84 } 85 virtual void process_block(float pitch, float drift = 0.f, bool stereo = false, bool FM = false, 86 float FMdepth = 0.f); 87 template <bool do_FM, bool do_bitcrush, AliasOscillator::ao_waves wavetype> 88 void process_block_internal(const float pitch, const float drift, const bool stereo, 89 const float fmdepthV, const float crush_bits); 90 91 lag<float, true> fmdepth; 92 93 // character filter 94 Surge::Oscillator::CharacterFilter<float> charFilt; 95 96 int n_unison = 1; 97 uint32_t phase[MAX_UNISON]; 98 float unisonOffsets[MAX_UNISON]; 99 float mixL[MAX_UNISON], mixR[MAX_UNISON]; 100 uint8_t dynamic_wavetable[256]; 101 unsigned dynamic_wavetable_sleep = 0; // blocks to wait before recalculating dynamic wavetable 102 103 struct UInt8RNG 104 { 105 // Based on http://en.wikipedia.org/wiki/Xorshift 106 // and inspired by https://github.com/edrosten/8bit_rng and 107 // http://www.donnelly-house.net/programming/cdp1802/8bitPRNGtest.html 108 109 uint8_t x, y, z, a; 110 uint8_t stepCount; UInt8RNGUInt8RNG111 UInt8RNG() : x(21), y(229), z(181), a(rand() & 0xFF), stepCount(0) {} 112 stepUInt8RNG113 inline uint8_t step() 114 { 115 uint8_t t = x ^ ((x << 3U) & 0xFF); 116 x = y; 117 y = z; 118 z = a; 119 a = a ^ (a >> 5U) ^ (t ^ (t >> 2U)); 120 return a; 121 } stepToUInt8RNG122 inline uint8_t stepTo(uint8_t sc, uint8_t every) 123 { 124 uint8_t r = a; 125 while (stepCount != sc) 126 { 127 stepCount++; 128 if (stepCount % every == 0) 129 r = step(); 130 } 131 return r; 132 } 133 }; 134 UInt8RNG urng8[MAX_UNISON]; 135 136 Surge::Oscillator::DriftLFO driftLFO[MAX_UNISON]; 137 }; 138 139 struct Always255CountedSet 140 : public CountedSetUserData // Something to feed to a ct_countedset_percent control 141 { getCountedSetSizeAlways255CountedSet142 virtual int getCountedSetSize() { return 255; } 143 }; 144 145 const Always255CountedSet ALWAYS255COUNTEDSET; 146 147 extern const char *ao_type_names[]; 148