Browse Source

Replace module disabling with bypassing using BypassRoute and Module::configBypass().

tags/v2.0.0
Andrew Belt 5 years ago
parent
commit
cc711b6d2d
4 changed files with 62 additions and 16 deletions
  1. +25
    -0
      include/engine/Module.hpp
  2. +1
    -1
      src/app/ModuleWidget.cpp
  3. +22
    -15
      src/engine/Engine.cpp
  4. +14
    -0
      src/engine/Module.cpp

+ 25
- 0
include/engine/Module.hpp View File

@@ -75,6 +75,12 @@ struct Module {
Expander leftExpander;
Expander rightExpander;

struct BypassRoute {
int inputId = -1;
int outputId = -1;
};
std::vector<BypassRoute> bypassRoutes;

/** Seconds spent in the process() method, with exponential smoothing.
Only written when CPU timing is enabled, since time measurement is expensive.
*/
@@ -146,6 +152,21 @@ struct Module {
outputInfos[portId] = p;
}

/** Adds a direct route from an input to an output when the module is bypassed. */
void configBypass(int inputId, int outputId) {
assert(inputId < (int) inputs.size());
assert(outputId < (int) outputs.size());
// Check that output is not yet routed
for (BypassRoute& br : bypassRoutes) {
assert(br.outputId != outputId);
}

BypassRoute br;
br.inputId = inputId;
br.outputId = outputId;
bypassRoutes.push_back(br);
}

struct ProcessArgs {
float sampleRate;
float sampleTime;
@@ -158,6 +179,10 @@ struct Module {
}
/** DEPRECATED. Override `process(const ProcessArgs& args)` instead. */
virtual void step() {}
/** Called instead of process() when Module is bypassed.
Typically you do not need to override this. Use configBypass() instead.
*/
virtual void processBypass(const ProcessArgs& args);

json_t* toJson();
/** This is virtual only for the purpose of unserializing legacy data when you could set properties of the `.modules[]` object itself.


+ 1
- 1
src/app/ModuleWidget.cpp View File

@@ -306,7 +306,7 @@ void ModuleWidget::draw(const DrawArgs& args) {
Widget::draw(args);

// Power meter
if (module && settings::cpuMeter && !module->disabled) {
if (module && settings::cpuMeter) {
nvgBeginPath(args.vg);
nvgRect(args.vg,
0, box.size.y - 35,


+ 22
- 15
src/engine/Engine.cpp View File

@@ -220,21 +220,28 @@ static void Engine_stepModulesWorker(Engine* that, int threadId) {
break;

Module* module = internal->modules[i];
if (!module->disabled) {
// Step module
if (cpuMeter) {
auto beginTime = std::chrono::high_resolution_clock::now();
module->process(processArgs);
auto endTime = std::chrono::high_resolution_clock::now();
float duration = std::chrono::duration<float>(endTime - beginTime).count();

// Smooth CPU time
const float cpuTau = 2.f /* seconds */;
module->cpuTime += (duration - module->cpuTime) * processArgs.sampleTime / cpuTau;
}
else {
module->process(processArgs);
}

// Start CPU timer
using time_point = std::chrono::time_point<std::chrono::high_resolution_clock>;
time_point beginTime;
if (cpuMeter) {
beginTime = std::chrono::high_resolution_clock::now();
}

// Step module
if (!module->disabled)
module->process(processArgs);
else
module->processBypass(processArgs);

// Stop CPU timer
if (cpuMeter) {
time_point endTime = std::chrono::high_resolution_clock::now();
float duration = std::chrono::duration<float>(endTime - beginTime).count();

// Smooth CPU time
const float cpuTau = 2.f /* seconds */;
module->cpuTime += (duration - module->cpuTime) * processArgs.sampleTime / cpuTau;
}

// Iterate ports to step plug lights


+ 14
- 0
src/engine/Module.cpp View File

@@ -47,6 +47,20 @@ void Module::config(int numParams, int numInputs, int numOutputs, int numLights)
}
}

void Module::processBypass(const ProcessArgs& args) {
for (BypassRoute& bypassRoute : bypassRoutes) {
// Route input voltages to output
Input& input = inputs[bypassRoute.inputId];
Output& output = outputs[bypassRoute.outputId];
int channels = input.getChannels();
for (int c = 0; c < channels; c++) {
float v = input.getVoltage(c);
output.setVoltage(v, c);
}
output.setChannels(channels);
}
}

json_t* Module::toJson() {
json_t* rootJ = json_object();



Loading…
Cancel
Save