| @@ -24,6 +24,9 @@ namespace engine { | |||
| /** DSP processor instance for your module. */ | |||
| struct Module { | |||
| struct Internal; | |||
| Internal* internal; | |||
| plugin::Model* model = NULL; | |||
| /** Unique ID for referring to the module in the engine. | |||
| Assigned when added to the engine. | |||
| @@ -81,12 +84,6 @@ struct Module { | |||
| }; | |||
| 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. | |||
| */ | |||
| float cpuTime = 0.f; | |||
| bool bypassed = false; | |||
| /** Constructs a Module with no params, inputs, outputs, and lights. */ | |||
| Module(); | |||
| /** Use config() instead. */ | |||
| @@ -276,6 +273,10 @@ struct Module { | |||
| virtual void onRandomize() {} | |||
| /** DEPRECATED. Override `onSampleRateChange(e)` instead. */ | |||
| virtual void onSampleRateChange() {} | |||
| // private | |||
| float& cpuTime(); | |||
| bool& bypassed(); | |||
| }; | |||
| @@ -299,7 +299,7 @@ ModuleWidget::~ModuleWidget() { | |||
| void ModuleWidget::draw(const DrawArgs& args) { | |||
| nvgScissor(args.vg, RECT_ARGS(args.clipBox)); | |||
| if (module && module->bypassed) { | |||
| if (module && module->bypassed()) { | |||
| nvgGlobalAlpha(args.vg, 0.33); | |||
| } | |||
| @@ -314,12 +314,12 @@ void ModuleWidget::draw(const DrawArgs& args) { | |||
| nvgFillColor(args.vg, nvgRGBAf(0, 0, 0, 0.75)); | |||
| nvgFill(args.vg); | |||
| float percent = module->cpuTime * APP->engine->getSampleRate() * 100; | |||
| float microseconds = module->cpuTime * 1e6f; | |||
| float percent = module->cpuTime() * APP->engine->getSampleRate() * 100; | |||
| float microseconds = module->cpuTime() * 1e6f; | |||
| std::string cpuText = string::f("%.1f%%\n%.2f μs", percent, microseconds); | |||
| bndLabel(args.vg, 2.0, box.size.y - 34.0, INFINITY, INFINITY, -1, cpuText.c_str()); | |||
| float p = math::clamp(module->cpuTime / APP->engine->getSampleTime(), 0.f, 1.f); | |||
| float p = math::clamp(module->cpuTime() / APP->engine->getSampleTime(), 0.f, 1.f); | |||
| nvgBeginPath(args.vg); | |||
| nvgRect(args.vg, | |||
| 0, (1.f - p) * box.size.y, | |||
| @@ -835,12 +835,12 @@ void ModuleWidget::cloneAction() { | |||
| void ModuleWidget::bypassAction() { | |||
| assert(module); | |||
| APP->engine->bypassModule(module, !module->bypassed); | |||
| APP->engine->bypassModule(module, !module->bypassed()); | |||
| // history::ModuleBypass | |||
| history::ModuleBypass* h = new history::ModuleBypass; | |||
| h->moduleId = module->id; | |||
| h->bypassed = module->bypassed; | |||
| h->bypassed = module->bypassed(); | |||
| APP->history->push(h); | |||
| } | |||
| @@ -908,7 +908,7 @@ void ModuleWidget::createContextMenu() { | |||
| ModuleBypassItem* bypassItem = new ModuleBypassItem; | |||
| bypassItem->text = "Bypass"; | |||
| bypassItem->rightText = RACK_MOD_CTRL_NAME "+E"; | |||
| if (module && module->bypassed) | |||
| if (module && module->bypassed()) | |||
| bypassItem->rightText = CHECKMARK_STRING " " + bypassItem->rightText; | |||
| bypassItem->moduleWidget = this; | |||
| menu->addChild(bypassItem); | |||
| @@ -229,7 +229,7 @@ static void Engine_stepModulesWorker(Engine* that, int threadId) { | |||
| } | |||
| // Step module | |||
| if (!module->bypassed) | |||
| if (!module->bypassed()) | |||
| module->process(processArgs); | |||
| else | |||
| module->processBypass(processArgs); | |||
| @@ -241,7 +241,7 @@ static void Engine_stepModulesWorker(Engine* that, int threadId) { | |||
| // Smooth CPU time | |||
| const float cpuTau = 2.f /* seconds */; | |||
| module->cpuTime += (duration - module->cpuTime) * processArgs.sampleTime / cpuTau; | |||
| module->cpuTime() += (duration - module->cpuTime()) * processArgs.sampleTime / cpuTau; | |||
| } | |||
| // Iterate ports to step plug lights | |||
| @@ -629,14 +629,14 @@ void Engine::randomizeModule(Module* module) { | |||
| void Engine::bypassModule(Module* module, bool bypassed) { | |||
| std::lock_guard<std::recursive_mutex> lock(internal->mutex); | |||
| assert(module); | |||
| if (module->bypassed == bypassed) | |||
| if (module->bypassed() == bypassed) | |||
| return; | |||
| // Clear outputs and set to 1 channel | |||
| for (Output& output : module->outputs) { | |||
| // This zeros all voltages, but the channel is set to 1 if connected | |||
| output.setChannels(0); | |||
| } | |||
| module->bypassed = bypassed; | |||
| module->bypassed() = bypassed; | |||
| // Trigger event | |||
| if (bypassed) { | |||
| Module::BypassEvent eBypass; | |||
| @@ -6,7 +6,16 @@ namespace rack { | |||
| namespace engine { | |||
| struct Module::Internal { | |||
| /** Seconds spent in the process() method, with exponential smoothing. | |||
| Only written when CPU timing is enabled, since time measurement is expensive. | |||
| */ | |||
| float cpuTime = 0.f; | |||
| bool bypassed = false; | |||
| }; | |||
| Module::Module() { | |||
| internal = new Internal; | |||
| } | |||
| Module::~Module() { | |||
| @@ -22,6 +31,7 @@ Module::~Module() { | |||
| if (outputInfo) | |||
| delete outputInfo; | |||
| } | |||
| delete internal; | |||
| } | |||
| void Module::config(int numParams, int numInputs, int numOutputs, int numLights) { | |||
| @@ -92,8 +102,8 @@ json_t* Module::toJson() { | |||
| json_object_set_new(rootJ, "params", paramsJ); | |||
| // bypassed | |||
| if (bypassed) | |||
| json_object_set_new(rootJ, "bypassed", json_boolean(bypassed)); | |||
| if (internal->bypassed) | |||
| json_object_set_new(rootJ, "bypassed", json_boolean(true)); | |||
| // leftModuleId | |||
| if (leftExpander.moduleId >= 0) | |||
| @@ -192,7 +202,7 @@ void Module::fromJson(json_t* rootJ) { | |||
| if (!bypassedJ) | |||
| bypassedJ = json_object_get(rootJ, "disabled"); | |||
| if (bypassedJ) | |||
| bypassed = json_boolean_value(bypassedJ); | |||
| internal->bypassed = json_boolean_value(bypassedJ); | |||
| // These do not need to be deserialized, since the module positions will set them correctly when added to the rack. | |||
| // // leftModuleId | |||
| @@ -236,5 +246,15 @@ void Module::onRandomize(const RandomizeEvent& e) { | |||
| } | |||
| float& Module::cpuTime() { | |||
| return internal->cpuTime; | |||
| } | |||
| bool& Module::bypassed() { | |||
| return internal->bypassed; | |||
| } | |||
| } // namespace engine | |||
| } // namespace rack | |||