Test2.cpp (7208B)
1 2 #include <math.h> 3 #include <algorithm> 4 5 #include "Test2.hpp" 6 #include "pitch.hpp" 7 8 void Test2::reset() { 9 } 10 11 void Test2::processAll(const ProcessArgs& args) { 12 if (!outputs[OUT_OUTPUT].isConnected()) { 13 return; 14 } 15 16 #ifdef COMPLEX_BIQUAD 17 _complexBiquad.setComplexParams( 18 params[PARAM1B_PARAM].getValue(), 19 params[PARAM2A_PARAM].getValue(), 20 params[PARAM2B_PARAM].getValue() * M_PI, 21 std::min(params[PARAM3A_PARAM].getValue(), 0.9f), 22 params[PARAM3B_PARAM].getValue() * M_PI 23 ); 24 float in = 0.0f; 25 if (inputs[IN_INPUT].isConnected()) { 26 in = inputs[IN_INPUT].getVoltage(); 27 } 28 outputs[OUT_OUTPUT].setVoltage(_complexBiquad.next(in)); 29 30 #elif MULTIPOLE 31 ++_steps; 32 if (_steps >= maxSteps) { 33 _steps = 0; 34 35 _filter.setParams( 36 params[PARAM2A_PARAM].getValue() <= 0.5f ? MultipoleFilter::LP_TYPE : MultipoleFilter::HP_TYPE, 37 2 * clamp((int)(params[PARAM1B_PARAM].getValue() * (MultipoleFilter::maxPoles / 2)), 1, MultipoleFilter::maxPoles / 2), 38 APP->engine->getSampleRate(), 39 params[PARAM1A_PARAM].getValue() * APP->engine->getSampleRate() / 2.0f, 40 params[PARAM2B_PARAM].getValue() * MultipoleFilter::maxRipple 41 ); 42 // _filter.setParams( 43 // MultipoleFilter::HP_TYPE, 44 // 4, 45 // APP->engine->getSampleRate(), 46 // 0.1f * APP->engine->getSampleRate(), 47 // 0.1f 48 // ); 49 } 50 float in = 0.0f; 51 if (inputs[IN_INPUT].isConnected()) { 52 in = inputs[IN_INPUT].getVoltage(); 53 } 54 outputs[OUT_OUTPUT].setVoltage(_filter.next(in)); 55 56 #elif ADSR_ENVELOPE 57 if (outputs[OUT_OUTPUT].isConnected()) { 58 _adsr.setSampleRate(APP->engine->getSampleRate()); 59 if (inputs[IN_INPUT].isConnected()) { 60 _trigger.process(inputs[IN_INPUT].getVoltage()); 61 } 62 _adsr.setGate(_trigger.isHigh()); 63 _adsr.setAttack(powf(params[PARAM1A_PARAM].getValue(), 2.0f) * 10.0f); 64 _adsr.setDecay(powf(params[PARAM1B_PARAM].getValue(), 2.0f) * 10.0f); 65 _adsr.setSustain(params[PARAM2A_PARAM].getValue()); 66 _adsr.setRelease(powf(params[PARAM2B_PARAM].getValue(), 2.0f) * 10.0f); 67 float attackShape = params[PARAM3A_PARAM].getValue(); 68 if (attackShape < 0.5f) { 69 attackShape += 0.5f; 70 } 71 else { 72 attackShape -= 0.5; 73 attackShape *= 2.0f; 74 attackShape += 1.0f; 75 } 76 float decayShape = params[PARAM3B_PARAM].getValue(); 77 if (decayShape < 0.5f) { 78 decayShape += 0.5f; 79 } 80 else { 81 decayShape -= 0.5; 82 decayShape *= 2.0f; 83 decayShape += 1.0f; 84 } 85 _adsr.setShapes(attackShape, 1.0f / decayShape, 1.0f / decayShape); // FIXME: inversions here untested 86 outputs[OUT_OUTPUT].setVoltage(_adsr.next() * 10.0f); 87 } 88 89 #elif LIMITER 90 float shape = params[PARAM1A_PARAM].getValue() * 5.0f; 91 float knee = params[PARAM2A_PARAM].getValue() * 10.0f; 92 float limit = params[PARAM2B_PARAM].getValue() * 15.0f; 93 float scale = params[PARAM1B_PARAM].getValue() * 2.0f + 1.0f; 94 _limiter.setParams(shape, knee, limit, scale); 95 outputs[OUT_OUTPUT].setVoltage(_limiter.next(inputs[IN_INPUT].getVoltage())); 96 97 #elif CHIRP 98 float sr = APP->engine->getSampleRate(); 99 _phasor.setSampleRate(sr); 100 101 float f1 = params[PARAM1A_PARAM].getValue(); 102 f1 *= f1; 103 f1 *= sr * 0.5f * std::min(f1, 0.99f); 104 f1 = std::max(10.0f, f1); 105 float f2 = params[PARAM1B_PARAM].getValue(); 106 f2 *= f2; 107 f2 *= sr * 0.5f * std::min(f2, 0.99f); 108 f2 = std::max(10.0f, f2); 109 float T = std::max(0.001f, params[PARAM2A_PARAM].getValue()); // seconds 110 bool linear = params[PARAM2B_PARAM].getValue() < 0.5f; 111 112 _time = _time * (float)(_time < T); 113 114 // formulas from https://en.wikipedia.org/wiki/Chirp 115 float out = 0.0f; 116 if (linear) { 117 float c = (f2 - f1) / T; 118 float phase = 2.0f * M_PI * (0.5f * c * _time * _time + f1 * _time); 119 // out = sinf(phase); 120 out = _phasor.nextForPhase(Phasor::radiansToPhase(phase)); 121 } 122 else { 123 float k = powf(f2 / f1, 1.0f / T); 124 float phase = 2.0f * M_PI * f1 * ((powf(k, _time) - 1.0f) / logf(k)); 125 // out = sinf(phase); 126 out = _phasor.nextForPhase(Phasor::radiansToPhase(phase)); 127 } 128 outputs[OUT_OUTPUT].setVoltage(out * 5.0f); 129 130 _time += 1.0f / sr; 131 132 #elif CHIRP2 133 float sr = APP->engine->getSampleRate(); 134 _chirp.setSampleRate(sr); 135 136 float f1 = params[PARAM1A_PARAM].getValue(); 137 f1 *= f1; 138 f1 *= sr * 0.5f * std::min(f1, 0.99f); 139 f1 = std::max(10.0f, f1); 140 float f2 = params[PARAM1B_PARAM].getValue(); 141 f2 *= f2; 142 f2 *= sr * 0.5f * std::min(f2, 0.99f); 143 f2 = std::max(10.0f, f2); 144 float T = ChirpOscillator::minTimeSeconds + params[PARAM2A_PARAM].getValue() * (10.0f - ChirpOscillator::minTimeSeconds); 145 bool linear = params[PARAM2B_PARAM].getValue() < 0.5f; 146 _chirp.setParams(f1, f2, T, linear); 147 outputs[OUT_OUTPUT].setVoltage(_chirp.next() * 5.0f); 148 149 if (_chirp.isCycleComplete()) { 150 _pulse.trigger(0.001f); 151 } 152 outputs[OUT2_OUTPUT].setVoltage(_pulse.process(1.0f / sr) * 5.0f); 153 #endif 154 } 155 156 // float Test2::oscillatorPitch1A() { 157 // if (inputs[CV1A_INPUT].isConnected()) { 158 // return cvToFrequency(inputs[CV1A_INPUT].getVoltage()); 159 // } 160 // return 10000.0 * powf(params[PARAM1_PARAM].getValue(), 2.0); 161 // } 162 163 164 struct Test2Widget : BGModuleWidget { 165 static constexpr int hp = 6; 166 167 Test2Widget(Test2* module) { 168 setModule(module); 169 box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); 170 setPanel(box.size, "Test2"); 171 createScrews(); 172 173 // generated by svg_widgets.rb 174 auto param1aParamPosition = Vec(9.5, 38.5); 175 auto param2aParamPosition = Vec(9.5, 138.5); 176 auto param3aParamPosition = Vec(9.5, 238.5); 177 auto param1bParamPosition = Vec(54.5, 38.5); 178 auto param2bParamPosition = Vec(54.5, 138.5); 179 auto param3bParamPosition = Vec(54.5, 238.5); 180 181 auto cv1aInputPosition = Vec(10.5, 78.0); 182 auto cv2aInputPosition = Vec(10.5, 178.0); 183 auto cv3aInputPosition = Vec(10.5, 278.0); 184 auto cv1bInputPosition = Vec(55.5, 78.0); 185 auto cv2bInputPosition = Vec(55.5, 178.0); 186 auto cv3bInputPosition = Vec(55.5, 278.0); 187 auto inInputPosition = Vec(10.5, 323.0); 188 189 auto outOutputPosition = Vec(55.5, 323.0); 190 // end generated by svg_widgets.rb 191 192 addParam(createParam<Knob26>(param1aParamPosition, module, Test2::PARAM1A_PARAM)); 193 addParam(createParam<Knob26>(param2aParamPosition, module, Test2::PARAM2A_PARAM)); 194 addParam(createParam<Knob26>(param3aParamPosition, module, Test2::PARAM3A_PARAM)); 195 addParam(createParam<Knob26>(param1bParamPosition, module, Test2::PARAM1B_PARAM)); 196 addParam(createParam<Knob26>(param2bParamPosition, module, Test2::PARAM2B_PARAM)); 197 addParam(createParam<Knob26>(param3bParamPosition, module, Test2::PARAM3B_PARAM)); 198 199 addInput(createInput<Port24>(cv1aInputPosition, module, Test2::CV1A_INPUT)); 200 addInput(createInput<Port24>(cv2aInputPosition, module, Test2::CV2A_INPUT)); 201 addInput(createInput<Port24>(cv3aInputPosition, module, Test2::CV3A_INPUT)); 202 addInput(createInput<Port24>(cv1bInputPosition, module, Test2::CV1B_INPUT)); 203 addInput(createInput<Port24>(cv2bInputPosition, module, Test2::CV2B_INPUT)); 204 addInput(createInput<Port24>(cv3bInputPosition, module, Test2::CV3B_INPUT)); 205 addInput(createInput<Port24>(inInputPosition, module, Test2::IN_INPUT)); 206 207 addOutput(createOutput<Port24>(outOutputPosition, module, Test2::OUT_OUTPUT)); 208 addOutput(createOutput<Port24>(Vec(outOutputPosition.x, outOutputPosition.y + 10), module, Test2::OUT2_OUTPUT)); 209 } 210 }; 211 212 Model* modelTest2 = bogaudio::createModel<Test2, Test2Widget>("Bogaudio-Test2", "TEST2", "test2");