@@ -26,15 +26,14 @@ struct _8vert : Module { | |||
} | |||
} | |||
void step() override { | |||
float deltaTime = APP->engine->getSampleTime(); | |||
void process(const ProcessArgs &args) override { | |||
float lastIn = 10.f; | |||
for (int i = 0; i < 8; i++) { | |||
lastIn = inputs[i].getNormalVoltage(lastIn); | |||
float out = lastIn * params[i].value; | |||
outputs[i].value = out; | |||
lights[2*i + 0].setSmoothBrightness(out / 5.f, deltaTime); | |||
lights[2*i + 1].setSmoothBrightness(-out / 5.f, deltaTime); | |||
lights[2*i + 0].setSmoothBrightness(out / 5.f, args.sampleTime); | |||
lights[2*i + 1].setSmoothBrightness(-out / 5.f, args.sampleTime); | |||
} | |||
} | |||
}; | |||
@@ -42,7 +42,7 @@ struct ADSR : Module { | |||
params[RELEASE_PARAM].config(0.f, 1.f, 0.5f, "Release"); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
float attack = clamp(params[ATTACK_PARAM].value + inputs[ATTACK_INPUT].value / 10.f, 0.f, 1.f); | |||
float decay = clamp(params[DECAY_PARAM].value + inputs[DECAY_INPUT].value / 10.f, 0.f, 1.f); | |||
float sustain = clamp(params[SUSTAIN_PARAM].value + inputs[SUSTAIN_INPUT].value / 10.f, 0.f, 1.f); | |||
@@ -62,7 +62,7 @@ struct ADSR : Module { | |||
env = sustain; | |||
} | |||
else { | |||
env += std::pow(base, 1 - decay) / maxTime * (sustain - env) * APP->engine->getSampleTime(); | |||
env += std::pow(base, 1 - decay) / maxTime * (sustain - env) * args.sampleTime; | |||
} | |||
} | |||
else { | |||
@@ -72,7 +72,7 @@ struct ADSR : Module { | |||
env = 1.f; | |||
} | |||
else { | |||
env += std::pow(base, 1 - attack) / maxTime * (1.01f - env) * APP->engine->getSampleTime(); | |||
env += std::pow(base, 1 - attack) / maxTime * (1.01f - env) * args.sampleTime; | |||
} | |||
if (env >= 1.f) { | |||
env = 1.f; | |||
@@ -86,7 +86,7 @@ struct ADSR : Module { | |||
env = 0.f; | |||
} | |||
else { | |||
env += std::pow(base, 1 - release) / maxTime * (0.f - env) * APP->engine->getSampleTime(); | |||
env += std::pow(base, 1 - release) / maxTime * (0.f - env) * args.sampleTime; | |||
} | |||
decaying = false; | |||
} | |||
@@ -47,7 +47,7 @@ struct Delay : Module { | |||
src_delete(src); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
// Get input to delay block | |||
float in = inputs[IN_INPUT].value; | |||
float feedback = clamp(params[FEEDBACK_PARAM].value + inputs[FEEDBACK_INPUT].value / 10.0f, 0.0f, 1.0f); | |||
@@ -56,7 +56,7 @@ struct Delay : Module { | |||
// Compute delay time in seconds | |||
float delay = 1e-3 * std::pow(10.0f / 1e-3, clamp(params[TIME_PARAM].value + inputs[TIME_INPUT].value / 10.0f, 0.0f, 1.0f)); | |||
// Number of delay samples | |||
float index = delay * APP->engine->getSampleRate(); | |||
float index = delay * args.sampleRate; | |||
// Push dry sample into history buffer | |||
if (!historyBuffer.full()) { | |||
@@ -93,11 +93,11 @@ struct Delay : Module { | |||
// TODO Make it sound better | |||
float color = clamp(params[COLOR_PARAM].value + inputs[COLOR_INPUT].value / 10.0f, 0.0f, 1.0f); | |||
float lowpassFreq = 10000.0f * std::pow(10.0f, clamp(2.0f*color, 0.0f, 1.0f)); | |||
lowpassFilter.setCutoff(lowpassFreq / APP->engine->getSampleRate()); | |||
lowpassFilter.setCutoff(lowpassFreq / args.sampleRate); | |||
lowpassFilter.process(wet); | |||
wet = lowpassFilter.lowpass(); | |||
float highpassFreq = 10.0f * std::pow(100.0f, clamp(2.0f*color - 1.0f, 0.0f, 1.0f)); | |||
highpassFilter.setCutoff(highpassFreq / APP->engine->getSampleRate()); | |||
highpassFilter.setCutoff(highpassFreq / args.sampleRate); | |||
highpassFilter.process(wet); | |||
wet = highpassFilter.highpass(); | |||
@@ -107,13 +107,12 @@ struct LFO : Module { | |||
params[PWM_PARAM].config(0.f, 1.f, 0.f); | |||
} | |||
void step() override { | |||
float deltaTime = APP->engine->getSampleTime(); | |||
void process(const ProcessArgs &args) override { | |||
oscillator.setPitch(params[FREQ_PARAM].value + params[FM1_PARAM].value * inputs[FM1_INPUT].value + params[FM2_PARAM].value * inputs[FM2_INPUT].value); | |||
oscillator.setPulseWidth(params[PW_PARAM].value + params[PWM_PARAM].value * inputs[PW_INPUT].value / 10.f); | |||
oscillator.offset = (params[OFFSET_PARAM].value > 0.f); | |||
oscillator.invert = (params[INVERT_PARAM].value <= 0.f); | |||
oscillator.step(deltaTime); | |||
oscillator.step(args.sampleTime); | |||
oscillator.setReset(inputs[RESET_INPUT].value); | |||
outputs[SIN_OUTPUT].value = 5.f * oscillator.sin(); | |||
@@ -121,8 +120,8 @@ struct LFO : Module { | |||
outputs[SAW_OUTPUT].value = 5.f * oscillator.saw(); | |||
outputs[SQR_OUTPUT].value = 5.f * oscillator.sqr(); | |||
lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), deltaTime); | |||
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime); | |||
lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), args.sampleTime); | |||
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime); | |||
} | |||
}; | |||
@@ -202,8 +201,8 @@ struct LFO2 : Module { | |||
params[FM_PARAM].config(0.f, 1.f, 0.5f); | |||
} | |||
void step() override { | |||
float deltaTime = APP->engine->getSampleTime(); | |||
void process(const ProcessArgs &args) override { | |||
float deltaTime = args.sampleTime; | |||
oscillator.setPitch(params[FREQ_PARAM].value + params[FM_PARAM].value * inputs[FM_INPUT].value); | |||
oscillator.offset = (params[OFFSET_PARAM].value > 0.f); | |||
oscillator.invert = (params[INVERT_PARAM].value <= 0.f); | |||
@@ -24,7 +24,7 @@ struct Merge : Module { | |||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
int lastChannel = -1; | |||
for (int c = 0; c < 16; c++) { | |||
if (inputs[MONO_INPUTS + c].isConnected()) { | |||
@@ -34,7 +34,7 @@ struct Mutes : Module { | |||
onReset(); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
float out = 0.f; | |||
for (int i = 0; i < NUM_CHANNELS; i++) { | |||
if (muteTrigger[i].process(params[MUTE_PARAM + i].value)) | |||
@@ -117,9 +117,7 @@ struct SEQ3 : Module { | |||
this->index = 0; | |||
} | |||
void step() override { | |||
float deltaTime = APP->engine->getSampleTime(); | |||
void process(const ProcessArgs &args) override { | |||
// Run | |||
if (runningTrigger.process(params[RUN_PARAM].value)) { | |||
running = !running; | |||
@@ -137,7 +135,7 @@ struct SEQ3 : Module { | |||
else { | |||
// Internal clock | |||
float clockTime = std::pow(2.0f, params[CLOCK_PARAM].value + inputs[CLOCK_INPUT].value); | |||
phase += clockTime * deltaTime; | |||
phase += clockTime * args.sampleTime; | |||
if (phase >= 1.0f) { | |||
setIndex(index + 1); | |||
} | |||
@@ -156,7 +154,7 @@ struct SEQ3 : Module { | |||
gates[i] = !gates[i]; | |||
} | |||
outputs[GATE_OUTPUT + i].value = (running && gateIn && i == index && gates[i]) ? 10.0f : 0.0f; | |||
lights[GATE_LIGHTS + i].setSmoothBrightness((gateIn && i == index) ? (gates[i] ? 1.f : 0.33) : (gates[i] ? 0.66 : 0.0), deltaTime); | |||
lights[GATE_LIGHTS + i].setSmoothBrightness((gateIn && i == index) ? (gates[i] ? 1.f : 0.33) : (gates[i] ? 0.66 : 0.0), args.sampleTime); | |||
} | |||
// Outputs | |||
@@ -165,8 +163,8 @@ struct SEQ3 : Module { | |||
outputs[ROW3_OUTPUT].value = params[ROW3_PARAM + index].value; | |||
outputs[GATES_OUTPUT].value = (gateIn && gates[index]) ? 10.0f : 0.0f; | |||
lights[RUNNING_LIGHT].value = (running); | |||
lights[RESET_LIGHT].setSmoothBrightness(resetTrigger.isHigh(), deltaTime); | |||
lights[GATES_LIGHT].setSmoothBrightness(gateIn, deltaTime); | |||
lights[RESET_LIGHT].setSmoothBrightness(resetTrigger.isHigh(), args.sampleTime); | |||
lights[GATES_LIGHT].setSmoothBrightness(gateIn, args.sampleTime); | |||
lights[ROW_LIGHTS].value = outputs[ROW1_OUTPUT].value / 10.0f; | |||
lights[ROW_LIGHTS + 1].value = outputs[ROW2_OUTPUT].value / 10.0f; | |||
lights[ROW_LIGHTS + 2].value = outputs[ROW3_OUTPUT].value / 10.0f; | |||
@@ -57,7 +57,7 @@ struct Scope : Module { | |||
params[EXTERNAL_PARAM].config(0.0f, 1.0f, 0.0f); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
// Modes | |||
if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { | |||
lissajous = !lissajous; | |||
@@ -73,7 +73,7 @@ struct Scope : Module { | |||
// Compute time | |||
float deltaTime = std::pow(2.0f, -params[TIME_PARAM].value); | |||
int frameCount = (int) std::ceil(deltaTime * APP->engine->getSampleRate()); | |||
int frameCount = (int) std::ceil(deltaTime * args.sampleRate); | |||
// Add frame to buffer | |||
if (bufferIndex < BUFFER_SIZE) { | |||
@@ -105,12 +105,12 @@ struct Scope : Module { | |||
// Reset if triggered | |||
float holdTime = 0.1f; | |||
if (resetTrigger.process(rescale(gate, params[TRIG_PARAM].value - 0.1f, params[TRIG_PARAM].value, 0.f, 1.f)) || (frameIndex >= APP->engine->getSampleRate() * holdTime)) { | |||
if (resetTrigger.process(rescale(gate, params[TRIG_PARAM].value - 0.1f, params[TRIG_PARAM].value, 0.f, 1.f)) || (frameIndex >= args.sampleRate * holdTime)) { | |||
bufferIndex = 0; frameIndex = 0; return; | |||
} | |||
// Reset if we've waited too long | |||
if (frameIndex >= APP->engine->getSampleRate() * holdTime) { | |||
if (frameIndex >= args.sampleRate * holdTime) { | |||
bufferIndex = 0; frameIndex = 0; return; | |||
} | |||
} | |||
@@ -170,13 +170,13 @@ struct ScopeDisplay : TransparentWidget { | |||
font = APP->window->loadFont(asset::plugin(pluginInstance, "res/sudo/Sudo.ttf")); | |||
} | |||
void drawWaveform(const DrawContext &ctx, float *valuesX, float *valuesY) { | |||
void drawWaveform(const DrawArgs &args, float *valuesX, float *valuesY) { | |||
if (!valuesX) | |||
return; | |||
nvgSave(ctx.vg); | |||
nvgSave(args.vg); | |||
Rect b = Rect(Vec(0, 15), box.size.minus(Vec(0, 15*2))); | |||
nvgScissor(ctx.vg, b.pos.x, b.pos.y, b.size.x, b.size.y); | |||
nvgBeginPath(ctx.vg); | |||
nvgScissor(args.vg, b.pos.x, b.pos.y, b.size.x, b.size.y); | |||
nvgBeginPath(args.vg); | |||
// Draw maximum display left to right | |||
for (int i = 0; i < BUFFER_SIZE; i++) { | |||
float x, y; | |||
@@ -192,71 +192,71 @@ struct ScopeDisplay : TransparentWidget { | |||
p.x = b.pos.x + b.size.x * x; | |||
p.y = b.pos.y + b.size.y * (1.0f - y); | |||
if (i == 0) | |||
nvgMoveTo(ctx.vg, p.x, p.y); | |||
nvgMoveTo(args.vg, p.x, p.y); | |||
else | |||
nvgLineTo(ctx.vg, p.x, p.y); | |||
nvgLineTo(args.vg, p.x, p.y); | |||
} | |||
nvgLineCap(ctx.vg, NVG_ROUND); | |||
nvgMiterLimit(ctx.vg, 2.0f); | |||
nvgStrokeWidth(ctx.vg, 1.5f); | |||
nvgGlobalCompositeOperation(ctx.vg, NVG_LIGHTER); | |||
nvgStroke(ctx.vg); | |||
nvgResetScissor(ctx.vg); | |||
nvgRestore(ctx.vg); | |||
nvgLineCap(args.vg, NVG_ROUND); | |||
nvgMiterLimit(args.vg, 2.0f); | |||
nvgStrokeWidth(args.vg, 1.5f); | |||
nvgGlobalCompositeOperation(args.vg, NVG_LIGHTER); | |||
nvgStroke(args.vg); | |||
nvgResetScissor(args.vg); | |||
nvgRestore(args.vg); | |||
} | |||
void drawTrig(const DrawContext &ctx, float value) { | |||
void drawTrig(const DrawArgs &args, float value) { | |||
Rect b = Rect(Vec(0, 15), box.size.minus(Vec(0, 15*2))); | |||
nvgScissor(ctx.vg, b.pos.x, b.pos.y, b.size.x, b.size.y); | |||
nvgScissor(args.vg, b.pos.x, b.pos.y, b.size.x, b.size.y); | |||
value = value / 2.0f + 0.5f; | |||
Vec p = Vec(box.size.x, b.pos.y + b.size.y * (1.0f - value)); | |||
// Draw line | |||
nvgStrokeColor(ctx.vg, nvgRGBA(0xff, 0xff, 0xff, 0x10)); | |||
nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x10)); | |||
{ | |||
nvgBeginPath(ctx.vg); | |||
nvgMoveTo(ctx.vg, p.x - 13, p.y); | |||
nvgLineTo(ctx.vg, 0, p.y); | |||
nvgClosePath(ctx.vg); | |||
nvgBeginPath(args.vg); | |||
nvgMoveTo(args.vg, p.x - 13, p.y); | |||
nvgLineTo(args.vg, 0, p.y); | |||
nvgClosePath(args.vg); | |||
} | |||
nvgStroke(ctx.vg); | |||
nvgStroke(args.vg); | |||
// Draw indicator | |||
nvgFillColor(ctx.vg, nvgRGBA(0xff, 0xff, 0xff, 0x60)); | |||
nvgFillColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x60)); | |||
{ | |||
nvgBeginPath(ctx.vg); | |||
nvgMoveTo(ctx.vg, p.x - 2, p.y - 4); | |||
nvgLineTo(ctx.vg, p.x - 9, p.y - 4); | |||
nvgLineTo(ctx.vg, p.x - 13, p.y); | |||
nvgLineTo(ctx.vg, p.x - 9, p.y + 4); | |||
nvgLineTo(ctx.vg, p.x - 2, p.y + 4); | |||
nvgClosePath(ctx.vg); | |||
nvgBeginPath(args.vg); | |||
nvgMoveTo(args.vg, p.x - 2, p.y - 4); | |||
nvgLineTo(args.vg, p.x - 9, p.y - 4); | |||
nvgLineTo(args.vg, p.x - 13, p.y); | |||
nvgLineTo(args.vg, p.x - 9, p.y + 4); | |||
nvgLineTo(args.vg, p.x - 2, p.y + 4); | |||
nvgClosePath(args.vg); | |||
} | |||
nvgFill(ctx.vg); | |||
nvgFill(args.vg); | |||
nvgFontSize(ctx.vg, 9); | |||
nvgFontFaceId(ctx.vg, font->handle); | |||
nvgFillColor(ctx.vg, nvgRGBA(0x1e, 0x28, 0x2b, 0xff)); | |||
nvgText(ctx.vg, p.x - 8, p.y + 3, "T", NULL); | |||
nvgResetScissor(ctx.vg); | |||
nvgFontSize(args.vg, 9); | |||
nvgFontFaceId(args.vg, font->handle); | |||
nvgFillColor(args.vg, nvgRGBA(0x1e, 0x28, 0x2b, 0xff)); | |||
nvgText(args.vg, p.x - 8, p.y + 3, "T", NULL); | |||
nvgResetScissor(args.vg); | |||
} | |||
void drawStats(const DrawContext &ctx, Vec pos, const char *title, Stats *stats) { | |||
nvgFontSize(ctx.vg, 13); | |||
nvgFontFaceId(ctx.vg, font->handle); | |||
nvgTextLetterSpacing(ctx.vg, -2); | |||
void drawStats(const DrawArgs &args, Vec pos, const char *title, Stats *stats) { | |||
nvgFontSize(args.vg, 13); | |||
nvgFontFaceId(args.vg, font->handle); | |||
nvgTextLetterSpacing(args.vg, -2); | |||
nvgFillColor(ctx.vg, nvgRGBA(0xff, 0xff, 0xff, 0x40)); | |||
nvgText(ctx.vg, pos.x + 6, pos.y + 11, title, NULL); | |||
nvgFillColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x40)); | |||
nvgText(args.vg, pos.x + 6, pos.y + 11, title, NULL); | |||
nvgFillColor(ctx.vg, nvgRGBA(0xff, 0xff, 0xff, 0x80)); | |||
nvgFillColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x80)); | |||
char text[128]; | |||
snprintf(text, sizeof(text), "pp % 06.2f max % 06.2f min % 06.2f", stats->vpp, stats->vmax, stats->vmin); | |||
nvgText(ctx.vg, pos.x + 22, pos.y + 11, text, NULL); | |||
nvgText(args.vg, pos.x + 22, pos.y + 11, text, NULL); | |||
} | |||
void draw(const DrawContext &ctx) override { | |||
void draw(const DrawArgs &args) override { | |||
if (!module) | |||
return; | |||
@@ -280,25 +280,25 @@ struct ScopeDisplay : TransparentWidget { | |||
if (module->lissajous) { | |||
// X x Y | |||
if (module->inputs[Scope::X_INPUT].active || module->inputs[Scope::Y_INPUT].active) { | |||
nvgStrokeColor(ctx.vg, nvgRGBA(0x9f, 0xe4, 0x36, 0xc0)); | |||
drawWaveform(ctx, valuesX, valuesY); | |||
nvgStrokeColor(args.vg, nvgRGBA(0x9f, 0xe4, 0x36, 0xc0)); | |||
drawWaveform(args, valuesX, valuesY); | |||
} | |||
} | |||
else { | |||
// Y | |||
if (module->inputs[Scope::Y_INPUT].active) { | |||
nvgStrokeColor(ctx.vg, nvgRGBA(0xe1, 0x02, 0x78, 0xc0)); | |||
drawWaveform(ctx, valuesY, NULL); | |||
nvgStrokeColor(args.vg, nvgRGBA(0xe1, 0x02, 0x78, 0xc0)); | |||
drawWaveform(args, valuesY, NULL); | |||
} | |||
// X | |||
if (module->inputs[Scope::X_INPUT].active) { | |||
nvgStrokeColor(ctx.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xc0)); | |||
drawWaveform(ctx, valuesX, NULL); | |||
nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xc0)); | |||
drawWaveform(args, valuesX, NULL); | |||
} | |||
float valueTrig = (module->params[Scope::TRIG_PARAM].value + offsetX) * gainX / 10.0f; | |||
drawTrig(ctx, valueTrig); | |||
drawTrig(args, valueTrig); | |||
} | |||
// Calculate and draw stats | |||
@@ -307,8 +307,8 @@ struct ScopeDisplay : TransparentWidget { | |||
statsX.calculate(module->bufferX); | |||
statsY.calculate(module->bufferY); | |||
} | |||
drawStats(ctx, Vec(0, 0), "X", &statsX); | |||
drawStats(ctx, Vec(0, box.size.y - 15), "Y", &statsY); | |||
drawStats(args, Vec(0, 0), "X", &statsX); | |||
drawStats(args, Vec(0, box.size.y - 15), "Y", &statsY); | |||
} | |||
}; | |||
@@ -37,7 +37,7 @@ struct SequentialSwitch : Module { | |||
} | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
// Determine current channel | |||
if (clockTrigger.process(inputs[CLOCK_INPUT].value / 2.f)) { | |||
channel++; | |||
@@ -24,7 +24,7 @@ struct Split : Module { | |||
int lightFrame = 0; | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
for (int c = 0; c < 16; c++) { | |||
float v = inputs[POLY_INPUT].getVoltage(c); | |||
outputs[MONO_OUTPUTS + c].setVoltage(v); | |||
@@ -22,15 +22,19 @@ struct Sum : Module { | |||
int frame = 0; | |||
dsp::VuMeter2 vuMeter; | |||
dsp::Counter vuCounter; | |||
dsp::Counter lightCounter; | |||
Sum() { | |||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||
params[LEVEL_PARAM].config(0.f, 1.f, 1.f, "Level", "%", 0.f, 100.f); | |||
vuMeter.lambda = 1 / 0.1f; | |||
vuCounter.setPeriod(16); | |||
lightCounter.setPeriod(256); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
int channels = inputs[POLY_INPUT].getChannels(); | |||
float sum = 0.f; | |||
for (int c = 0; c < channels; c++) { | |||
@@ -40,12 +44,12 @@ struct Sum : Module { | |||
sum *= params[LEVEL_PARAM].getValue(); | |||
outputs[MONO_OUTPUT].setVoltage(sum); | |||
if (frame % 16 == 0) { | |||
vuMeter.process(APP->engine->getSampleTime() * 16, sum / 10.f); | |||
if (vuCounter.process()) { | |||
vuMeter.process(args.sampleTime * vuCounter.period, sum / 10.f); | |||
} | |||
// Set channel lights infrequently | |||
if (frame % 256 == 0) { | |||
if (lightCounter.process()) { | |||
for (int c = 0; c < 16; c++) { | |||
bool active = (c < inputs[POLY_INPUT].getChannels()); | |||
lights[CHANNEL_LIGHTS + c].setBrightness(active); | |||
@@ -56,8 +60,6 @@ struct Sum : Module { | |||
lights[VU_LIGHTS + i].setBrightness(vuMeter.getBrightness(-3.f * i, -3.f * (i - 1))); | |||
} | |||
} | |||
frame++; | |||
} | |||
}; | |||
@@ -25,18 +25,17 @@ struct Unity : Module { | |||
bool merge = false; | |||
dsp::VuMeter2 vuMeters[2]; | |||
dsp::Counter vuCounter; | |||
dsp::Counter lightCounter; | |||
Unity() { | |||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||
params[AVG1_PARAM].config(0.0, 1.0, 0.0, "Ch 1 average mode"); | |||
params[AVG2_PARAM].config(0.0, 1.0, 0.0, "Ch 2 average mode"); | |||
vuCounter.setPeriod(256); | |||
lightCounter.setPeriod(256); | |||
} | |||
void step() override { | |||
float deltaTime = APP->engine->getSampleTime(); | |||
void process(const ProcessArgs &args) override { | |||
float mix[2] = {}; | |||
int count[2] = {}; | |||
@@ -65,10 +64,10 @@ struct Unity : Module { | |||
// Outputs | |||
outputs[MIX1_OUTPUT + 2 * i].value = mix[i]; | |||
outputs[INV1_OUTPUT + 2 * i].value = -mix[i]; | |||
vuMeters[i].process(deltaTime, mix[i] / 10.f); | |||
vuMeters[i].process(args.sampleTime, mix[i] / 10.f); | |||
} | |||
if (vuCounter.process()) { | |||
if (lightCounter.process()) { | |||
// Lights | |||
for (int i = 0; i < 2; i++) { | |||
lights[VU_LIGHTS + 5 * i + 0].setBrightness(vuMeters[i].getBrightness(0.f, 0.f)); | |||
@@ -38,7 +38,7 @@ struct VCA : Module { | |||
outputs[out].value = v; | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
stepChannel(IN1_INPUT, LEVEL1_PARAM, LIN1_INPUT, EXP1_INPUT, OUT1_OUTPUT); | |||
stepChannel(IN2_INPUT, LEVEL2_PARAM, LIN2_INPUT, EXP2_INPUT, OUT2_OUTPUT); | |||
} | |||
@@ -102,7 +102,7 @@ struct VCA_1 : Module { | |||
params[EXP_PARAM].config(0.0, 1.0, 1.0, "Response mode"); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
float cv = inputs[CV_INPUT].getNormalVoltage(10.f) / 10.f; | |||
if ((int) params[EXP_PARAM].value == 0) | |||
cv = std::pow(cv, 4.f); | |||
@@ -119,13 +119,13 @@ struct VCA_1VUKnob : SliderKnob { | |||
box.size = mm2px(Vec(10, 46)); | |||
} | |||
void draw(const DrawContext &ctx) override { | |||
void draw(const DrawArgs &args) override { | |||
float lastCv = module ? module->lastCv : 1.f; | |||
nvgBeginPath(ctx.vg); | |||
nvgRoundedRect(ctx.vg, 0, 0, box.size.x, box.size.y, 2.0); | |||
nvgFillColor(ctx.vg, nvgRGB(0, 0, 0)); | |||
nvgFill(ctx.vg); | |||
nvgBeginPath(args.vg); | |||
nvgRoundedRect(args.vg, 0, 0, box.size.x, box.size.y, 2.0); | |||
nvgFillColor(args.vg, nvgRGB(0, 0, 0)); | |||
nvgFill(args.vg); | |||
const int segs = 25; | |||
const Vec margin = Vec(3, 3); | |||
@@ -136,16 +136,16 @@ struct VCA_1VUKnob : SliderKnob { | |||
float segValue = clamp(value * segs - (segs - i - 1), 0.f, 1.f); | |||
float amplitude = value * lastCv; | |||
float segAmplitude = clamp(amplitude * segs - (segs - i - 1), 0.f, 1.f); | |||
nvgBeginPath(ctx.vg); | |||
nvgRect(ctx.vg, r.pos.x, r.pos.y + r.size.y / segs * i + 0.5, | |||
nvgBeginPath(args.vg); | |||
nvgRect(args.vg, r.pos.x, r.pos.y + r.size.y / segs * i + 0.5, | |||
r.size.x, r.size.y / segs - 1.0); | |||
if (segValue > 0.f) { | |||
nvgFillColor(ctx.vg, color::alpha(nvgRGBf(0.33, 0.33, 0.33), segValue)); | |||
nvgFill(ctx.vg); | |||
nvgFillColor(args.vg, color::alpha(nvgRGBf(0.33, 0.33, 0.33), segValue)); | |||
nvgFill(args.vg); | |||
} | |||
if (segAmplitude > 0.f) { | |||
nvgFillColor(ctx.vg, color::alpha(component::GREEN, segAmplitude)); | |||
nvgFill(ctx.vg); | |||
nvgFillColor(args.vg, color::alpha(component::GREEN, segAmplitude)); | |||
nvgFill(args.vg); | |||
} | |||
} | |||
} | |||
@@ -91,7 +91,7 @@ struct VCF : Module { | |||
filter.reset(); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
if (!outputs[LPF_OUTPUT].active && !outputs[HPF_OUTPUT].active) { | |||
outputs[LPF_OUTPUT].value = 0.f; | |||
outputs[HPF_OUTPUT].value = 0.f; | |||
@@ -100,7 +100,7 @@ struct VCF : Module { | |||
float input = inputs[IN_INPUT].value / 5.f; | |||
float drive = clamp(params[DRIVE_PARAM].value + inputs[DRIVE_INPUT].value / 10.f, 0.f, 1.f); | |||
float gain = powf(1.f + drive, 5); | |||
float gain = std::pow(1.f + drive, 5); | |||
input *= gain; | |||
// Add -60dB noise to bootstrap self-oscillation | |||
@@ -108,7 +108,7 @@ struct VCF : Module { | |||
// Set resonance | |||
float res = clamp(params[RES_PARAM].value + inputs[RES_INPUT].value / 10.f, 0.f, 1.f); | |||
filter.resonance = powf(res, 2) * 10.f; | |||
filter.resonance = std::pow(res, 2) * 10.f; | |||
// Set cutoff frequency | |||
float pitch = 0.f; | |||
@@ -116,13 +116,13 @@ struct VCF : Module { | |||
pitch += inputs[FREQ_INPUT].value * dsp::quadraticBipolar(params[FREQ_CV_PARAM].value); | |||
pitch += params[FREQ_PARAM].value * 10.f - 5.f; | |||
pitch += dsp::quadraticBipolar(params[FINE_PARAM].value * 2.f - 1.f) * 7.f / 12.f; | |||
float cutoff = 261.626f * powf(2.f, pitch); | |||
float cutoff = 261.626f * std::pow(2.f, pitch); | |||
cutoff = clamp(cutoff, 1.f, 8000.f); | |||
filter.setCutoff(cutoff); | |||
/* | |||
// Process sample | |||
float dt = APP->engine->getSampleTime() / UPSAMPLE; | |||
float dt = args.sampleTime / UPSAMPLE; | |||
float inputBuf[UPSAMPLE]; | |||
float lowpassBuf[UPSAMPLE]; | |||
float highpassBuf[UPSAMPLE]; | |||
@@ -142,7 +142,7 @@ struct VCF : Module { | |||
outputs[HPF_OUTPUT].value = 5.f * highpassDecimator.process(highpassBuf); | |||
} | |||
*/ | |||
filter.process(input, APP->engine->getSampleTime()); | |||
filter.process(input, args.sampleTime); | |||
outputs[LPF_OUTPUT].value = 5.f * filter.lowpass; | |||
outputs[HPF_OUTPUT].value = 5.f * filter.highpass; | |||
} | |||
@@ -28,7 +28,7 @@ struct VCMixer : Module { | |||
params[LVL_PARAM + 3].config(0.0, 1.0, 1.0, "Ch 4 level"); | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
float mix = 0.f; | |||
for (int i = 0; i < 4; i++) { | |||
float ch = inputs[CH_INPUT + i].value; | |||
@@ -58,7 +58,7 @@ struct VoltageControlledOscillator { | |||
// Adjust pitch slew | |||
if (++pitchSlewIndex > 32) { | |||
const float pitchSlewTau = 100.f; // Time constant for leaky integrator in seconds | |||
pitchSlew += (random::normal() - pitchSlew / pitchSlewTau) * APP->engine->getSampleTime(); | |||
pitchSlew += (random::normal() - pitchSlew / pitchSlewTau) * deltaTime; | |||
pitchSlewIndex = 0; | |||
} | |||
} | |||
@@ -204,8 +204,7 @@ struct VCO : Module { | |||
params[PWM_PARAM].config(0.f, 1.f, 0.f, "Pulse width modulation", "%", 0.f, 100.f); | |||
} | |||
void step() override { | |||
float deltaTime = APP->engine->getSampleTime(); | |||
void process(const ProcessArgs &args) override { | |||
oscillator.analog = params[MODE_PARAM].value > 0.f; | |||
oscillator.soft = params[SYNC_PARAM].value <= 0.f; | |||
@@ -218,7 +217,7 @@ struct VCO : Module { | |||
oscillator.setPulseWidth(params[PW_PARAM].value + params[PWM_PARAM].value * inputs[PW_INPUT].value / 10.f); | |||
oscillator.syncEnabled = inputs[SYNC_INPUT].active; | |||
oscillator.process(deltaTime, inputs[SYNC_INPUT].value); | |||
oscillator.process(args.sampleTime, inputs[SYNC_INPUT].value); | |||
// Set output | |||
if (outputs[SIN_OUTPUT].active) | |||
@@ -230,8 +229,8 @@ struct VCO : Module { | |||
if (outputs[SQR_OUTPUT].active) | |||
outputs[SQR_OUTPUT].value = 5.f * oscillator.sqr(); | |||
lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), deltaTime); | |||
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime); | |||
lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), args.sampleTime); | |||
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime); | |||
} | |||
}; | |||
@@ -309,8 +308,8 @@ struct VCO2 : Module { | |||
params[FM_PARAM].config(0.f, 1.f, 0.f, "Frequency modulation"); | |||
} | |||
void step() override { | |||
float deltaTime = APP->engine->getSampleTime(); | |||
void process(const ProcessArgs &args) override { | |||
float deltaTime = args.sampleTime; | |||
oscillator.analog = params[MODE_PARAM].value > 0.f; | |||
oscillator.soft = params[SYNC_PARAM].value <= 0.f; | |||
@@ -27,15 +27,15 @@ struct Viz : Module { | |||
counter.period = 16; | |||
} | |||
void step() override { | |||
void process(const ProcessArgs &args) override { | |||
if (counter.process()) { | |||
channels = inputs[POLY_INPUT].getChannels(); | |||
float deltaTime = APP->engine->getSampleTime() * counter.period; | |||
float deltaTime = args.sampleTime * counter.period; | |||
for (int c = 0; c < 16; c++) { | |||
float v = inputs[POLY_INPUT].getVoltage(c) / 10.f; | |||
lights[VU_LIGHTS + c*2 + 0].setSmoothBrightness(v, deltaTime); | |||
lights[VU_LIGHTS + c*2 + 1].setSmoothBrightness(-v, deltaTime); | |||
lights[VU_LIGHTS + c*2 + 0].setSmoothBrightness(v, deltaTime * counter.period); | |||
lights[VU_LIGHTS + c*2 + 1].setSmoothBrightness(-v, deltaTime * counter.period); | |||
} | |||
} | |||
} | |||
@@ -51,20 +51,20 @@ struct VizDisplay : Widget { | |||
font = APP->window->loadFont(asset::plugin(pluginInstance, "res/nunito/Nunito-Bold.ttf")); | |||
} | |||
void draw(const widget::DrawContext &ctx) override { | |||
void draw(const DrawArgs &args) override { | |||
for (int c = 0; c < 16; c++) { | |||
Vec p = Vec(15, 16 + (float) c / 16 * (box.size.y - 10)); | |||
std::string text = string::f("%d", c + 1); | |||
nvgFontFaceId(ctx.vg, font->handle); | |||
nvgFontSize(ctx.vg, 11); | |||
nvgTextLetterSpacing(ctx.vg, 0.0); | |||
nvgTextAlign(ctx.vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); | |||
nvgFontFaceId(args.vg, font->handle); | |||
nvgFontSize(args.vg, 11); | |||
nvgTextLetterSpacing(args.vg, 0.0); | |||
nvgTextAlign(args.vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); | |||
if (module && c < module->channels) | |||
nvgFillColor(ctx.vg, nvgRGB(255, 255, 255)); | |||
nvgFillColor(args.vg, nvgRGB(255, 255, 255)); | |||
else | |||
nvgFillColor(ctx.vg, nvgRGB(99, 99, 99)); | |||
nvgText(ctx.vg, p.x, p.y, text.c_str(), NULL); | |||
nvgFillColor(args.vg, nvgRGB(99, 99, 99)); | |||
nvgText(args.vg, p.x, p.y, text.c_str(), NULL); | |||
} | |||
} | |||
}; | |||