Browse Source

Addressing feedback from Robin

* make orange more vidid
* draggable sliders
pull/42/head
hemmer 2 years ago
parent
commit
537cd5c7da
4 changed files with 318 additions and 16 deletions
  1. +4
    -2
      README.md
  2. +88
    -0
      res/components/CKSSThree_bg.svg
  3. +148
    -0
      res/components/CKSSThree_fg.svg
  4. +78
    -14
      src/MotionMTR.cpp

+ 4
- 2
README.md View File

@@ -21,9 +21,11 @@ We have tried to make the VCV implementations as authentic as possible, however

* The Noise Plethora filters self-oscillate on the hardware version but not the software version.

* EvenVCO has the option (default true) to remove DC from the pulse waveform output (hardware contains DC for non-50% duty cycles)
* EvenVCO has the option (default true) to remove DC from the pulse waveform output (hardware contains DC for non-50% duty cycles).

* PonyVCO optionally allows the user:
* to filter DC from the TZFM input signal (hardware filters below 15mHz)
* to limit the pulsewidth from 5% to 95% (hardware is full range)
* to remove DC from the pulse waveform output (hardware contains DC for non-50% duty cycles)
* to remove DC from the pulse waveform output (hardware contains DC for non-50% duty cycles)

* MotionMTR optionally doesn't use the 10V normalling on inputs if in audio mode to avoid acidentally adding unwanted DC to audio signals, see context menu. E.g. if you temporarily unpatch an audio source whilst using it it mixer mode, you get 10V DC suddenly and a nasty pop.

+ 88
- 0
res/components/CKSSThree_bg.svg View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->

<svg
version="1.0"
id="svg258108"
sodipodi:docname="CKSSThree_bg.svg"
x="0px"
y="0px"
width="13.457px"
height="28.34766px"
viewBox="0 0 13.457 28.34766"
enable-background="new 0 0 13.457 28.34766"
xml:space="preserve"
inkscape:version="1.2.1 (9c6d41e, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs158" />
<sodipodi:namedview
bordercolor="#666666"
borderopacity="1.0"
fit-margin-bottom="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-top="0"
id="base"
inkscape:current-layer="svg258108"
inkscape:cx="3.8392857"
inkscape:cy="16.964286"
inkscape:document-units="mm"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="882"
inkscape:window-maximized="0"
inkscape:window-width="1600"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:zoom="11.2"
pagecolor="#ffffff"
showgrid="false"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1">
</sodipodi:namedview>
<path
id="path243332"
inkscape:connector-curvature="0"
d="M0,1.41795c0-0.78124,0.6406-1.41797,1.41793-1.41797h10.62499 c0.77739,0,1.4141,0.63671,1.4141,1.41797v25.51173c0,0.77735-0.63669,1.41797-1.4141,1.41797H1.41793 C0.6406,28.34765,0,27.70702,0,26.92968V1.41795z" />
<linearGradient
id="path243334_1_"
gradientUnits="userSpaceOnUse"
x1="6.73046"
y1="1.26953"
x2="6.73046"
y2="27.07812">
<stop
offset="0"
style="stop-color:#3B3B3B"
id="stop134" />
<stop
offset="1"
style="stop-color:#242424"
id="stop136" />
</linearGradient>
<path
id="path243334"
inkscape:connector-curvature="0"
opacity="0.54"
fill="url(#path243334_1_)"
d="M11.3242,1.26953H2.13671 c-0.48326,0-0.87501,0.39176-0.87501,0.87501v24.05857c0,0.48326,0.39176,0.87501,0.87501,0.87501h9.18749 c0.48326,0,0.87501-0.39176,0.87501-0.87501V2.14454C12.19921,1.66128,11.80746,1.26953,11.3242,1.26953z" />
<rect
x="-19.43386"
y="19.77311"
fill="none"
width="0.6829"
height="0.89523"
id="rect140" />
<rect
x="0.73033"
y="0.80507"
opacity="0.3"
width="12.00026"
height="1.71664"
id="rect142" />

</svg>

+ 148
- 0
res/components/CKSSThree_fg.svg View File

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->

<svg
version="1.0"
id="svg258108"
sodipodi:docname="CKSSThree_fg.svg"
x="0px"
y="0px"
width="10.94143"
height="11.941"
viewBox="0 0 10.94143 11.941"
enable-background="new 0 0 13.457 28.34766"
xml:space="preserve"
inkscape:version="1.2.1 (9c6d41e, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs3211"><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1577"
id="linearGradient1579"
x1="6.4409394"
y1="10.29908"
x2="6.4493213"
y2="13.185839"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.003741,0,0,1,-0.03019806,-1.4171131)" /><linearGradient
inkscape:collect="always"
id="linearGradient1577"><stop
style="stop-color:#000000;stop-opacity:0.38225257;"
offset="0"
id="stop1573" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop1575" /></linearGradient></defs>
<sodipodi:namedview
bordercolor="#666666"
borderopacity="1.0"
fit-margin-bottom="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-top="0"
id="base"
inkscape:current-layer="svg258108"
inkscape:cx="1.0976869"
inkscape:cy="8.2185788"
inkscape:document-units="mm"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="882"
inkscape:window-maximized="0"
inkscape:window-width="1600"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:zoom="53.293886"
pagecolor="#ffffff"
showgrid="false"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1">
</sodipodi:namedview>

<linearGradient
id="path243334_1_"
gradientUnits="userSpaceOnUse"
x1="6.7304602"
y1="1.2695301"
x2="6.7304602"
y2="27.078119">
<stop
offset="0"
style="stop-color:#3B3B3B"
id="stop3187" />
<stop
offset="1"
style="stop-color:#242424"
id="stop3189" />
</linearGradient>

<rect
x="-19.433861"
y="19.773109"
fill="none"
width="0.68290001"
height="0.89523"
id="rect3193" />

<g
id="g3208"
transform="translate(-1.25778,-18.23161)">
<linearGradient
id="path5815_2_"
gradientUnits="userSpaceOnUse"
x1="6.7284999"
y1="18.231609"
x2="6.7284999"
y2="27.078119">
<stop
offset="0.00559"
style="stop-color:#3D3B3B"
id="stop3197" />
<stop
offset="1"
style="stop-color:#2D2C2C"
id="stop3199" />
</linearGradient>
<path
id="path5815_1_"
inkscape:connector-curvature="0"
fill="url(#path5815_2_)"
d="m 1.25778,18.23161 h 10.94143 v 8.84652 H 1.25778 Z"
style="fill:url(#path5815_2_)" />
<path
id="path5817_1_"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="m 1.25778,21.77853 h 10.94143 v 0.87738 H 1.25778 Z" />
<path
id="path5819_1_"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="m 1.25778,25.32545 h 10.94143 v 0.87738 H 1.25778 Z" />
<path
id="path5821_1_"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="m 1.25778,23.55285 h 10.94143 v 0.87738 H 1.25778 Z" />
<path
id="path5823_1_"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="m 1.25778,20.00513 h 10.94143 v 0.87738 H 1.25778 Z" />
<path
id="path5825_1_"
inkscape:connector-curvature="0"
fill="#797979"
d="m 1.25778,18.23161 h 10.94143 v 0.87738 H 1.25778 Z" />
</g>
<rect
style="fill:url(#linearGradient1579);fill-opacity:1;stroke:none;stroke-width:1.33393;stroke-linejoin:round;stroke-miterlimit:1.5"
id="rect1517"
width="13.160316"
height="2.9625583"
x="0"
y="8.8440666" /></svg>

+ 78
- 14
src/MotionMTR.cpp View File

@@ -57,20 +57,29 @@ struct MotionMTR : Module {
bool startingUp = true;
dsp::Timer startupTimer;

bool break10VNormalForAudioMode = true;

MotionMTR() {
config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
configSwitch(MODE1_PARAM, 0.f, 2.f, 1.f, "Channel 1 mode", modeLabels);

auto mode1 = configSwitch(MODE1_PARAM, 0.f, 2.f, 1.f, "Channel 1 mode", modeLabels);
mode1->snapEnabled = true;
configParam(CTRL_1_PARAM, 0.f, 1.f, 0.f, "Channel 1 gain");
configSwitch(MODE2_PARAM, 0.f, 2.f, 1.f, "Channel 2 mode", modeLabels);

auto mode2 = configSwitch(MODE2_PARAM, 0.f, 2.f, 1.f, "Channel 2 mode", modeLabels);
mode2->snapEnabled = true;
configParam(CTRL_2_PARAM, 0.f, 1.f, 0.f, "Channel 2 gain");
configSwitch(MODE3_PARAM, 0.f, 2.f, 1.f, "Channel 3 mode", modeLabels);

auto mode3 = configSwitch(MODE3_PARAM, 0.f, 2.f, 1.f, "Channel 3 mode", modeLabels);
mode3->snapEnabled = true;
configParam(CTRL_3_PARAM, 0.f, 1.f, 0.f, "Channel 3 gain");

auto in1 = configInput(IN1_INPUT, "Channel 1");
in1->description = "Normalled to 10V (except in audio mode)";
in1->description = "Normalled to 10V (except optionally in audio mode)";
auto in2 = configInput(IN2_INPUT, "Channel 2");
in2->description = "Normalled to 10V (except in audio mode)";
in2->description = "Normalled to 10V (except optionally in audio mode)";
auto in3 = configInput(IN3_INPUT, "Channel 3");
in3->description = "Normalled to 10V (except in audio mode)";
in3->description = "Normalled to 10V (except optionally in audio mode)";

configOutput(OUT1_OUTPUT, "Channel 1");
configOutput(OUT2_OUTPUT, "Channel 2");
@@ -105,9 +114,9 @@ struct MotionMTR : Module {
const LightDisplayType mode2 = (LightDisplayType) params[MODE2_PARAM].getValue();
const LightDisplayType mode3 = (LightDisplayType) params[MODE3_PARAM].getValue();

const float in1 = inputs[IN1_INPUT].getNormalVoltage(10.f * (mode1 != AUDIO));
const float in2 = inputs[IN2_INPUT].getNormalVoltage(10.f * (mode2 != AUDIO));
const float in3 = inputs[IN3_INPUT].getNormalVoltage(10.f * (mode3 != AUDIO));
const float in1 = inputs[IN1_INPUT].getNormalVoltage(10.f * (mode1 != AUDIO || !break10VNormalForAudioMode));
const float in2 = inputs[IN2_INPUT].getNormalVoltage(10.f * (mode2 != AUDIO || !break10VNormalForAudioMode));
const float in3 = inputs[IN3_INPUT].getNormalVoltage(10.f * (mode3 != AUDIO || !break10VNormalForAudioMode));

const float out1 = in1 * params[CTRL_1_PARAM].getValue() * (mode1 == CV_INV ? -1 : +1);
const float out2 = in2 * params[CTRL_2_PARAM].getValue() * (mode2 == CV_INV ? -1 : +1);
@@ -234,7 +243,7 @@ struct MotionMTR : Module {

if (signal >= 0) {
for (int i = 1; i < NUM_LIGHTS_PER_DIAL; ++i) {
float value = 0.5f * (signal > (10 * (i + 1.) / (NUM_LIGHTS_PER_DIAL + 1)));
float value = (signal > (10 * (i + 1.) / (NUM_LIGHTS_PER_DIAL + 1)));
// purple
setLightRGBSmooth(lightId + 3 * i, args, 0.82f * value, 0.0f, 0.82f * value);
}
@@ -242,12 +251,52 @@ struct MotionMTR : Module {
else {
for (int i = 1; i < NUM_LIGHTS_PER_DIAL; ++i) {
float value = (signal < (-10 * (NUM_LIGHTS_PER_DIAL - i + 1.) / (NUM_LIGHTS_PER_DIAL + 1.)));
setLightRGBSmooth(lightId + 3 * i, args, value, 0.65f * value, 0.f);
// orange
setLightRGBSmooth(lightId + 3 * i, args, value, 0.4f * value, 0.f);
}
}
}
}

json_t* dataToJson() override {
json_t* rootJ = json_object();
json_object_set_new(rootJ, "break10VNormalForAudioMode", json_boolean(break10VNormalForAudioMode));
return rootJ;
}

void dataFromJson(json_t* rootJ) override {
json_t* break10VNormalAudioJ = json_object_get(rootJ, "break10VNormalForAudioMode");
if (break10VNormalAudioJ) {
break10VNormalForAudioMode = json_boolean_value(break10VNormalAudioJ);
}
}
};

struct CKSSThreeDragable : app::SvgSlider {
CKSSThreeDragable() {
math::Vec margin = math::Vec(0, 0);
maxHandlePos = math::Vec(1, 1).plus(margin);
minHandlePos = math::Vec(1, 18).plus(margin);
setBackgroundSvg(Svg::load(asset::plugin(pluginInstance, "res/components/CKSSThree_bg.svg")));
setHandleSvg(Svg::load(asset::plugin(pluginInstance, "res/components/CKSSThree_fg.svg")));
background->box.pos = margin;
box.size = background->box.size.plus(margin.mult(2));
}

// disable double click as this messes with click to advance
void onDoubleClick(const event::DoubleClick& e) override { }

// cycle through the values (with reset) on click only (not drag)
void onAction(const ActionEvent& e) override {
ParamQuantity* paramQuantity = getParamQuantity();
float range = paramQuantity->maxValue - paramQuantity->minValue;
float newValue = paramQuantity->getValue() + 1.f;
if (newValue > paramQuantity->maxValue) {
newValue -= range + 1.f;
}
paramQuantity->setValue(newValue);
}
};


@@ -259,11 +308,11 @@ struct MotionMTRWidget : ModuleWidget {
addChild(createWidget<Knurlie>(Vec(RACK_GRID_WIDTH, 0)));
addChild(createWidget<Knurlie>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));

addParam(createParam<CKSSThree>(mm2px(Vec(1.298, 17.851)), module, MotionMTR::MODE1_PARAM));
addParam(createParam<CKSSThreeDragable>(mm2px(Vec(1.298, 17.851)), module, MotionMTR::MODE1_PARAM));
addParam(createParamCentered<Davies1900hBlackKnob>(mm2px(Vec(18.217, 22.18)), module, MotionMTR::CTRL_1_PARAM));
addParam(createParam<CKSSThree>(mm2px(Vec(23.762, 46.679)), module, MotionMTR::MODE2_PARAM));
addParam(createParam<CKSSThreeDragable>(mm2px(Vec(23.762, 46.679)), module, MotionMTR::MODE2_PARAM));
addParam(createParamCentered<Davies1900hBlackKnob>(mm2px(Vec(11.777, 50.761)), module, MotionMTR::CTRL_2_PARAM));
addParam(createParam<CKSSThree>(mm2px(Vec(1.34, 74.461)), module, MotionMTR::MODE3_PARAM));
addParam(createParam<CKSSThreeDragable>(mm2px(Vec(1.34, 74.461)), module, MotionMTR::MODE3_PARAM));
addParam(createParamCentered<Davies1900hBlackKnob>(mm2px(Vec(18.31, 78.89)), module, MotionMTR::CTRL_3_PARAM));

addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(5.008, 100.315)), module, MotionMTR::IN1_INPUT));
@@ -296,6 +345,21 @@ struct MotionMTRWidget : ModuleWidget {
}
}
}


void appendContextMenu(Menu* menu) override {
MotionMTR* module = dynamic_cast<MotionMTR*>(this->module);
assert(module);

menu->addChild(new MenuSeparator());
menu->addChild(createSubmenuItem("Hardware compatibility", "",
[ = ](Menu * menu) {
menu->addChild(createBoolPtrMenuItem("Disable 10V normal in audio mode", "", &module->break10VNormalForAudioMode));
}
));


}
};



Loading…
Cancel
Save