docb / dbRackSequencer

GNU General Public License v3.0
18 stars 6 forks source link

CDiv keeps original gate width #31

Closed hatsoptional closed 5 months ago

hatsoptional commented 6 months ago

Hi, I noticed that the pulse width of the CDiv output is equal to the pw of the input clock, instead of being multiplied by the division factor.

immagine

If this is intended and not a bug, could you please add an option to make CDiv output the same as the clocked divided output?

docb commented 6 months ago

hi, this is intended, currently i do not measure the pw of the incoming clock so i have nothing to multiply with and it would be some effort to do this properly. i also don't have any actions in between clock triggers. the only thing i can imagine is to have an option to ignore the pw and hold a gate on half the division number (where at odd divisions this would be shortened by one clock trigger)

docb commented 6 months ago

you could also check rgate from bogaudio or gate mod from count modula. gate2

hatsoptional commented 6 months ago

Hi, thanks but just for fun I took a stab at it:

cdiv

These are the changes, if you're ok with it let me know if I can open a PR.

index d8eef61..c4d37f5 100644
--- a/src/CDiv.cpp
+++ b/src/CDiv.cpp
@@ -19,7 +19,11 @@ struct CDiv : Module {
   dsp::SchmittTrigger rstTrigger;
   dsp::PulseGenerator rstPulse;
   dsp::ClockDivider paramDivider;
+  bool curHigh = true;
+  bool prevHigh = false;
   unsigned long  currentPos=0;
+  unsigned long edges=0;
+  bool orig_pw=true;
        CDiv() {
                config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
     configInput(CLK_INPUT,"Clock");
@@ -46,6 +50,15 @@ struct CDiv : Module {
     if(rstTrigger.process(inputs[RST_INPUT].getVoltage())) {
       rstPulse.trigger(0.001f);
       currentPos=0;
+      edges=0;
+      curHigh=true;
+      prevHigh=false;
+    } else {
+      prevHigh=curHigh;
+      curHigh=clockTrigger.isHigh();
+      if ((curHigh && !prevHigh) || (!curHigh && prevHigh)) {
+       edges++;
+      }
     }
     bool resetGate=rstPulse.process(args.sampleTime);
     if(clockTrigger.process(inputs[CLK_INPUT].getVoltage()) && !resetGate) {
@@ -53,8 +66,13 @@ struct CDiv : Module {
     }
     for(int k=0;k<NUM_DIV;k++) {
       int currentDiv=params[DIV_PARAM+k].getValue();
-      bool gate = currentPos%currentDiv==0;
-      outputs[CLK_OUTPUT+k].setVoltage(gate?inputs[CLK_INPUT].getVoltage():0.f);
+      if (orig_pw) {
+       bool gate = currentPos%currentDiv==0;
+       outputs[CLK_OUTPUT+k].setVoltage(gate?inputs[CLK_INPUT].getVoltage():0.f);
+      } else {
+       bool gate = edges%(currentDiv*2) < (unsigned long)currentDiv;
+       outputs[CLK_OUTPUT+k].setVoltage(gate?10.f:0.f);
+      }
     }
        }
 };
@@ -90,7 +108,13 @@ struct CDivWidget : ModuleWidget {
       y+=30;
     }
        }
+
+  void appendContextMenu(Menu* menu) override {
+    CDiv* module = getModule<CDiv>();
+    menu->addChild(new MenuSeparator);
+    menu->addChild(createBoolPtrMenuItem("Keep input clock original pulse width", "", &module->orig_pw));
+  }
 };

-Model* modelCDiv = createModel<CDiv, CDivWidget>("CDiv");
\ No newline at end of file
+Model* modelCDiv = createModel<CDiv, CDivWidget>("CDiv");
docb commented 6 months ago

hi, could you make a PR, i would like to test it and thing through. Thanks!

hatsoptional commented 5 months ago

Closing as the PR has been merged, thanks for your time spent reviewing, testing and merging.