diff --git a/src/ShapeMaster/Channel.cpp b/src/ShapeMaster/Channel.cpp index 7473412..1707bd5 100644 --- a/src/ShapeMaster/Channel.cpp +++ b/src/ShapeMaster/Channel.cpp @@ -11,7 +11,12 @@ -void Channel::construct(int _chanNum, bool* _running, uint32_t* _sosEosEoc, ClockDetector* _clockDetector, Input* _inputs, Output* _outputs, Param* _params, std::vector* _paramQuantitiesSrc, PresetAndShapeManager* _presetAndShapeManager) { +Channel::Channel(int _chanNum, bool* _running, uint32_t* _sosEosEoc, ClockDetector* _clockDetector, Input* _inputs, Output* _outputs, Param* _params, ParamQuantity* pqReps, PresetAndShapeManager* _presetAndShapeManager) { + // channelSettings.cc1 = 0; + // channelSettings2.cc1 = 0; + // channelSettings3.cc1 = 0; + // channelSettings4.cc1 = 0; + chanNum = _chanNum; running = _running; hpFilter.setParameters(true, 0.1f); @@ -35,15 +40,11 @@ void Channel::construct(int _chanNum, bool* _running, uint32_t* _sosEosEoc, Cloc paLow = &_params[LOW_PARAM + chanNum * NUM_CHAN_PARAMS]; paPrevNextPreSha = &_params[PREV_NEXT_PRE_SHA + chanNum * NUM_CHAN_PARAMS]; smoothFilter.setParameters(false, 0.4f); - ParamQuantity* pqReps = NULL; - if (_paramQuantitiesSrc) { - pqReps = (*_paramQuantitiesSrc)[REPETITIONS_PARAM + chanNum * NUM_CHAN_PARAMS]; - } presetAndShapeManager = _presetAndShapeManager;// can be null clockDetector = _clockDetector; - playHead.construct(_chanNum, _sosEosEoc, _clockDetector, _running, pqReps, &_params[chanNum * NUM_CHAN_PARAMS], &_inputs[TRIG_INPUTS + chanNum], &scEnvelope, _presetAndShapeManager, &nodeTrigPulseGen, &nodeTrigDuration); - // onReset(false); // not needed since ShapeMaster::onReset() will propagate to Channel::onReset(); + + onReset(false); // redundant since ShapeMaster::onReset() will propagate to Channel::onReset(), but keep to reset anyways for static code analysis warnings (but we can avoid withParams at least) } void Channel::onReset(bool withParams) { diff --git a/src/ShapeMaster/Channel.hpp b/src/ShapeMaster/Channel.hpp index 2be88ca..05e3d2d 100644 --- a/src/ShapeMaster/Channel.hpp +++ b/src/ShapeMaster/Channel.hpp @@ -150,13 +150,7 @@ class Channel { public: - Channel() { - channelSettings.cc1 = 0; - channelSettings2.cc1 = 0; - channelSettings3.cc1 = 0; - channelSettings4.cc1 = 0; - } - void construct(int _chanNum, bool* _running, uint32_t* _sosEosEoc, ClockDetector* _clockDetector, Input* _inputs, Output* _outputs, Param* _params, std::vector* _paramQuantitiesSrc, PresetAndShapeManager* _presetAndShapeManager); + Channel(int _chanNum, bool* _running, uint32_t* _sosEosEoc, ClockDetector* _clockDetector, Input* _inputs, Output* _outputs, Param* _params, ParamQuantity* pqReps, PresetAndShapeManager* _presetAndShapeManager); void onReset(bool withParams); diff --git a/src/ShapeMaster/Shape.hpp b/src/ShapeMaster/Shape.hpp index 1b4f58a..303bc3d 100644 --- a/src/ShapeMaster/Shape.hpp +++ b/src/ShapeMaster/Shape.hpp @@ -40,7 +40,7 @@ class Shape { int pc;// point cache, index into points, has to be managed in lockstep with numPts such that 0 <= pc < (numPts - 1) int pcDelta; - std::atomic_flag lock_shape = ATOMIC_FLAG_INIT;// blocking and mandatory for all modifications that can temporarily change invariants, non-blocking test for process() (should leave output unchanged when can't acquire lock) + std::atomic_flag* lock_shape;// blocking and mandatory for all modifications that can temporarily change invariants, non-blocking test for process() (should leave output unchanged when can't acquire lock) float evalShapeForProcessRet = 0.0f; @@ -54,22 +54,26 @@ class Shape { return (rndVal - 0.5f) * _ctrlMax * 0.01f + 0.5f; } - bool lockShapeNonBlocking() {// returns true if we got the lock successfuly - return !lock_shape.test_and_set();//std::memory_order_acquire); + bool lockShapeNonBlocking() {// returns true if we got the lock successfully + return !lock_shape->test_and_set();//std::memory_order_acquire); } void lockShapeBlocking() { - while (lock_shape.test_and_set()) {};//std::memory_order_acquire)) {} + while (lock_shape->test_and_set()) {};//std::memory_order_acquire)) {} } void unlockShape() {// only call this after having called lockShapeBlocking() or after a successful lockShapeNonBlocking() - lock_shape.clear();//std::memory_order_release); + lock_shape->clear();//std::memory_order_release); } Shape() { + lock_shape = new std::atomic_flag(ATOMIC_FLAG_INIT); onReset(); } + ~Shape() { + delete lock_shape; + } void onReset(); diff --git a/src/ShapeMaster/ShapeMaster.cpp b/src/ShapeMaster/ShapeMaster.cpp index f3043bd..fab303e 100644 --- a/src/ShapeMaster/ShapeMaster.cpp +++ b/src/ShapeMaster/ShapeMaster.cpp @@ -75,11 +75,13 @@ ShapeMaster::ShapeMaster() {// : worker(&ShapeMaster::worker_nextPresetOrShape, configLight(SC_LPF_LIGHT, "Current channel sidechain LPF active"); + channelDirtyCache = new Channel(0, &running, NULL, NULL, &inputs[0], &outputs[0], channelDirtyCacheParams, NULL, NULL); + channels.reserve(8); + presetAndShapeManager.construct(&(channels[0]), channelDirtyCache, &miscSettings3); for (int c = 0; c < 8; c++) { - channels[c].construct(c, &running, &sosEosEoc, &clockDetector, &inputs[0], &outputs[0], ¶ms[0], ¶mQuantities, &presetAndShapeManager); + ParamQuantity* pqReps = paramQuantities[REPETITIONS_PARAM + c * NUM_CHAN_PARAMS]; + channels.push_back(Channel(c, &running, &sosEosEoc, &clockDetector, &inputs[0], &outputs[0], ¶ms[0], pqReps, &presetAndShapeManager)); } - presetAndShapeManager.construct(channels, &channelDirtyCache, &miscSettings3); - channelDirtyCache.construct(0, &running, NULL, NULL, &inputs[0], &outputs[0], channelDirtyCacheParams, NULL, NULL); onReset(); } @@ -105,7 +107,7 @@ void ShapeMaster::onReset() { for (int c = 0; c < NUM_CHAN; c++) { channels[c].onReset(false); } - channelDirtyCache.onReset(true); + channelDirtyCache->onReset(true); currChan = 0; resetNonJson(); } @@ -258,7 +260,7 @@ void ShapeMaster::process(const ProcessArgs &args) { // Main process for (int c = 0; c < NUM_CHAN; c++) { - channels[c].process(c == fsDiv8, cvExp ? &(cvExp->chanCvs[c]) : NULL); + channels[c].process(c == fsDiv8, (cvExp != NULL) ? (&(cvExp->chanCvs[c])) : NULL); } // Scope @@ -315,7 +317,7 @@ void ShapeMaster::processRunToggled() { void ShapeMasterWidget::appendContextMenu(Menu *menu) { - ShapeMaster* module = (ShapeMaster*)(this->module); + ShapeMaster* module = static_cast(this->module); assert(module); menu->addChild(new MenuSeparator()); @@ -379,7 +381,7 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { // Main panels from Inkscape setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/dark/ShapeMaster.svg"))); - SvgPanel* svgPanel = (SvgPanel*)getPanel(); + SvgPanel* svgPanel = static_cast(getPanel()); panelBorder = findBorder(svgPanel->fb); // Left side (audio, trig, clock, reset, run inputs) @@ -422,7 +424,7 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { SmChannelButton* channelButton; addChild(channelButton = createWidgetCentered(mm2px(Vec(27.94f + 53.792f / 2.0f, aboveDispY)))); if (module) { - channelButton->channels = module->channels; + channelButton->channels = &(module->channels[0]); channelButton->currChan = &(module->currChan); channelButton->miscSettings2GlobalSrc = &(module->miscSettings2); channelButton->trigExpPresentSrc = &(module->expPresentRight); @@ -433,15 +435,15 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { // preset label addChild(smLabels[16] = createWidgetCentered(mm2px(Vec(103.52f, aboveDispY)))); if (module) { - ((PresetLabel*)(smLabels[16]))->presetAndShapeManager = &(module->presetAndShapeManager); - ((PresetLabel*)(smLabels[16]))->presetOrShapeDirty = &(presetOrShapeDirty); - ((PresetLabel*)(smLabels[16]))->unsupportedSync = &(unsupportedSync); + (static_cast(smLabels[16]))->presetAndShapeManager = &(module->presetAndShapeManager); + (static_cast(smLabels[16]))->presetOrShapeDirty = &(presetOrShapeDirty); + (static_cast(smLabels[16]))->unsupportedSync = &(unsupportedSync); } // shape label addChild(smLabels[17] = createWidgetCentered(mm2px(Vec(145.1f, aboveDispY)))); if (module) { - ((ShapeLabel*)(smLabels[17]))->presetAndShapeManager = &(module->presetAndShapeManager); - ((ShapeLabel*)(smLabels[17]))->presetOrShapeDirty = &(presetOrShapeDirty); + (static_cast(smLabels[17]))->presetAndShapeManager = &(module->presetAndShapeManager); + (static_cast(smLabels[17]))->presetOrShapeDirty = &(presetOrShapeDirty); } // deferral lights addChild(createLightCentered>>(mm2px(Vec(103.52f - 40.0f / 2.0f + 1.05f, aboveDispY - 2.0f)), module, ShapeMaster::DEFERRAL_LIGHTS + 0)); @@ -479,10 +481,10 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { if (module) { scopeButtons->settingSrc = &module->miscSettings.cc4[2]; scopeButtons->currChan = &(module->currChan); - scopeButtons->channels = module->channels; + scopeButtons->channels = &(module->channels[0]); scopeButtons->scopeBuffers = &(module->scopeBuffers); shapeButtons->currChan = &(module->currChan); - shapeButtons->channels = module->channels; + shapeButtons->channels = &(module->channels[0]); } // Display area @@ -495,12 +497,12 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { smDisplayLight->dragPtSelect = &(smDisplay->dragPtSelect); if (module) { smDisplay->currChan = &(module->currChan); - smDisplay->channels = module->channels; + smDisplay->channels = &(module->channels[0]); smDisplay->lineWidthSrc = &(module->lineWidth); smDisplay->setting3Src = &(module->miscSettings3); smDisplayLight->currChan = &(module->currChan); - smDisplayLight->channels = module->channels; + smDisplayLight->channels = &(module->channels[0]); smDisplayLight->displayInfo = &displayInfo; smDisplayLight->settingSrc = &(module->miscSettings); smDisplayLight->setting2Src = &(module->miscSettings2); @@ -514,7 +516,7 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { addChild(bigNumbers = createWidgetCentered(mm2px(Vec(96.52f, 79.0f)))); if (module) { bigNumbers->currChan = &(module->currChan); - bigNumbers->channels = module->channels; + bigNumbers->channels = &(module->channels[0]); bigNumbers->displayInfo = &displayInfo; } @@ -529,10 +531,10 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { addParam(smButtons[c][2] = createParamCentered(mm2px(Vec(48.16f, belowDispY)), module, FREEZE_PARAM + cp)); addParam(smButtons[c][1] = createParamCentered(mm2px(Vec(61.23f, belowDispY)), module, LOOP_PARAM + cp)); if (module) { - ((SmPlayButton*)smButtons[c][3])->currChan = &(module->currChan); - ((SmPlayButton*)smButtons[c][3])->channels = module->channels; - ((SmLoopButton*)smButtons[c][1])->currChan = &(module->currChan); - ((SmLoopButton*)smButtons[c][1])->channels = module->channels; + (static_cast(smButtons[c][3]))->currChan = &(module->currChan); + (static_cast(smButtons[c][3]))->channels = &(module->channels[0]); + (static_cast(smButtons[c][1]))->currChan = &(module->currChan); + (static_cast(smButtons[c][1]))->channels = &(module->channels[0]); } } // GridX and range @@ -559,10 +561,10 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { addParam(smButtons[c][4] = createParamCentered(syncPosVec, module, SYNC_PARAM + cp)); addParam(smButtons[c][0] = createParamCentered(lockPosVec, module, LOCK_PARAM + cp)); if (module) { - ((SmSyncButton*)smButtons[c][4])->currChan = &(module->currChan); - ((SmSyncButton*)smButtons[c][4])->channels = module->channels; - ((SmSyncButton*)smButtons[c][4])->inClock = &(module->inputs[CLOCK_INPUT]); - ((SmSyncButton*)smButtons[c][4])->displayInfo = &displayInfo; + (static_cast(smButtons[c][4]))->currChan = &(module->currChan); + (static_cast(smButtons[c][4]))->channels = &(module->channels[0]); + (static_cast(smButtons[c][4]))->inClock = &(module->inputs[CLOCK_INPUT]); + (static_cast(smButtons[c][4]))->displayInfo = &displayInfo; } } @@ -593,8 +595,8 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { addChild(smLabels[1] = createWidgetCentered(mm2px(Vec(62.56f, rowMid)))); addChild(smLabels[2] = createWidgetCentered(mm2px(Vec(74.88f, rowBot)))); if (module) { - ((KnobLabelLength*)smLabels[0])->lengthSyncParamSrc = &(module->params[LENGTH_SYNC_PARAM]); - ((KnobLabelLength*)smLabels[0])->lengthUnsyncParamSrc = &(module->params[LENGTH_UNSYNC_PARAM]); + (static_cast(smLabels[0]))->lengthSyncParamSrc = &(module->params[LENGTH_SYNC_PARAM]); + (static_cast(smLabels[0]))->lengthUnsyncParamSrc = &(module->params[LENGTH_UNSYNC_PARAM]); } @@ -714,7 +716,7 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { addParam(sidechainSettingsButton = createParamCentered(mm2px(Vec(187.24f, 101.87f)), module, GEAR_PARAM)); if (module) { sidechainSettingsButton->currChan = &(module->currChan); - sidechainSettingsButton->channels = module->channels; + sidechainSettingsButton->channels = &(module->channels[0]); } svgPanel->fb->addChild(createWidgetCentered(mm2px(Vec(173.05f, knob2Y)))); for (int c = 0; c < 8; c++) { @@ -729,7 +731,7 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { for (int c = 0; c < 8; c++) { for (int i = 0; i < NUM_KNOB_PARAMS; i++) { smKnobs[c][i]->currChan = &(module->currChan);// will likely need this for CV arcs - smKnobs[c][i]->channels = module->channels;// will likely need this for CV arcs + smKnobs[c][i]->channels = &(module->channels[0]);// will likely need this for CV arcs smKnobs[c][i]->detailsShowSrc = &(module->miscSettings.cc4[0]); smKnobs[c][i]->cloakedModeSrc = &(module->cloakedMode); smKnobs[c][i]->displayInfo = &displayInfo; @@ -749,7 +751,7 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { for (int i = 0; i < NUM_SM_LABELS; i++) { smLabels[i]->knobLabelColorsSrc = &(module->miscSettings.cc4[1]);// unused in [18] and [19] since they are in the display color (GridX and Range) smLabels[i]->currChan = &(module->currChan); - smLabels[i]->channels = module->channels; + smLabels[i]->channels = &(module->channels[0]); } } @@ -768,7 +770,7 @@ ShapeMasterWidget::ShapeMasterWidget(ShapeMaster *module) { void ShapeMasterWidget::step() { - ShapeMaster* module = (ShapeMaster*)(this->module); + ShapeMaster* module = static_cast(this->module); if (module) { int chan = module->currChan; @@ -808,25 +810,25 @@ void ShapeMasterWidget::step() { std::string currChanPresetPath = module->channels[chan].getPresetPath(); std::string currChanShapePath = module->channels[chan].getShapePath(); if (!currChanPresetPath.empty()) { - if (!(module->channelDirtyCache.getPresetPath() == currChanPresetPath)) { - if (!loadPresetOrShape(currChanPresetPath, &module->channelDirtyCache, true, &unsupportedSync, false)) { + if (!(module->channelDirtyCache->getPresetPath() == currChanPresetPath)) { + if (!loadPresetOrShape(currChanPresetPath, module->channelDirtyCache, true, &unsupportedSync, false)) { currChanPresetPath = ""; module->channels[chan].setPresetPath(currChanPresetPath); } } if (!currChanPresetPath.empty()) { - presetOrShapeDirty = module->channels[chan].isDirty(&module->channelDirtyCache); + presetOrShapeDirty = module->channels[chan].isDirty(module->channelDirtyCache); } } else if (!currChanShapePath.empty()) { - if (!(module->channelDirtyCache.getShapePath() == currChanShapePath)) { - if (!loadPresetOrShape(currChanShapePath, &module->channelDirtyCache, false, NULL, false)) { + if (!(module->channelDirtyCache->getShapePath() == currChanShapePath)) { + if (!loadPresetOrShape(currChanShapePath, module->channelDirtyCache, false, NULL, false)) { currChanShapePath = ""; module->channels[chan].setShapePath(currChanShapePath); } } if (!currChanShapePath.empty()) { - presetOrShapeDirty = module->channels[chan].isDirtyShape(&module->channelDirtyCache); + presetOrShapeDirty = module->channels[chan].isDirtyShape(module->channelDirtyCache); } } else { @@ -845,7 +847,7 @@ void ShapeMasterWidget::step() { if (panelBorder && panelBorder->box.size.x != (box.size.x + newSizeAdd)) { panelBorder->box.pos.x = (module->expPresentLeft ? -3 : 0); panelBorder->box.size.x = (box.size.x + newSizeAdd); - SvgPanel* svgPanel = (SvgPanel*)getPanel(); + SvgPanel* svgPanel = static_cast(getPanel()); svgPanel->fb->dirty = true; } diff --git a/src/ShapeMaster/ShapeMaster.hpp b/src/ShapeMaster/ShapeMaster.hpp index e4f5dd6..a899303 100644 --- a/src/ShapeMaster/ShapeMaster.hpp +++ b/src/ShapeMaster/ShapeMaster.hpp @@ -56,7 +56,7 @@ struct ShapeMaster : Module { PackedBytes4 miscSettings3; RandomSettings randomSettings; float lineWidth = 0.0f; - Channel channels[8]; + std::vector channels;// size 8 int currChan = 0; @@ -76,20 +76,21 @@ struct ShapeMaster : Module { dsp::SchmittTrigger clockTrigger; dsp::SchmittTrigger resetTrigger; PresetAndShapeManager presetAndShapeManager; - Channel channelDirtyCache; + Channel* channelDirtyCache; Param channelDirtyCacheParams[NUM_CHAN_PARAMS] = {}; ShapeMaster(); - // ~ShapeMaster() { + ~ShapeMaster() { // if (channelCopyPasteCache != NULL) { // json_decref(channelCopyPasteCache); // } - // } + delete channelDirtyCache; + } - void onReset() override; + void onReset() override final; void resetNonJson() {