diff --git a/plugin.json b/plugin.json
index f907252..a8004c9 100644
--- a/plugin.json
+++ b/plugin.json
@@ -1,7 +1,7 @@
{
"slug": "CatroModulo",
"name": "Catro/Modulo",
- "version": "1.0.2",
+ "version": "1.0.3",
"license": "BSD-3-Clause",
"brand": "catronomix",
"author": "catronomix",
diff --git a/res/CM-1.svg b/res/CM-1.svg
index 4374e48..15cc92e 100644
--- a/res/CM-1.svg
+++ b/res/CM-1.svg
@@ -66,8 +66,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.6394021"
- inkscape:cx="25.73249"
- inkscape:cy="340.91672"
+ inkscape:cx="208.93215"
+ inkscape:cy="104.79003"
inkscape:document-units="mm"
inkscape:current-layer="layer3"
showgrid="false"
@@ -76,8 +76,8 @@
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1017"
+ inkscape:window-width="1600"
+ inkscape:window-height="877"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
@@ -88,7 +88,7 @@
inkscape:object-paths="false"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:bbox-paths="false"
- inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-bbox-midpoints="true"
inkscape:snap-intersection-paths="false"
inkscape:snap-smooth-nodes="false"
inkscape:snap-midpoints="false"
@@ -124,7 +124,7 @@
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="rect817"
- d="M 0,-105.66934 C 14.31816,-64.122725 28.371477,22.830661 28.371474,22.830658 L 0,22.830657 Z"
+ d="M 0,-105.66934 C 14.31816,-64.122725 41.546077,22.830661 41.546074,22.830658 L 0,22.830657 Z"
style="display:inline;opacity:1;vector-effect:none;fill:#93bfa5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.53800601;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
+
+ d="m 45.818187,93.40314 13.520508,2.11924 c 2.976296,0.339297 5.54873,0.0403 8.356749,0.0403"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#c06969;stroke-width:0.65536892;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -468,7 +396,7 @@
@@ -674,6 +602,74 @@
id="path6927"
inkscape:connector-curvature="0" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -696,7 +692,7 @@
inkscape:connector-curvature="0"
id="path2113"
d="m 6.1513878,29.0251 c 7.1077092,-6.125689 12.9429802,-4.584659 19.5382592,-0.167603 8.301335,6.798066 12.275922,6.098679 20.689643,0 6.831173,-3.99296 7.107524,-3.898148 10.171505,-3.898148 4.125986,0 7.256656,3.765907 10.906314,3.765907 3.139172,0 5.526848,-2.499058 9.640482,-2.499058 3.726905,0 9.549482,2.868041 9.549482,2.868041"
- style="fill:none;fill-opacity:1;stroke:#c06969;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="fill:none;fill-opacity:1;stroke:#c63434;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccccscc"
inkscape:tile-cx="45.647267"
inkscape:tile-cy="15.577987"
@@ -708,7 +704,7 @@
inkscape:connector-curvature="0"
id="path2099"
d="m 6.1513878,42.12341 c 7.1077092,-6.125689 12.9429802,-4.584659 19.5382592,-0.167603 8.301335,6.798066 12.275922,6.098679 20.689643,0 6.831173,-3.99296 7.107524,-3.898148 10.171505,-3.898148 4.125986,0 7.256656,3.765907 10.906314,3.765907 3.139172,0 5.526848,-2.499058 9.640482,-2.499058 3.726905,0 9.549482,2.868041 9.549482,2.868041"
- style="fill:none;fill-opacity:1;stroke:#c06969;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="fill:none;fill-opacity:1;stroke:#c63434;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccccscc"
inkscape:tile-cx="45.647267"
inkscape:tile-cy="15.577987"
@@ -720,7 +716,7 @@
inkscape:connector-curvature="0"
id="path2085"
d="m 6.1513878,55.22172 c 7.1077092,-6.125689 12.9429802,-4.584659 19.5382592,-0.167603 8.301335,6.798066 12.275922,6.098679 20.689643,0 6.831173,-3.99296 7.107524,-3.898148 10.171505,-3.898148 4.125986,0 7.256656,3.765907 10.906314,3.765907 3.139172,0 5.526848,-2.499058 9.640482,-2.499058 3.726905,0 9.549482,2.868041 9.549482,2.868041"
- style="fill:none;fill-opacity:1;stroke:#c06969;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="fill:none;fill-opacity:1;stroke:#c63434;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccccscc"
inkscape:tile-cx="45.647267"
inkscape:tile-cy="15.577987"
@@ -732,7 +728,7 @@
inkscape:connector-curvature="0"
id="path2071"
d="m 6.1513878,68.32003 c 7.1077092,-6.125689 12.9429802,-4.584659 19.5382592,-0.167603 8.301335,6.798066 12.275922,6.098679 20.689643,0 6.831173,-3.99296 7.107524,-3.898148 10.171505,-3.898148 4.125986,0 7.256656,3.765907 10.906314,3.765907 3.139172,0 5.526848,-2.499058 9.640482,-2.499058 3.726905,0 9.549482,2.868041 9.549482,2.868041"
- style="fill:none;fill-opacity:1;stroke:#c06969;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="fill:none;fill-opacity:1;stroke:#c63434;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccccscc"
inkscape:tile-cx="45.647267"
inkscape:tile-cy="15.577987"
@@ -744,7 +740,7 @@
inkscape:connector-curvature="0"
id="path2057"
d="m 6.1513878,81.41834 c 7.1077092,-6.125689 12.9429802,-4.584659 19.5382592,-0.167603 8.301335,6.798066 12.275922,6.098679 20.689643,0 6.831173,-3.99296 7.107524,-3.898148 10.171505,-3.898148 4.125986,0 7.256656,3.765907 10.906314,3.765907 3.139172,0 5.526848,-2.499058 9.640482,-2.499058 3.726905,0 9.549482,2.868041 9.549482,2.868041"
- style="fill:none;fill-opacity:1;stroke:#c06969;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="fill:none;fill-opacity:1;stroke:#c63434;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccccscc"
inkscape:tile-cx="45.647267"
inkscape:tile-cy="15.577987"
@@ -756,7 +752,7 @@
inkscape:connector-curvature="0"
id="path2043"
d="m 6.1513878,94.51666 c 7.1077092,-6.125689 12.9429802,-4.584659 19.5382592,-0.167603 8.301335,6.798063 12.275922,6.098683 20.689643,0 6.831173,-3.99296 7.107524,-3.898148 10.171505,-3.898148 4.125986,0 7.256656,3.765907 10.906314,3.765907 3.139172,0 5.526848,-2.499058 9.640482,-2.499058 3.726905,0 9.549482,2.868041 9.549482,2.868041"
- style="fill:none;fill-opacity:1;stroke:#c06969;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="fill:none;fill-opacity:1;stroke:#c63434;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccccscc"
inkscape:tile-cx="45.647267"
inkscape:tile-cy="15.577987"
@@ -768,7 +764,7 @@
inkscape:connector-curvature="0"
id="path2029"
d="m 6.1513878,107.61497 c 7.1077092,-6.12569 12.9429802,-4.58466 19.5382592,-0.1676 8.301335,6.79806 12.275922,6.09868 20.689643,0 6.831173,-3.99296 7.107524,-3.89815 10.171505,-3.89815 4.125986,0 7.256656,3.76591 10.906314,3.76591 3.139172,0 5.526848,-2.49906 9.640482,-2.49906 3.726905,0 9.549482,2.86804 9.549482,2.86804"
- style="fill:none;fill-opacity:1;stroke:#c06969;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="fill:none;fill-opacity:1;stroke:#c63434;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccccscc"
inkscape:tile-cx="45.647267"
inkscape:tile-cy="15.577987"
@@ -1820,6 +1816,64 @@
sodipodi:nodetypes="sssss" />
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/res/CM-4.svg b/res/CM-4.svg
index 9918660..8024a5c 100644
--- a/res/CM-4.svg
+++ b/res/CM-4.svg
@@ -64,24 +64,24 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="1.4535161"
- inkscape:cx="-127.97237"
- inkscape:cy="250.00494"
+ inkscape:zoom="4.1111644"
+ inkscape:cx="-4.2123814"
+ inkscape:cy="287.46929"
inkscape:document-units="mm"
- inkscape:current-layer="layer6"
+ inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1017"
+ inkscape:window-width="1600"
+ inkscape:window-height="877"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:snap-bbox="true"
- inkscape:bbox-nodes="true"
+ inkscape:bbox-nodes="false"
inkscape:object-nodes="true"
inkscape:snap-page="true"
inkscape:object-paths="false"
@@ -343,20 +343,30 @@
+ id="path2246"
+ inkscape:connector-curvature="0" />
+ id="path2248"
+ inkscape:connector-curvature="0" />
+ id="path2250"
+ inkscape:connector-curvature="0" />
+ id="path2252"
+ inkscape:connector-curvature="0" />
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/CM-8.svg b/res/CM-8.svg
index 0d43048..4685ddf 100644
--- a/res/CM-8.svg
+++ b/res/CM-8.svg
@@ -65,8 +65,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4535161"
- inkscape:cx="16.169347"
- inkscape:cy="239.48326"
+ inkscape:cx="-156.08527"
+ inkscape:cy="246.94076"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
@@ -75,8 +75,8 @@
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
- inkscape:window-width="1600"
- inkscape:window-height="837"
+ inkscape:window-width="1920"
+ inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
@@ -91,8 +91,8 @@
inkscape:snap-intersection-paths="false"
inkscape:snap-smooth-nodes="false"
inkscape:snap-midpoints="false"
- inkscape:snap-object-midpoints="false"
- inkscape:snap-center="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
inkscape:snap-others="true"
showguides="true"
inkscape:guide-bbox="true"
@@ -289,6 +289,31 @@
d="m 14.458984,8.8925777 a 0.19275636,0.19275636 0 0 0 -0.189453,0.1953128 v 2.9902335 a 0.19275636,0.19275636 0 1 0 0.384766,0 V 9.0878905 A 0.19275636,0.19275636 0 0 0 14.458984,8.8925777 Z"
id="path7473"
inkscape:connector-curvature="0" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ style="display:none">
+
+
+
diff --git a/res/CM-TS_smallh_1.svg b/res/CM-TS_smallh_1.svg
new file mode 100644
index 0000000..f035b33
--- /dev/null
+++ b/res/CM-TS_smallh_1.svg
@@ -0,0 +1,218 @@
+
+
+
+
diff --git a/res/CM-input_ext.svg b/res/CM-input_ext.svg
new file mode 100644
index 0000000..751601f
--- /dev/null
+++ b/res/CM-input_ext.svg
@@ -0,0 +1,144 @@
+
+
+
+
diff --git a/res/CM8_normoff.svg b/res/CM8_normoff.svg
new file mode 100644
index 0000000..9bcbd4d
--- /dev/null
+++ b/res/CM8_normoff.svg
@@ -0,0 +1,103 @@
+
+
+
+
diff --git a/res/CM8_normon.svg b/res/CM8_normon.svg
new file mode 100644
index 0000000..a246ca4
--- /dev/null
+++ b/res/CM8_normon.svg
@@ -0,0 +1,103 @@
+
+
+
+
diff --git a/res/CM9_ledinc.svg b/res/CM9_ledinc.svg
index cbdf6f5..774d35b 100644
--- a/res/CM9_ledinc.svg
+++ b/res/CM9_ledinc.svg
@@ -25,9 +25,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="41.607159"
- inkscape:cx="6.8942966"
- inkscape:cy="2.3916192"
+ inkscape:zoom="14.710352"
+ inkscape:cx="-4.530684"
+ inkscape:cy="1.886097"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
@@ -35,8 +35,8 @@
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
- inkscape:window-width="1600"
- inkscape:window-height="837"
+ inkscape:window-width="1920"
+ inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
@@ -54,7 +54,7 @@
image/svg+xml
-
+
diff --git a/src/CM_helpers.cpp b/src/CM_helpers.cpp
index a7aa8bd..6ba1a18 100644
--- a/src/CM_helpers.cpp
+++ b/src/CM_helpers.cpp
@@ -5,12 +5,16 @@
//helper functions
//math and logic
-float cm_clamp(float val, float lo = -10.0, float hi = 10.0){
+float cm_clamp(float val, float lo = -10.0, float hi = 10.0, bool normalize = false){
if (lo > hi) return 0;
- return std::min(std::max(val, lo), hi);
+ val = std::min(std::max(val, lo), hi);
+ if (normalize){
+ val = 10.0f * ((val - lo) / (hi - lo)) - 5.0f;
+ }
+ return val ;
}
-float cm_fold(float val, float lo = -10.0, float hi = 10.0){
+float cm_fold(float val, float lo = -10.0, float hi = 10.0, bool normalize = false){
if (lo == hi){
return lo;
@@ -24,7 +28,10 @@ float cm_fold(float val, float lo = -10.0, float hi = 10.0){
val = hi + (hi - val);
}
}
- val = std::max(lo, std::min(val, hi));
+ val = std::min(std::max(val, lo), hi);
+ if (normalize){
+ val = 10.0f * ((val - lo) / (hi - lo)) - 5.0f;
+ }
return val;
}
return 0.0;
@@ -51,5 +58,4 @@ float cm_gauss(float size){
}
float cm_gauss(float size, float offset){
return cm_gauss(size) + offset;
-}
-
+}
\ No newline at end of file
diff --git a/src/CM_helpers.hpp b/src/CM_helpers.hpp
index 2ead0de..183566a 100644
--- a/src/CM_helpers.hpp
+++ b/src/CM_helpers.hpp
@@ -4,10 +4,9 @@
//helper functions header
//math and logic
-float cm_clamp(float val, float lo, float hi);
-float cm_fold(float val, float lo, float hi);
+float cm_clamp(float val, float lo, float hi, bool normalize);
+float cm_fold(float val, float lo, float hi, bool normalize);
float cm_gauss(float size);
float cm_gauss(float size, float offset);
-
#endif
\ No newline at end of file
diff --git a/src/CatroModulo.hpp b/src/CatroModulo.hpp
index d735054..5a56fba 100644
--- a/src/CatroModulo.hpp
+++ b/src/CatroModulo.hpp
@@ -38,6 +38,12 @@ struct CM_Knob_small_def_half : CM_Knob_small_def {
}
};
+struct CM_Knob_small_def_half_16 : CM_Knob_small_def_half {
+ CM_Knob_small_def_half_16() {
+ snap = true;
+ }
+};
+
struct CM_Knob_small_red : SvgKnob {
CM_Knob_small_red() {
minAngle = -1.0*M_PI;
@@ -82,6 +88,14 @@ struct CM_Knob_big_def_tt : CM_Knob_big_def {
}
};
+struct CM_Knob_big_def_tts : CM_Knob_big_def {
+ CM_Knob_big_def_tts() {
+ minAngle = -0.75*M_PI;
+ maxAngle = 0.75*M_PI;
+ snap = true;
+ }
+};
+
struct CM_Knob_big_red : SvgKnob {
CM_Knob_big_red() {
minAngle = -1.0*M_PI;
@@ -175,6 +189,13 @@ struct CM_Input_bpm : SvgPort {
}
};
+struct CM_Input_ext : SvgPort {
+ CM_Input_ext() {
+ setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CM-input_ext.svg")));
+ shadow->opacity = 0;
+ }
+};
+
struct CM_Output_def : SvgPort {
CM_Output_def() {
@@ -211,6 +232,13 @@ struct CM_Switch_small : SvgSwitch {
}
};
+struct CM_Switch_smallh : SvgSwitch {
+ CM_Switch_smallh() {
+ addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CM-TS_smallh_0.svg")));
+ addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CM-TS_smallh_1.svg")));
+ }
+};
+
struct CM_TryMe_button : SvgSwitch {
CM_TryMe_button() {
momentary = true;
@@ -262,6 +290,13 @@ struct CM_Ledbutton_mini : SvgSwitch {
}
};
+struct CM_8_normalizebutton : SvgSwitch {
+ CM_8_normalizebutton() {
+ addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CM8_normoff.svg")));
+ addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CM8_normon.svg")));
+ }
+};
+
//mechanisms
@@ -519,6 +554,18 @@ struct CM_BpmClock {
float clk_out[3] = {};
int resetframes = 0;
+
+ //ext input detector
+ dsp::SchmittTrigger externalClockTrigger;
+ float extTime = 0.0f;
+ float extLasttime[2] = {};
+ // float extRate = 0.0f;
+ // int extCount = 0;
+ // float exthistory[4] = {};
+ int rateLock = 0;
+ float extRateLocked = 0.0f;
+ // float ret = 0.0f;
+
public:
CM_BpmClock(){
@@ -531,8 +578,7 @@ struct CM_BpmClock {
//between 0 and 1000
void setbpm(float bpm){
- bpm = std::max(bpm, 0.0f);
- clk_bpm = bpm;
+ clk_bpm = std::max(bpm, 0.0f);
bpm_cv = bpmtocv(bpm);
// freq = clk_bpm / 30.0; //double freq! -for halfstep
}
@@ -555,7 +601,7 @@ struct CM_BpmClock {
void step(float dt){
pulsegen();
- freq = clk_bpm / 30.0; //double freq! -for halfstep
+ freq = clk_bpm / 15.0f; //double freq! -for halfstep
float deltaPhase = fminf(freq * dt, 0.5f); //delta is halftime
phase += deltaPhase;
if (phase >= 1.0f){phase -= 1.0f;}
@@ -583,21 +629,67 @@ struct CM_BpmClock {
return 0.0;
}else{
resetframes = 0;
- return 1.0;
+ return clk_out[out];
}
}
float bpmtocv(float bpm){
- return bpm * 0.01;
+ return bpm / 60.0f;
}
float cvtobpm(float cv){
- return cv * 100.0;
+ return cv * 60.0f;
+ }
+
+ float exttrack(float ext, float interval){
+ if (externalClockTrigger.process(ext)){
+ extLasttime[1] = extLasttime[0];
+ extLasttime[0] = extTime;
+ if (extLasttime[0] > 0 && abs(extLasttime[0] - extLasttime[1]) < 0.001){
+ extRateLocked = (6.0f / ((extLasttime[0] + extLasttime[1] + interval) * 5.0f));
+ if (rateLock == 0){
+ setReset(1.0f);
+ rateLock = 1;
+ }
+ }else{
+ rateLock = 0;
+ }
+ extTime = 0.0f;
+ }
+ extTime += interval;
+
+ return (extRateLocked > 0) ? extRateLocked : 0.0f;
+ }
+
+ void extreset(bool go){
+ if (go){
+ externalClockTrigger.reset();
+ extreset();
+ }
+ }
+
+ void extreset(){
+ extTime = 0.0f;
+ extLasttime[0] = 0.0f;
+ extLasttime[1] = 0.0f;
+ extRateLocked = 0.0f;
+ // extCount = 0;
+ rateLock = 0;
+ // extRateLocked = 0.0f;
}
private:
+ bool compar(int num, float valone, const float valar[]){
+ for (int i=0; i < num; i++){
+ if (valar[i] != valone){
+ return false;
+ }
+ }
+ return true;
+ }
+
float sqr(){
float sqr = phase < pw ? 1.0f : -1.0f;
return sqr;
@@ -810,6 +902,35 @@ struct CM9_LedIndicator : SvgWidget {
}
};
+//Operator mode switch
+struct CM_OP : Button {
+
+ int *opmode = nullptr;
+ const float opcoords[8] = {10.2, 15.4, 10.2, 5.1, 5.4, 10.5, 15.6, 10.5};
+
+ CM_OP(float x, float y) {
+ box.pos.x = x;
+ box.pos.y = y;
+ };
+
+ void draw(const DrawArgs &args) override {
+ // Background
+ NVGcolor backgroundColor = nvgRGB(0xff, 0xf4, 0x00);
+ nvgBeginPath(args.vg);
+ nvgCircle(args.vg, opcoords[*opmode], opcoords[*opmode + 4], 2.5f);
+ nvgFillColor(args.vg, backgroundColor);
+ nvgFill(args.vg);
+ }
+
+ void onDragStart(const event::DragStart& e) override {
+ *opmode = (*opmode < 3) ? (*opmode + 1) : 0;
+ }
+
+ int getopmode(){
+ return *opmode;
+ }
+};
+
//yellow big led indicator
struct BigLedIndicator : TransparentWidget {
@@ -832,7 +953,7 @@ struct BigLedIndicator : TransparentWidget {
nvgBeginPath(args.vg);
nvgRoundedRect(args.vg, 4.0, 4.0, box.size.x - 8.0, box.size.y - 8.0, 4.0);
nvgFillColor(args.vg, nvgRGB(0xff, 0xf4, 0x00));
- nvgFill(args.vg);;
+ nvgFill(args.vg);
}
}
-};
+};
\ No newline at end of file
diff --git a/src/CatroModulo_CM-1.cpp b/src/CatroModulo_CM-1.cpp
index f654d93..901b884 100644
--- a/src/CatroModulo_CM-1.cpp
+++ b/src/CatroModulo_CM-1.cpp
@@ -11,11 +11,12 @@ struct LowFrequencyOscillator {
float pw = 0.5f;
float freq = 1.0f;
bool invert = false;
+ bool paused = false;
dsp::SchmittTrigger resetTrigger;
LowFrequencyOscillator() {}
void setPitch(float pitch) {
- pitch = fminf(pitch, 13.0f);
+ //pitch = fminf(pitch, 13.0f);
freq = powf(2.0f, pitch);
}
@@ -42,6 +43,9 @@ struct LowFrequencyOscillator {
default : freq = 0; break;
}
}
+ void setPitchU(float multi, float base) {
+ freq = powf(multi, 3.0f) * (base / 240);
+ }
void setPulseWidth(float pw_) {
const float pwMin = 0.01f;
@@ -58,9 +62,14 @@ struct LowFrequencyOscillator {
phase = 0.0f;
}
}
+
+ void pause(bool p) {
+ paused = p;
+ }
+
void step(float dt) {
float deltaPhase = fminf(freq * dt, 0.5f);
- phase += deltaPhase;
+ phase += paused ? 0.0f : deltaPhase;
if (phase >= 1.0f)
phase -= 1.0f;
@@ -94,15 +103,18 @@ struct LowFrequencyOscillator {
//mixing the types
float tmix() {
float tmr = 0.0f;
- if (typemix < 1.0f){
+ if (typemix == 0.0f){
+ tmr = sin();
+ }else if (typemix < 1.0f){
tmr = (1.0f - typemix) * sin() + typemix * tri();
- }else
- if (typemix < 2.0f){
+ }else if (typemix < 2.0f){
typemix -= 1.0f;
tmr = (1.0f - typemix) * tri() + typemix * saw();
- }else {
+ }else if (typemix < 3.0f){
typemix -= 2.0f;
tmr = (1.0f - typemix) * saw() + typemix * sqr();
+ }else{
+ tmr = sqr();
}
return tmr;
}
@@ -122,6 +134,8 @@ struct CM1Module : Module {
ENUMS(PARAM_PHASE, 8),
PARAM_RESET,
PARAM_OFFSET,
+ PARAM_LOCK,
+ PARAM_PAUSE,
NUM_PARAMS
};
enum InputIds {
@@ -131,11 +145,11 @@ struct CM1Module : Module {
ENUMS(INPUT_PHASE, 8),
INPUT_RESET,
INPUT_BPM,
+ INPUT_PAUSE,
NUM_INPUTS
};
enum OutputIds {
ENUMS(OUTPUT_LFO, 8),
- OUTPUT_MIX,
NUM_OUTPUTS
};
enum LightIds {
@@ -153,13 +167,15 @@ struct CM1Module : Module {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
int i = -1;
while(++i < 8){
- configParam(CM1Module::PARAM_TYPE + i , 0.0f, 3.0f, 0.0f, "");
- configParam(CM1Module::PARAM_RATE + i , 0.0f, 1.0f, 0.5f, "");
- configParam(CM1Module::PARAM_PW + i ,0.001f, 1.0f, 0.5f, "");
- configParam(CM1Module::PARAM_PHASE + i , 0.0f , 1.0f, 0.5f, "");
+ configParam(CM1Module::PARAM_TYPE + i , 0.0f, 3.0f, 0.0f, "shape", "", 0.0f, 1.0f, 1.0f);
+ configParam(CM1Module::PARAM_RATE + i , 0.0f, 1.0f, 0.5f, "rate", "", 0.0f, 16.0f, -8.0f);
+ configParam(CM1Module::PARAM_PW + i ,0.001f, 1.0f, 0.5f, "pulse width", "%", 0.0f, 100.0f);
+ configParam(CM1Module::PARAM_PHASE + i , 0.0f , 1.0f, 0.5f, "phase", "°", 0.0f, 360.0f, -180.0f);
}
- configParam(CM1Module::PARAM_RESET, 0.0f, 1.0f, 0.0f, "");
- configParam(CM1Module::PARAM_OFFSET, 0.0f, 1.0f, 0.0f, "");
+ configParam(CM1Module::PARAM_RESET, 0.0f, 1.0f, 0.0f, "reset");
+ configParam(CM1Module::PARAM_OFFSET, 0.0f, 1.0f, 0.0f, "offset", "V", 0.0f, 5.0f);
+ configParam(CM1Module::PARAM_LOCK, 0.0f, 1.0f, 0.0f, "lock", "", 0.0f, -1.0f, 1.0f);
+ configParam(CM1Module::PARAM_PAUSE, 0.0f, 1.0f, 0.0f, "pause");
}
void process(const ProcessArgs &args) override;
@@ -173,9 +189,9 @@ struct CM1Module : Module {
//Tarzan - this is for TJ :)
void CM1Module::process(const ProcessArgs &args) {
- float mixOut = 0.0f;
float offset = 5.0f * params[PARAM_OFFSET].getValue();
float reset = (inputs[INPUT_RESET].getVoltage() || params[PARAM_RESET].getValue());
+ bool paused = (inputs[INPUT_PAUSE].getVoltage() || params[PARAM_PAUSE].getValue());
if (inputs[INPUT_BPM].isConnected()){
lfoclock.setcv(inputs[INPUT_BPM].getVoltage());
@@ -191,18 +207,27 @@ void CM1Module::process(const ProcessArgs &args) {
float mod_one = clamp((inputs[INPUT_TYPE + i].isConnected()) ? params[PARAM_TYPE + i].getValue() * inputs[INPUT_TYPE + i].getVoltage() * 0.1f : params[PARAM_TYPE + i].getValue(), 0.0f, 3.0f); //TYPE
float mod_two;
if (synced == true){
- mod_two = roundf(clamp((inputs[INPUT_RATE + i].isConnected()) ? (params[PARAM_RATE + i].getValue() * 16.0 - 8.0) + (clamp(inputs[INPUT_RATE + i].getVoltage() * 0.1, -1.0f, 1.0f) * 8) : params[PARAM_RATE + i].getValue() * 16.0 - 8.0 , -8.0f, 8.0f)); //RATE
+ if (params[PARAM_LOCK].getValue() == 0){
+ mod_two = roundf(clamp((inputs[INPUT_RATE + i].isConnected()) ? (params[PARAM_RATE + i].getValue() * 16.0f - 8.0f) + (inputs[INPUT_RATE + i].getVoltage() * 0.8f) : params[PARAM_RATE + i].getValue() * 16.0f - 8.0f , -8.0f, 8.0f)); //RATE;
+ }else{
+ mod_two = clamp((inputs[INPUT_RATE + i].isConnected()) ? (params[PARAM_RATE + i].getValue() * 2.0f) + (inputs[INPUT_RATE + i].getVoltage() * 0.2f) : params[PARAM_RATE + i].getValue() * 2.0f , 0.0f, 4.0f); //RATE
+ }
}else{
- mod_two = clamp((inputs[INPUT_RATE + i].isConnected()) ? (params[PARAM_RATE + i].getValue() * 21.0 - 8.0) + (clamp(inputs[INPUT_RATE + i].getVoltage() * 0.1, -1.0f, 1.0f) * 21) : params[PARAM_RATE + i].getValue() * 21.0 - 8.0 , -8.0f, 13.0f); //RATE
+ mod_two = clamp((inputs[INPUT_RATE + i].isConnected()) ? (params[PARAM_RATE + i].getValue() * 21.0 - 8.0) + (inputs[INPUT_RATE + i].getVoltage() * 2.1) : params[PARAM_RATE + i].getValue() * 21.0 - 8.0 , -8.0f, 13.0f); //RATE
}
float mod_thr = clamp((inputs[INPUT_PW + i].isConnected()) ? params[PARAM_PW + i].getValue() * (1.0 + inputs[INPUT_PW + i].getVoltage()) * 0.05f : params[PARAM_PW + i].getValue(), 0.0f, 1.0f); //PW
float mod_fou = clamp((inputs[INPUT_PHASE + i].isConnected()) ? params[PARAM_PHASE + i].getValue() + inputs[INPUT_PHASE + i].getVoltage() * 0.1f : params[PARAM_PHASE + i].getValue(), 0.0f, 1.0f); //PHASE
//set lfo mods
+ lfo[i].pause(paused);
lfo[i].setMix(mod_one);
if (synced == true){
- lfo[i].setPitch(mod_two, lfoclock.getbpm());
+ if (params[PARAM_LOCK].getValue()){
+ lfo[i].setPitchU(mod_two, lfoclock.getbpm());
+ }else{
+ lfo[i].setPitch(mod_two, lfoclock.getbpm());
+ }
}else{
lfo[i].setPitch(mod_two);
}
@@ -215,15 +240,12 @@ void CM1Module::process(const ProcessArgs &args) {
out = 5.0f * lfo[i].tmix() + offset;
outputs[OUTPUT_LFO + i].setVoltage(clamp(out, -10.0f, 10.0f) );
- mixOut += out;
}else{
out = 0.0f;
outputs[OUTPUT_LFO + i].setVoltage(0);
}
}
- //mixed output
- outputs[OUTPUT_MIX].setVoltage(mixOut * 0.125f);
}
@@ -267,6 +289,10 @@ struct CM1ModuleWidget : ModuleWidget {
//RESET
addParam(createParam(Vec(8.5, 339.2), module, CM1Module::PARAM_RESET));
addInput(createInput(Vec(17.4, 339.2), module, CM1Module::INPUT_RESET));
+
+ //RESET
+ addParam(createParam(Vec(214.3, 329.3), module, CM1Module::PARAM_PAUSE));
+ addInput(createInput(Vec(223.1, 329.3), module, CM1Module::INPUT_PAUSE));
//OFFSET (+5V)
addParam(createParam(Vec(48.3, 338.7), module, CM1Module::PARAM_OFFSET));
@@ -274,9 +300,8 @@ struct CM1ModuleWidget : ModuleWidget {
//sync (bpm)
addInput(createInput(Vec(70.1, 339.2), module, CM1Module::INPUT_BPM));
- //
- //MIXOUT
- addOutput(createOutput(Vec(188.0, 342.5), module, 8));
+ //synclock
+ addParam(createParam(Vec(100.5, 343.2), module, CM1Module::PARAM_LOCK));
}
diff --git a/src/CatroModulo_CM-1.cpp.bak b/src/CatroModulo_CM-1.cpp.bak
new file mode 100644
index 0000000..f654d93
--- /dev/null
+++ b/src/CatroModulo_CM-1.cpp.bak
@@ -0,0 +1,290 @@
+#include "CatroModulo.hpp"
+//#include "dsp/minblep.hpp" //got to figure this out...
+
+//Catro-Module 8xlfo
+
+struct LowFrequencyOscillator {
+
+ float phase = 0.0f;
+ float pshift = 0.0f;
+ float typemix = 0.0f;
+ float pw = 0.5f;
+ float freq = 1.0f;
+ bool invert = false;
+ dsp::SchmittTrigger resetTrigger;
+
+ LowFrequencyOscillator() {}
+ void setPitch(float pitch) {
+ pitch = fminf(pitch, 13.0f);
+ freq = powf(2.0f, pitch);
+ }
+
+ void setPitch(int multi, float base) {
+ switch (multi){
+ case -8 : freq = base / 7680 ; break;
+ case -7 : freq = base / 3840 ; break;
+ case -6 : freq = base / 1920 ; break;
+ case -5 : freq = base / 1440 ; break;
+ case -4 : freq = base / 960 ; break;
+ case -3 : freq = base / 720 ; break;
+ case -2 : freq = base / 480 ; break;
+ case -1 : freq = base / 360 ; break;
+ case 0 : freq = base / 240 ; break;
+ case 1 : freq = base / 120 ; break;
+ case 2 : freq = base / 60 ; break;
+ case 3 : freq = base / 30 ; break;
+ case 4 : freq = base / 15 ; break;
+ case 5 : freq = base / 10 ; break;
+ case 6 : freq = base / 7.5 ; break;
+ case 7 : freq = base / 5 ; break;
+ case 8 : freq = base / 2.5 ; break;
+
+ default : freq = 0; break;
+ }
+ }
+
+ void setPulseWidth(float pw_) {
+ const float pwMin = 0.01f;
+ pw = clamp(pw_, pwMin, 1.0f - pwMin);
+ }
+ void setShift(float ps){
+ pshift = ps;
+ }
+ void setMix(float sm){
+ typemix = sm;
+ }
+ void setReset(float reset) {
+ if (resetTrigger.process(reset * 100)) {
+ phase = 0.0f;
+ }
+ }
+ void step(float dt) {
+ float deltaPhase = fminf(freq * dt, 0.5f);
+ phase += deltaPhase;
+ if (phase >= 1.0f)
+ phase -= 1.0f;
+
+ pshift += phase;
+ if(pshift >= 1.0f){
+ pshift -= 1.0f;
+ }
+ }
+
+ float sin() {
+ return sinf(2*M_PI * pshift) * (invert ? -1.0f : 1.0f);
+ }
+
+ float tri(float x) {
+ return 4.0f * fabsf(x - roundf(x));
+ }
+ float tri() {
+ return -1.0f + tri(invert ? pshift - 0.25f : pshift - 0.75f);
+ }
+ float saw(float x) {
+ return 2.0f * (x - roundf(x));
+ }
+ float saw() {
+ return saw(pshift) * (invert ? -1.0f : 1.0f);
+ }
+ float sqr() {
+ float sqr = (pshift < pw) ^ invert ? 1.0f : -1.0f;
+ return sqr;
+ }
+
+ //mixing the types
+ float tmix() {
+ float tmr = 0.0f;
+ if (typemix < 1.0f){
+ tmr = (1.0f - typemix) * sin() + typemix * tri();
+ }else
+ if (typemix < 2.0f){
+ typemix -= 1.0f;
+ tmr = (1.0f - typemix) * tri() + typemix * saw();
+ }else {
+ typemix -= 2.0f;
+ tmr = (1.0f - typemix) * saw() + typemix * sqr();
+ }
+ return tmr;
+ }
+
+ // float light() {
+ // return sinf(2*M_PI * pshift);
+ // }
+};
+
+
+
+struct CM1Module : Module {
+ enum ParamIds {
+ ENUMS(PARAM_TYPE, 8),
+ ENUMS(PARAM_RATE, 8),
+ ENUMS(PARAM_PW, 8),
+ ENUMS(PARAM_PHASE, 8),
+ PARAM_RESET,
+ PARAM_OFFSET,
+ NUM_PARAMS
+ };
+ enum InputIds {
+ ENUMS(INPUT_TYPE, 8),
+ ENUMS(INPUT_RATE, 8),
+ ENUMS(INPUT_PW, 8),
+ ENUMS(INPUT_PHASE, 8),
+ INPUT_RESET,
+ INPUT_BPM,
+ NUM_INPUTS
+ };
+ enum OutputIds {
+ ENUMS(OUTPUT_LFO, 8),
+ OUTPUT_MIX,
+ NUM_OUTPUTS
+ };
+ enum LightIds {
+ NUM_LIGHTS = 0
+ };
+
+ //generate 8 lfos
+ LowFrequencyOscillator lfo[8];
+
+ //bpm clock for synced lfo
+ CM_BpmClock lfoclock;
+ bool synced = false;
+
+ CM1Module() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
+ int i = -1;
+ while(++i < 8){
+ configParam(CM1Module::PARAM_TYPE + i , 0.0f, 3.0f, 0.0f, "");
+ configParam(CM1Module::PARAM_RATE + i , 0.0f, 1.0f, 0.5f, "");
+ configParam(CM1Module::PARAM_PW + i ,0.001f, 1.0f, 0.5f, "");
+ configParam(CM1Module::PARAM_PHASE + i , 0.0f , 1.0f, 0.5f, "");
+ }
+ configParam(CM1Module::PARAM_RESET, 0.0f, 1.0f, 0.0f, "");
+ configParam(CM1Module::PARAM_OFFSET, 0.0f, 1.0f, 0.0f, "");
+
+ }
+ void process(const ProcessArgs &args) override;
+
+ // For more advanced Module features, read Rack's engine.hpp header file
+ // - dataToJson, dataFromJson: serialization of internal data
+ // - onSampleRateChange: event triggered by a change of sample rate
+ // - onReset, onRandomize, onCreate, onDelete: implements special behavior when user clicks these from the context menu
+};
+
+//Tarzan - this is for TJ :)
+
+void CM1Module::process(const ProcessArgs &args) {
+ float mixOut = 0.0f;
+ float offset = 5.0f * params[PARAM_OFFSET].getValue();
+ float reset = (inputs[INPUT_RESET].getVoltage() || params[PARAM_RESET].getValue());
+
+ if (inputs[INPUT_BPM].isConnected()){
+ lfoclock.setcv(inputs[INPUT_BPM].getVoltage());
+ synced = true;
+ }else{
+ synced = false;
+ }
+
+ for (int i = 0; i < 8; i++) {
+ float out;
+ if (outputs[OUTPUT_LFO + i].isConnected() == true){
+ //merge modulations
+ float mod_one = clamp((inputs[INPUT_TYPE + i].isConnected()) ? params[PARAM_TYPE + i].getValue() * inputs[INPUT_TYPE + i].getVoltage() * 0.1f : params[PARAM_TYPE + i].getValue(), 0.0f, 3.0f); //TYPE
+ float mod_two;
+ if (synced == true){
+ mod_two = roundf(clamp((inputs[INPUT_RATE + i].isConnected()) ? (params[PARAM_RATE + i].getValue() * 16.0 - 8.0) + (clamp(inputs[INPUT_RATE + i].getVoltage() * 0.1, -1.0f, 1.0f) * 8) : params[PARAM_RATE + i].getValue() * 16.0 - 8.0 , -8.0f, 8.0f)); //RATE
+ }else{
+ mod_two = clamp((inputs[INPUT_RATE + i].isConnected()) ? (params[PARAM_RATE + i].getValue() * 21.0 - 8.0) + (clamp(inputs[INPUT_RATE + i].getVoltage() * 0.1, -1.0f, 1.0f) * 21) : params[PARAM_RATE + i].getValue() * 21.0 - 8.0 , -8.0f, 13.0f); //RATE
+ }
+ float mod_thr = clamp((inputs[INPUT_PW + i].isConnected()) ? params[PARAM_PW + i].getValue() * (1.0 + inputs[INPUT_PW + i].getVoltage()) * 0.05f : params[PARAM_PW + i].getValue(), 0.0f, 1.0f); //PW
+ float mod_fou = clamp((inputs[INPUT_PHASE + i].isConnected()) ? params[PARAM_PHASE + i].getValue() + inputs[INPUT_PHASE + i].getVoltage() * 0.1f : params[PARAM_PHASE + i].getValue(), 0.0f, 1.0f); //PHASE
+
+
+ //set lfo mods
+ lfo[i].setMix(mod_one);
+ if (synced == true){
+ lfo[i].setPitch(mod_two, lfoclock.getbpm());
+ }else{
+ lfo[i].setPitch(mod_two);
+ }
+ lfo[i].setPulseWidth(mod_thr);
+ lfo[i].setShift(mod_fou);
+
+ //run lfo
+ lfo[i].step(args.sampleTime);
+ lfo[i].setReset(reset);
+
+ out = 5.0f * lfo[i].tmix() + offset;
+ outputs[OUTPUT_LFO + i].setVoltage(clamp(out, -10.0f, 10.0f) );
+ mixOut += out;
+ }else{
+ out = 0.0f;
+ outputs[OUTPUT_LFO + i].setVoltage(0);
+ }
+
+ }
+ //mixed output
+ outputs[OUTPUT_MIX].setVoltage(mixOut * 0.125f);
+}
+
+
+struct CM1ModuleWidget : ModuleWidget {
+ CM1ModuleWidget(CM1Module *module) {
+ setModule(module);
+ setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CM-1.svg")));
+
+ addChild(createWidget(Vec(RACK_GRID_WIDTH, 0)));
+ addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
+ addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
+ addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
+
+ //GRID
+ const float gridrowjacks[8] = {35.5, 74.3, 113.1, 151.9, 190.7, 229.5, 268.2, 307};
+ const float gridcoljacks[10] = {3.7, 29.9, 64.8, 94.1, 126.0, 155.1, 186.4, 215.8, 249.2, 278.5};
+
+ int i = -1;
+
+
+ while(++i < 8){
+ //INPUTS
+ addInput(createInput(Vec(gridcoljacks[0], gridrowjacks[i]), module, CM1Module::INPUT_TYPE + i));
+ addInput(createInput(Vec(gridcoljacks[2], gridrowjacks[i]), module, CM1Module::INPUT_RATE + i));
+ addInput(createInput(Vec(gridcoljacks[4], gridrowjacks[i]), module, CM1Module::INPUT_PW + i));
+ addInput(createInput(Vec(gridcoljacks[6], gridrowjacks[i]), module, CM1Module::INPUT_PHASE + i));
+ //POTS
+ addChild(createWidget(Vec(gridcoljacks[1], gridrowjacks[i] - 15.0)));
+ addChild(createWidget(Vec(gridcoljacks[3], gridrowjacks[i] + 7.0)));
+ addChild(createWidget(Vec(gridcoljacks[5], gridrowjacks[i] - 15.0)));
+ addChild(createWidget(Vec(gridcoljacks[7], gridrowjacks[i] - 15.0)));
+ //KNOBS
+ addParam(createParam(Vec(gridcoljacks[1], gridrowjacks[i] - 15.0), module, CM1Module::PARAM_TYPE + i ));
+ addParam(createParam(Vec(gridcoljacks[3], gridrowjacks[i] + 7.0), module, CM1Module::PARAM_RATE + i ));
+ addParam(createParam(Vec(gridcoljacks[5], gridrowjacks[i] - 15.0), module, CM1Module::PARAM_PW + i ));
+ addParam(createParam(Vec(gridcoljacks[7], gridrowjacks[i] - 15.0), module, CM1Module::PARAM_PHASE + i ));
+ //OUTPUTS
+ addOutput(createOutput(Vec(gridcoljacks[8], gridrowjacks[i]), module, CM1Module::OUTPUT_LFO + i));
+ }
+
+ //RESET
+ addParam(createParam(Vec(8.5, 339.2), module, CM1Module::PARAM_RESET));
+ addInput(createInput(Vec(17.4, 339.2), module, CM1Module::INPUT_RESET));
+
+ //OFFSET (+5V)
+ addParam(createParam(Vec(48.3, 338.7), module, CM1Module::PARAM_OFFSET));
+
+ //sync (bpm)
+ addInput(createInput(Vec(70.1, 339.2), module, CM1Module::INPUT_BPM));
+
+ //
+ //MIXOUT
+ addOutput(createOutput(Vec(188.0, 342.5), module, 8));
+
+
+ }
+};
+
+
+// Specify the Module and ModuleWidget subclass, human-readable
+// author name for categorization per pluginInstance, module slug (should never
+// change), human-readable module name, and any number of tags
+// (found in `include/tags.hpp`) separated by commas.
+Model *modelCM1Module = createModel("CatroModulo_CM-1");
diff --git a/src/CatroModulo_CM-10.cpp b/src/CatroModulo_CM-10.cpp
index 1b802d9..c3ec514 100644
--- a/src/CatroModulo_CM-10.cpp
+++ b/src/CatroModulo_CM-10.cpp
@@ -39,11 +39,10 @@ struct CM10Module : Module {
CM10Module() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam(CM10Module::PARAM_REC, 0.0, 1.0, 0.0f, "");
- configParam(CM10Module::PARAM_PLAY, 0.0, 1.0, 0.0f, "");
- configParam(CM10Module::PARAM_REC + 1, 0.0, 1.0, 0.0f, "");
- configParam(CM10Module::PARAM_PLAY + 1, 0.0, 1.0, 0.0f, "");
-
+ configParam(CM10Module::PARAM_REC, 0.0, 1.0, 0.0f, "capture");
+ configParam(CM10Module::PARAM_PLAY, 0.0, 1.0, 0.0f, "override");
+ configParam(CM10Module::PARAM_REC + 1, 0.0, 1.0, 0.0f, "capture");
+ configParam(CM10Module::PARAM_PLAY + 1, 0.0, 1.0, 0.0f, "override");
}
void process(const ProcessArgs &args) override;
diff --git a/src/CatroModulo_CM-2.cpp b/src/CatroModulo_CM-2.cpp
index 0296d3c..62f91a3 100644
--- a/src/CatroModulo_CM-2.cpp
+++ b/src/CatroModulo_CM-2.cpp
@@ -27,23 +27,23 @@ struct CM2Module : Module {
CM2Module() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam(CM2Module::PARAMS_ATN + 0, -1.0f, 1.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_ATN + 1, -1.0f, 1.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_ATN + 2, -1.0f, 1.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_ATN + 3, -1.0f, 1.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_ATN + 4, -1.0f, 1.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_ATN + 5, -1.0f, 1.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_ATN + 6, -1.0f, 1.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_ATN + 7, -1.0f, 1.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_OFF + 0, -5.0f, 5.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_OFF + 1, -5.0f, 5.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_OFF + 2, -5.0f, 5.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_OFF + 3, -5.0f, 5.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_OFF + 4, -5.0f, 5.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_OFF + 5, -5.0f, 5.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_OFF + 6, -5.0f, 5.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_OFF + 7, -5.0f, 5.0f, 0.0f, "");
- configParam(CM2Module::PARAMS_X2, 1.0f, 2.0f, 1.0f, "");
+ configParam(CM2Module::PARAMS_ATN + 0, -1.0f, 1.0f, 0.0f, "attenuate", "%", 0.0f, 100.0f);
+ configParam(CM2Module::PARAMS_ATN + 1, -1.0f, 1.0f, 0.0f, "attenuate", "%", 0.0f, 100.0f);
+ configParam(CM2Module::PARAMS_ATN + 2, -1.0f, 1.0f, 0.0f, "attenuate", "%", 0.0f, 100.0f);
+ configParam(CM2Module::PARAMS_ATN + 3, -1.0f, 1.0f, 0.0f, "attenuate", "%", 0.0f, 100.0f);
+ configParam(CM2Module::PARAMS_ATN + 4, -1.0f, 1.0f, 0.0f, "attenuate", "%", 0.0f, 100.0f);
+ configParam(CM2Module::PARAMS_ATN + 5, -1.0f, 1.0f, 0.0f, "attenuate", "%", 0.0f, 100.0f);
+ configParam(CM2Module::PARAMS_ATN + 6, -1.0f, 1.0f, 0.0f, "attenuate", "%", 0.0f, 100.0f);
+ configParam(CM2Module::PARAMS_ATN + 7, -1.0f, 1.0f, 0.0f, "attenuate", "%", 0.0f, 100.0f);
+ configParam(CM2Module::PARAMS_OFF + 0, -5.0f, 5.0f, 0.0f, "offset", "V");
+ configParam(CM2Module::PARAMS_OFF + 1, -5.0f, 5.0f, 0.0f, "offset", "V");
+ configParam(CM2Module::PARAMS_OFF + 2, -5.0f, 5.0f, 0.0f, "offset", "V");
+ configParam(CM2Module::PARAMS_OFF + 3, -5.0f, 5.0f, 0.0f, "offset", "V");
+ configParam(CM2Module::PARAMS_OFF + 4, -5.0f, 5.0f, 0.0f, "offset", "V");
+ configParam(CM2Module::PARAMS_OFF + 5, -5.0f, 5.0f, 0.0f, "offset", "V");
+ configParam(CM2Module::PARAMS_OFF + 6, -5.0f, 5.0f, 0.0f, "offset", "V");
+ configParam(CM2Module::PARAMS_OFF + 7, -5.0f, 5.0f, 0.0f, "offset", "V");
+ configParam(CM2Module::PARAMS_X2, 1.0f, 2.0f, 1.0f, "output multiplier");
}
void process(const ProcessArgs &args) override;
diff --git a/src/CatroModulo_CM-3.cpp b/src/CatroModulo_CM-3.cpp
index f78cb73..d4beeb4 100644
--- a/src/CatroModulo_CM-3.cpp
+++ b/src/CatroModulo_CM-3.cpp
@@ -64,20 +64,20 @@ struct CM3Module : Module {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
int y = 0;
for(int i = 0; i < 16; i += 2){
- configParam(CM3Module::PARAM_REC + y, 0.0f, 1.0f, 0.0f, "");
- configParam(CM3Module::PARAM_EYE + y, -1.0f, 1.0f, 0.0f, "");
+ configParam(CM3Module::PARAM_REC + y, 0.0f, 1.0f, 0.0f, "record values in slot " + std::to_string(y + 1));
+ configParam(CM3Module::PARAM_EYE + y, -1.0f, 1.0f, 0.0f, "value " + std::to_string(y + 1), "", 0.0f, 100.0f);
y++;
}
- configParam(CM3Module::PARAM_PATTERN, 0.0f, 15.0f, 0.0f, "");
- configParam(CM3Module::PARAM_MORPH, -1.0f, 1.0f, 0.0f, "");
- configParam(CM3Module::PARAM_LENGTH, 0.0f, 15.0f, 7.0f, "");
- configParam(CM3Module::PARAM_TRYME, 0.0f, 1.0f, 0.0f, "");
- configParam(CM3Module::PARAM_SCAN, 0.0f, 1.0f, 0.0f, "");
- configParam(CM3Module::PARAM_SELECT, 0.0f, 7.99999f, 0.0f, "");
- configParam(CM3Module::PARAM_SEQ, 0.0f, 1.0f, 1.0f, "");
- configParam(CM3Module::PARAM_RESET, 0.0f, 1.0f, 0.0f, "");
- configParam(CM3Module::PARAM_STEP, 0.0f, 1.0f, 0.0f, "");
+ configParam(CM3Module::PARAM_PATTERN, 0.0f, 15.0f, 0.0f, "pattern select", "", 0.0f, 1.0f, 1.0f);
+ configParam(CM3Module::PARAM_MORPH, -1.0f, 1.0f, 0.0f, "(multiplied < source > recording)");
+ configParam(CM3Module::PARAM_LENGTH, 0.0f, 15.0f, 7.0f, "pattern lenght", "", 0.0f, 1.0f, 1.0f);
+ configParam(CM3Module::PARAM_TRYME, 0.0f, 1.0f, 0.0f, "randomize (!)");
+ configParam(CM3Module::PARAM_SCAN, 0.0f, 1.0f, 0.0f, "enable scan/blend");
+ configParam(CM3Module::PARAM_SELECT, 0.0f, 7.99999f, 0.0f, "select recording for output");
+ configParam(CM3Module::PARAM_SEQ, 0.0f, 1.0f, 1.0f, "enable sequencer", "", 0.0f, -1.0f, 1.0f);
+ configParam(CM3Module::PARAM_RESET, 0.0f, 1.0f, 0.0f, "reset");
+ configParam(CM3Module::PARAM_STEP, 0.0f, 1.0f, 0.0f, "step");
recball_x = recball_xarray[0];
recball_y = recball_yarray[0];
@@ -300,9 +300,9 @@ struct CM3ModuleWidget : ModuleWidget {
}
//OTHER ELEMENTS
- addParam(createParam(Vec(33.4 , 34.7), module, CM3Module::PARAM_PATTERN));
+ addParam(createParam(Vec(33.4 , 34.7), module, CM3Module::PARAM_PATTERN));
addParam(createParam(Vec(156.5 , 17.9), module, CM3Module::PARAM_MORPH));
- addParam(createParam(Vec(326.0 , 34.7), module, CM3Module::PARAM_LENGTH));
+ addParam(createParam(Vec(326.0 , 34.7), module, CM3Module::PARAM_LENGTH));
addParam(createParam(Vec(15.0 , 320.1), module, CM3Module::PARAM_TRYME));
addParam(createParam(Vec(137.8 , 309.0), module, CM3Module::PARAM_SCAN));
addParam(createParam(Vec(161.3 , 286.0), module, CM3Module::PARAM_SELECT));
diff --git a/src/CatroModulo_CM-4.cpp b/src/CatroModulo_CM-4.cpp
index 63f4224..db18c03 100644
--- a/src/CatroModulo_CM-4.cpp
+++ b/src/CatroModulo_CM-4.cpp
@@ -12,9 +12,8 @@ struct CM4Module : Module {
NUM_PARAMS
};
enum InputIds {
- INPUT_BPM1,
- INPUT_BPM2,
- INPUT_BPM3,
+ INPUT_EXT,
+ INPUT_BPM,
INPUT_RST,
NUM_INPUTS
};
@@ -35,14 +34,14 @@ struct CM4Module : Module {
float bpm_display = 0.0;
//create objects
- //dsp::SchmittTrigger recordTrigger[16];
CM_BpmClock bpmclock;
+ bool isreset = false;
CM4Module() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam(CM4Module::PARAM_BPM, 0.0f, 6.0, 0.0f, "");
- configParam(CM4Module::PARAM_SNAP, 0.0f, 2.0f, 1.0f, "");
- configParam(CM4Module::PARAM_RST, 0.0f, 1.0f, 0.0f, "");
+ configParam(CM4Module::PARAM_BPM, 0.0f, 5.0, 0.0f, "tempo", " BPM", 0.0f, 100.0f);
+ configParam(CM4Module::PARAM_SNAP, 0.0f, 2.0f, 1.0f, "snap");
+ configParam(CM4Module::PARAM_RST, 0.0f, 1.0f, 0.0f, "reset");
//initialize objects
}
@@ -51,22 +50,40 @@ struct CM4Module : Module {
void CM4Module::process(const ProcessArgs &args) {
if (params[PARAM_SNAP].getValue() == 0){
- bpmclock.setbpm(int( (params[PARAM_BPM].getValue() * 100.0) * 50) / 50.0f );
+ bpmclock.setbpm(int( (params[PARAM_BPM].getValue() * 100.0) * 100) / 100.0f );
}else if (params[PARAM_SNAP].getValue() == 1){
- bpmclock.setbpm(int( (params[PARAM_BPM].getValue() * 100.0) * 0.5) * 2.0f);
+ bpmclock.setbpm(int(params[PARAM_BPM].getValue() * 100.0));
}else if (params[PARAM_SNAP].getValue() == 2){
- bpmclock.setbpm(int( (params[PARAM_BPM].getValue() * 100.0) * 0.1) * 10.0f );
+ bpmclock.setbpm(int( (params[PARAM_BPM].getValue() * 100.0) * 0.2) * 5.0f );
}
-
+
outputs[OUTPUT_RST].setVoltage((inputs[INPUT_RST].getVoltage() || params[PARAM_RST].getValue()) * 10.0);
- bpmclock.setReset(outputs[OUTPUT_RST].value);
+ bpmclock.setReset(outputs[OUTPUT_RST].getVoltage());
- outputs[OUTPUT_BPM1].setVoltage(bpmclock.addcv((inputs[INPUT_BPM1].isConnected()) ? inputs[INPUT_BPM1].getVoltage() : 0.0f));
- outputs[OUTPUT_BPM2].setVoltage(bpmclock.addcv((inputs[INPUT_BPM2].isConnected()) ? inputs[INPUT_BPM2].getVoltage() : 0.0f));
+ //external clock
+ if (inputs[INPUT_EXT].isConnected()){
+ float extcv = bpmclock.exttrack(inputs[INPUT_EXT].getVoltage(), args.sampleTime);
+ //extcv = (extcv > 0) ? (1.0f / extcv) * (60000.0f / args.sampleRate ) : 0.0f;//* 1.211387038158690f : 0.0f;
+ if (params[PARAM_SNAP].getValue() == 0){
+ bpmclock.addcv(bpmclock.bpmtocv(0.01) * roundf(extcv * 10000.0f));
+ }else if (params[PARAM_SNAP].getValue() == 1){
+ bpmclock.addcv(bpmclock.bpmtocv(1) * roundf(extcv * 100.0f));
+ }else if (params[PARAM_SNAP].getValue() == 2){
+ bpmclock.addcv(bpmclock.bpmtocv(5) * roundf(extcv * 20.0f));
+ }
+ isreset = false;
+ }else if (isreset == false){
+ bpmclock.extreset(true);
+ isreset = true;
+ }
+ outputs[OUTPUT_BPM1].setVoltage(bpmclock.getcv());
+
+ //add bpm cv
+ outputs[OUTPUT_BPM2].setVoltage(bpmclock.addcv((inputs[INPUT_BPM].isConnected()) ? inputs[INPUT_BPM].getVoltage() : 0.0f));
outputs[OUTPUT_D2].setVoltage(bpmclock.getcv() * 0.5);
outputs[OUTPUT_X2].setVoltage(bpmclock.getcv() * 2.0);
- bpm_display = bpmclock.getbpm() / 2.0f;
+ bpm_display = bpmclock.getbpm();
bpmclock.step(args.sampleTime);
@@ -90,8 +107,8 @@ struct CM4ModuleWidget : ModuleWidget {
addParam(createParam(Vec(3.6 , 56.0), module, CM4Module::PARAM_BPM));
addParam(createParam(Vec(7.0, 43.0), module, CM4Module::PARAM_SNAP));
- addInput(createInput(Vec(7.0 , 126.3), module, CM4Module::INPUT_BPM1));
- addInput(createInput(Vec(7.0 , 169.1), module, CM4Module::INPUT_BPM2));
+ addInput(createInput(Vec(0.0 , 126.3), module, CM4Module::INPUT_EXT));
+ addInput(createInput(Vec(7.0 , 169.1), module, CM4Module::INPUT_BPM));
addOutput(createOutput(Vec(44.4 , 126.3), module, CM4Module::OUTPUT_BPM1));
addOutput(createOutput(Vec(44.4 , 169.1), module, CM4Module::OUTPUT_BPM2));
diff --git a/src/CatroModulo_CM-4.cpp.bak2 b/src/CatroModulo_CM-4.cpp.bak2
new file mode 100644
index 0000000..107fb7f
--- /dev/null
+++ b/src/CatroModulo_CM-4.cpp.bak2
@@ -0,0 +1,145 @@
+#include "CatroModulo.hpp"
+
+
+//Catro-Module CM-4: vcClk
+
+struct CM4Module : Module {
+
+ enum ParamIds {
+ PARAM_BPM,
+ PARAM_RST,
+ PARAM_SNAP,
+ NUM_PARAMS
+ };
+ enum InputIds {
+ INPUT_EXT,
+ INPUT_BPM,
+ INPUT_RST,
+ NUM_INPUTS
+ };
+ enum OutputIds {
+ OUTPUT_BPM1,
+ OUTPUT_BPM2,
+ OUTPUT_D2,
+ OUTPUT_X2,
+ OUTPUT_CLKD2,
+ OUTPUT_CLK,
+ OUTPUT_CLKX2,
+ OUTPUT_RST,
+ NUM_OUTPUTS
+ };
+ enum LightIds {
+ NUM_LIGHTS
+ };
+
+ float bpm_display = 0.0;
+ bool extconnect = false;
+ //create objects
+ CM_BpmClock bpmclock;
+
+ CM4Module() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
+ configParam(CM4Module::PARAM_BPM, 0.0f, 6.0, 0.0f, "BPM", "", 0.0f, 50.0f);
+ configParam(CM4Module::PARAM_SNAP, 0.0f, 2.0f, 1.0f, "snap");
+ configParam(CM4Module::PARAM_RST, 0.0f, 1.0f, 0.0f, "reset");
+
+ //initialize objects
+ }
+ void process(const ProcessArgs &args) override;
+};
+
+void CM4Module::process(const ProcessArgs &args) {
+ if (params[PARAM_SNAP].getValue() == 0){
+ bpmclock.setbpm(bpmclock.cvtobpm(int((params[PARAM_BPM].getValue() * 100.0) * 100) / 100.0f));
+ }else if (params[PARAM_SNAP].getValue() == 1){
+ bpmclock.setbpm(int(params[PARAM_BPM].getValue() * 100.0));
+ }else if (params[PARAM_SNAP].getValue() == 2){
+ bpmclock.setbpm(int( (params[PARAM_BPM].getValue() * 100.0) * 0.2) * 5.0f );
+ }
+
+ outputs[OUTPUT_RST].setVoltage((inputs[INPUT_RST].getVoltage() || params[PARAM_RST].getValue()) * 10.0);
+ bpmclock.setReset(outputs[OUTPUT_RST].value);
+
+ //external clock
+ if (inputs[INPUT_EXT].isConnected()){
+ float extcv = bpmclock.exttrack(inputs[INPUT_EXT].getVoltage(), args.sampleTime);
+ extcv = (extcv > 0.35) ? (1.0f / extcv) * 1.211387038158690f : 0.0f;
+ if (params[PARAM_SNAP].getValue() == 0){
+ bpmclock.addcv(extcv);
+ }else if (params[PARAM_SNAP].getValue() == 1){
+ bpmclock.addcv(bpmclock.bpmtocv(2) * roundf(extcv * 50.0f));
+ }else if (params[PARAM_SNAP].getValue() == 2){
+ bpmclock.addcv(bpmclock.bpmtocv(10) * roundf(extcv * 10.0f));
+ extconnect = true;
+ }
+ }else if (extconnect == true){
+ bpmclock.extreset(true);
+ extconnect = false;
+ }
+ outputs[OUTPUT_BPM1].setVoltage(bpmclock.getcv());
+
+ //add bpm cv
+ outputs[OUTPUT_BPM2].setVoltage(bpmclock.addcv((inputs[INPUT_BPM].isConnected()) ? inputs[INPUT_BPM].getVoltage() : 0.0f));
+
+ outputs[OUTPUT_D2].setVoltage(bpmclock.getcv() * 0.5);
+ outputs[OUTPUT_X2].setVoltage(bpmclock.getcv() * 2.0);
+ // bpm_display = bpmclock.getbpm() / 2.0f;
+ bpm_display = bpmclock.debug(); //temp debugging output
+
+ bpmclock.step(args.sampleTime);
+
+ outputs[OUTPUT_CLK].setVoltage(bpmclock.track(1) * 10.0);
+ outputs[OUTPUT_CLKD2].setVoltage(bpmclock.track(2) * 10.0);
+ outputs[OUTPUT_CLKX2].setVoltage(bpmclock.track(0) * 10.0);
+}
+
+struct CM4ModuleWidget : ModuleWidget {
+
+ CM4ModuleWidget(CM4Module *module) {
+ setModule(module);
+ setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CM-4.svg")));
+
+ //addChild(createWidget(Vec(30, 0)));
+ addChild(createWidget(Vec(box.size.x - 16, 0)));
+ addChild(createWidget(Vec(5, 365)));
+ // addChild(createWidget(Vec(box.size.x - 60, 365)));
+
+ //UNIQUE ELEMENTS
+ addParam(createParam(Vec(3.6 , 56.0), module, CM4Module::PARAM_BPM));
+ addParam(createParam(Vec(7.0, 43.0), module, CM4Module::PARAM_SNAP));
+
+ addInput(createInput(Vec(0.0 , 126.3), module, CM4Module::INPUT_EXT));
+ addInput(createInput(Vec(7.0 , 169.1), module, CM4Module::INPUT_BPM));
+
+ addOutput(createOutput(Vec(44.4 , 126.3), module, CM4Module::OUTPUT_BPM1));
+ addOutput(createOutput(Vec(44.4 , 169.1), module, CM4Module::OUTPUT_BPM2));
+
+ addOutput(createOutput(Vec(7.0 , 212.0), module, CM4Module::OUTPUT_D2));
+ addOutput(createOutput(Vec(44.4 , 212.0), module, CM4Module::OUTPUT_X2));
+
+ addOutput(createOutput(Vec(26.1 , 293.9), module, CM4Module::OUTPUT_CLK));
+ addOutput(createOutput(Vec(3.5 , 326.5), module, CM4Module::OUTPUT_CLKD2));
+ addOutput(createOutput(Vec(48.1 , 326.5), module, CM4Module::OUTPUT_CLKX2));
+
+ addInput(createInput(Vec(6.2 , 251.8), module, CM4Module::INPUT_RST));
+ addParam(createParam(Vec(29.4 , 251.8), module, CM4Module::PARAM_RST));
+ addOutput(createOutput(Vec(52.4 , 251.8), module, CM4Module::OUTPUT_RST));
+
+ if (module)
+ {
+ //LCD display
+ NumDisplayWidget *display = new NumDisplayWidget();
+ display->box.pos = Vec(7.0, 21.0);
+ display->box.size = Vec(61.1, 20.4);
+ display->value = &module->bpm_display;
+ addChild(display);
+ }
+ }
+};
+
+
+// Specify the Module and ModuleWidget subclass, human-readable
+// author name for categorization per pluginInstance, module slug (should never
+// change), human-readable module name, and any number of tags
+// (found in `include/tags.hpp`) separated by commas.
+Model *modelCM4Module = createModel("CatroModulo_CM-4");
diff --git a/src/CatroModulo_CM-5.cpp b/src/CatroModulo_CM-5.cpp
index 580a09f..afd492f 100644
--- a/src/CatroModulo_CM-5.cpp
+++ b/src/CatroModulo_CM-5.cpp
@@ -47,7 +47,7 @@ struct CM5Module : Module {
CM5Module() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam(CM5Module::PARAM_RST, 0.0f, 1.0f, 0.0f, "");
+ configParam(CM5Module::PARAM_RST, 0.0f, 1.0f, 0.0f, "reset");
//initialize objects
}
void process(const ProcessArgs &args) override;
diff --git a/src/CatroModulo_CM-7.cpp b/src/CatroModulo_CM-7.cpp
index 3f24a0a..d0c45d1 100644
--- a/src/CatroModulo_CM-7.cpp
+++ b/src/CatroModulo_CM-7.cpp
@@ -47,7 +47,7 @@ struct CM7Module : Module {
CM7Module() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam(CM7Module::PARAM_RST, 0.0f, 1.0f, 0.0f, "");
+ configParam(CM7Module::PARAM_RST, 0.0f, 1.0f, 0.0f, "reset");
//initialize objects
}
void process(const ProcessArgs &args) override;
diff --git a/src/CatroModulo_CM-8.cpp b/src/CatroModulo_CM-8.cpp
index a4ea61c..e94eda0 100644
--- a/src/CatroModulo_CM-8.cpp
+++ b/src/CatroModulo_CM-8.cpp
@@ -10,6 +10,7 @@ struct CM8Module : Module {
PARAM__b,
PARAM_CIA,
PARAM_BMODE,
+ PARAM_NORMALIZE,
NUM_PARAMS
};
enum InputIds {
@@ -70,10 +71,11 @@ struct CM8Module : Module {
CM8Module() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam(CM8Module::PARAM__a, -10.0, 10.0, 0.0f, "Lower treshold");
- configParam(CM8Module::PARAM__b, -10.0, 10.0, 0.0f, "Upper treshold");
- configParam(CM8Module::PARAM_CIA, 0.0f, 2.0f, 0.0f, "Centered - Inversing - Additive");
- configParam(CM8Module::PARAM_BMODE, 0.0f, 1.0f, 0.0f, "Binary mode");
+ configParam(CM8Module::PARAM__a, -10.0, 10.0, 0.0f, "lower treshold", "V");
+ configParam(CM8Module::PARAM__b, -10.0, 10.0, 0.0f, "upper treshold", "V");
+ configParam(CM8Module::PARAM_CIA, 0.0f, 2.0f, 0.0f, "centered < inversing > additive");
+ configParam(CM8Module::PARAM_BMODE, 0.0f, 1.0f, 0.0f, "binary mode");
+ configParam(CM8Module::PARAM_NORMALIZE, 0.0f, 1.0f, 0.0f, "normalize waveshapers");
srand(time(NULL));
cia = 1;
@@ -149,8 +151,8 @@ void CM8Module::process(const ProcessArgs &args) {
//A
outputs[OUTPUT_ALTB].setVoltage((binA > binB) * 10.0);
outputs[OUTPUT_AISB].setVoltage((binA == binB) * 10.0);
- outputs[OUTPUT_ACLM].setVoltage(cm_clamp(binA, lo, hi));
- outputs[OUTPUT_AFLD].setVoltage(cm_fold(binA, lo, hi));
+ outputs[OUTPUT_ACLM].setVoltage(cm_clamp(binA, lo, hi, params[PARAM_NORMALIZE].getValue()));
+ outputs[OUTPUT_AFLD].setVoltage(cm_fold(binA, lo, hi, params[PARAM_NORMALIZE].getValue()));
outputs[OUTPUT_ALO].setVoltage((currentA < lo) * 10.0);
outputs[OUTPUT_AHI].setVoltage((currentA > hi) * 10.0);
outputs[OUTPUT_ARNG].setVoltage((currentA >= lo && currentA <= hi) * 10.0);
@@ -158,8 +160,8 @@ void CM8Module::process(const ProcessArgs &args) {
//B
outputs[OUTPUT_BLTA].setVoltage((binA < binB) * 10.0);
outputs[OUTPUT_ANTB].setVoltage(!(binA == binB) * 10.0);
- outputs[OUTPUT_BCLM].setVoltage(cm_clamp(binB, lo, hi));
- outputs[OUTPUT_BFLD].setVoltage(cm_fold(binB, lo, hi));
+ outputs[OUTPUT_BCLM].setVoltage(cm_clamp(binB, lo, hi, params[PARAM_NORMALIZE].getValue()));
+ outputs[OUTPUT_BFLD].setVoltage(cm_fold(binB, lo, hi, params[PARAM_NORMALIZE].getValue()));
outputs[OUTPUT_BLO].setVoltage((currentB < lo) * 10.0);
outputs[OUTPUT_BHI].setVoltage((currentB > hi) * 10.0);
outputs[OUTPUT_BRNG].setVoltage((currentB >= lo && currentB <= hi) * 10.0);
@@ -191,6 +193,7 @@ struct CM8ModuleWidget : ModuleWidget {
addParam(createParam(Vec(16.4, 103.3), module, CM8Module::PARAM_CIA));
addParam(createParam(Vec(5.0, 117.2), module, CM8Module::PARAM_BMODE));
addInput(createInput(Vec(54.0 , 112.7), module, CM8Module::INPUT_SNH));
+ addParam(createParam(Vec(25.0 , 241.3), module, CM8Module::PARAM_NORMALIZE));
float a = 5.4;
float b = 46.0;
diff --git a/src/CatroModulo_CM-9.cpp b/src/CatroModulo_CM-9.cpp
index f937e5e..444ee1d 100644
--- a/src/CatroModulo_CM-9.cpp
+++ b/src/CatroModulo_CM-9.cpp
@@ -45,18 +45,41 @@ struct CM9Module : Module {
float ins[8];
float outs[8];
bool gatemode = 0;
+ int opmode = 0;
CM9Module() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam(CM9Module::PARAM_SEL, 0.0, 7.0, 0.0f, "");
-
+ configParam(CM9Module::PARAM_SEL, 0.0, 7.0, 0.0f, "selector", "", 0.0f, 1.0f, 1.0f);
}
void process(const ProcessArgs &args) override;
+ void onReset() override{
+ opmode = 0;
+ }
+
+ json_t *dataToJson() override {
+
+ json_t *rootJ = json_object();
+ json_t *opmodeJ = json_array();
+ json_array_append_new(opmodeJ, json_integer(opmode));
+ json_object_set_new(rootJ, "opmode", opmodeJ);
+
+ return rootJ;
+ }
+
+
+ void dataFromJson(json_t *rootJ) override {
+ // load opmode
+ json_t *opmodeJ = json_object_get(rootJ, "opmode");
+ opmode = json_integer_value(json_array_get(opmodeJ, 0));
+ }
};
void CM9Module::process(const ProcessArgs &args) {
+
+ gatemode = true;
+
//process inputs
int inputsconnected = 0;
for (int i = 0; i < 8; i++){
@@ -64,10 +87,11 @@ void CM9Module::process(const ProcessArgs &args) {
inputsconnected++;
ins[i] = inputs[INPUT_IN + i].getVoltage();
}else{
- ins[i] = 10.0;
+ ins[i] = 0.0f;
}
}
-
+ gatemode = (inputsconnected == 0 && inputs[INPUT_1].isConnected() == false);
+
//process selector
float selectorparam = clamp(round((inputs[INPUT_SEL].isConnected()) ? inputs[INPUT_SEL].getVoltage() * 0.1 * params[PARAM_SEL].getValue() : params[PARAM_SEL].getValue()), 0, 7);
@@ -88,35 +112,69 @@ void CM9Module::process(const ProcessArgs &args) {
//process outputs
//reset all to 0
for (int i = 0; i < NUM_OUTPUTS; i++){
- outputs[OUTPUT_OUT + i].setVoltage(0.0);
+ outputs[OUTPUT_OUT + i].setVoltage(0.0f);
}
- gatemode = true;
+ outputs[OUTPUT_1].setVoltage(selector * 1.4285714285714285714285714285714f);
- if (inputs[INPUT_1].isConnected()){
- outputs[OUTPUT_OUT + selector].setVoltage(inputs[INPUT_1].getVoltage());
- gatemode = false;
- }
- if (outputs[OUTPUT_1].isConnected()){
- if (inputsconnected > 0){
- outputs[OUTPUT_1].setVoltage(inputs[INPUT_IN + selector].getVoltage());
+ if (gatemode == true){
+ if (inputs[INPUT_CLK].isConnected()){
+ outputs[OUTPUT_OUT + selector].setVoltage((inputs[INPUT_CLK].getVoltage() > 0) ? 10.0f : 0.0f);
}else{
- outputs[OUTPUT_1].setVoltage(selector * 1.4285714285714285714285714285714f);
+ outputs[OUTPUT_OUT + selector].setVoltage(10.0f);
+ }
+ }else{
+ if (inputs[INPUT_1].isConnected()){
+ outputs[OUTPUT_OUT + selector].setVoltage(inputs[INPUT_1].getVoltage());
+ }else if (inputsconnected > 0){
+ outputs[OUTPUT_OUT + selector].setVoltage(ins[selector]);
}
-
-
- }
- if (gatemode == true){
if (inputsconnected > 0){
- outputs[OUTPUT_OUT + selector].setVoltage(inputs[INPUT_IN + selector].getVoltage());
- }else{
- if (inputs[INPUT_CLK].isConnected()){
- outputs[OUTPUT_OUT + selector].setVoltage((inputs[INPUT_CLK].getVoltage() > 0) ? 10.0f : 0.0f);
+ outputs[OUTPUT_1].setVoltage(ins[selector]);
+ }
+ }
+
+ if (opmode > 0){
+ if (gatemode == true){
+ for (int i = 0; i < 8; i++){
+ float tempval = outputs[OUTPUT_OUT + i].getVoltage();
+ outputs[OUTPUT_OUT + i].setVoltage(10.0f - tempval);
+ }
+ }else if (opmode == 1){
+ for (int i = 0; i < 8; i++){
+ float tempval = outputs[OUTPUT_OUT + i].getVoltage();
+ outputs[OUTPUT_OUT + i].setVoltage(0.0f - tempval);
+ }
+ if (inputsconnected > 0){
+ outputs[OUTPUT_1].setVoltage(0.0f - ins[selector]);
+ }
+ }else if (opmode == 2){
+
+ if (inputsconnected > 0){
+ for (int i = 0; i < 8; i++){
+ outputs[OUTPUT_OUT + i].setVoltage(0.0f - inputs[INPUT_IN + i].getVoltage());
+ }
+ outputs[OUTPUT_1].setVoltage(outputs[OUTPUT_OUT + selector].getVoltage());
}else{
- outputs[OUTPUT_OUT + selector].setVoltage(10.0f);
+ for (int i = 0; i < 8; i++){
+ outputs[OUTPUT_OUT + i].setVoltage(0.0f - inputs[INPUT_1].getVoltage());
+ }
}
+
+ outputs[OUTPUT_OUT + selector].setVoltage(0.0f);
+ }else if (opmode == 3){
+ if (inputsconnected > 0){
+ for (int i = 0; i < 8; i++){
+ outputs[OUTPUT_OUT + i].setVoltage(inputs[INPUT_IN + i].getVoltage());
+ }
+ outputs[OUTPUT_1].setVoltage(outputs[OUTPUT_OUT + selector].getVoltage());
+ }else{
+ for (int i = 0; i < 8; i++){
+ outputs[OUTPUT_OUT + i].setVoltage(inputs[INPUT_1].getVoltage());
+ }
+ }
+ outputs[OUTPUT_OUT + selector].setVoltage(0.0f);
}
}
-
//indicator leds
ledy = 114.1 + 27.7 * selector;
@@ -134,7 +192,7 @@ struct CM9ModuleWidget : ModuleWidget {
// addChild(createWidget(Vec(box.size.x - 60, 365)));
//widget items
- addParam(createParam(Vec(7.0 , 20.2), module, CM9Module::PARAM_SEL));
+ addParam(createParam(Vec(7.0 , 20.2), module, CM9Module::PARAM_SEL));
addInput(createInput(Vec(2.8, 65.9), module, CM9Module::INPUT_SEL));
addInput(createInput(Vec(50.2 , 30.0), module, CM9Module::INPUT_CLK));
@@ -157,13 +215,19 @@ struct CM9ModuleWidget : ModuleWidget {
addOutput(createOutput(Vec(25.7 , 326.6), module, CM9Module::OUTPUT_1));
- //led selector display
+
if (module)
{
+ //led selector display
CM9_LedIndicator *ledindicator = new CM9_LedIndicator();
ledindicator->posx = &module->ledx;
ledindicator->posy = &module->ledy;
addChild(ledindicator);
+
+ //Operating mode selector
+ CM_OP *opswitch = new CM_OP(53.7, 333.9f);
+ opswitch->opmode = &module->opmode;
+ addChild(opswitch);
}
}
};