From 376a19962e40899f0f292e7fc9a49fdfb45670ed Mon Sep 17 00:00:00 2001 From: Christoph Hart <> Date: Mon, 18 Nov 2024 22:17:22 +0100 Subject: [PATCH] - added control.compare node --- hi_dsp_library/dsp_nodes/CableNodes.h | 104 ++++++++++++++++++ .../dynamic_elements/DynamicSmootherNode.cpp | 85 +++++++++++++- .../dynamic_elements/DynamicSmootherNode.h | 23 ++++ .../node_library/HiseNodeFactory.cpp | 2 +- 4 files changed, 211 insertions(+), 3 deletions(-) diff --git a/hi_dsp_library/dsp_nodes/CableNodes.h b/hi_dsp_library/dsp_nodes/CableNodes.h index 00b6c83f90..f02c9dfaf1 100644 --- a/hi_dsp_library/dsp_nodes/CableNodes.h +++ b/hi_dsp_library/dsp_nodes/CableNodes.h @@ -2024,7 +2024,110 @@ namespace control LogicState rightValue = LogicState::Undefined; LogicType logicType = LogicType::AND; mutable bool dirty = false; + }; + + struct compare + { + enum class Comparator + { + EQ, + NEQ, + GT, + LT, + GET, + LET, + MIN, + MAX, + numComparators + }; + + SN_NODE_ID("compare"); + SN_DESCRIPTION("compares the input signals and outputs either 1.0 or 0.0"); + + static constexpr bool isNormalisedModulation() { return true; } + static constexpr bool needsProcessing() { return false; } + + bool operator==(const compare& other) const + { + return comparator == other.comparator && leftValue == other.leftValue && rightValue == other.rightValue; + } + + void reset() + { + + } + double getValue() const + { + dirty = false; + + switch (comparator) + { + case Comparator::EQ: return (double)(int)(leftValue == rightValue); + case Comparator::NEQ: return (double)(int)(leftValue != rightValue); + case Comparator::GT: return (double)(int)(leftValue > rightValue); + case Comparator::LT: return (double)(int)(leftValue < rightValue); + case Comparator::GET: return (double)(int)(leftValue >= rightValue); + case Comparator::LET: return (double)(int)(leftValue <= rightValue); + case Comparator::MIN: return jmin(leftValue, rightValue); + case Comparator::MAX: return jmax(leftValue, rightValue); + case Comparator::numComparators: + default: return 0.0; + } + } + + template void setParameter(double v) + { + if constexpr (P == 0) + { + auto prevValue = leftValue; + leftValue = v; + dirty |= leftValue != prevValue; + } + + if constexpr (P == 1) + { + auto prevValue = rightValue; + rightValue = v; + dirty |= (prevValue != rightValue); + } + + if constexpr (P == 2) + { + comparator = (Comparator)jlimit(0, (int)Comparator::numComparators - 1, (int)v); + dirty = true; + } + } + + template static void createParameters(ParameterDataList& data, NodeType& n) + { + { + parameter::data p("Left"); + p.template setParameterCallbackWithIndex(&n); + p.setRange({ 0.0, 1.0 }); + p.setDefaultValue(0.0); + data.add(std::move(p)); + } + { + parameter::data p("Right"); + p.template setParameterCallbackWithIndex(&n); + p.setRange({ 0.0, 1.0 }); + p.setDefaultValue(0.0); + data.add(std::move(p)); + } + { + parameter::data p("Comparator"); + p.template setParameterCallbackWithIndex(&n); + p.setParameterValueNames({ "EQ", "NEQ", "GT", "LT", "GTE", "LTE", "MIN", "MAX" }); + p.setDefaultValue(0.0); + data.add(std::move(p)); + } + } + + double leftValue = 0.0; + double rightValue = 0.0; + Comparator comparator = Comparator::EQ; + mutable bool dirty = false; }; struct change: public pimpl::no_mod_normalisation @@ -2447,6 +2550,7 @@ namespace control template using bipolar = multi_parameter; template using minmax = multi_parameter; template using logic_op = multi_parameter; + template using compare = multi_parameter; template using intensity = multi_parameter; template using bang = multi_parameter; template using delay_cable = multi_parameter; diff --git a/hi_scripting/scripting/scriptnode/dynamic_elements/DynamicSmootherNode.cpp b/hi_scripting/scripting/scriptnode/dynamic_elements/DynamicSmootherNode.cpp index 187286ace6..126b36d782 100644 --- a/hi_scripting/scripting/scriptnode/dynamic_elements/DynamicSmootherNode.cpp +++ b/hi_scripting/scripting/scriptnode/dynamic_elements/DynamicSmootherNode.cpp @@ -105,9 +105,90 @@ void logic_op_editor::resized() dragger.setBounds(b); } +compare_editor::compare_editor (CompareBase* b, PooledUIUpdater* u): + ScriptnodeExtraComponent(b, u), + dragger(u) +{ + setSize(256, 60); + addAndMakeVisible(dragger); +} + +void compare_editor::paint (Graphics& g) +{ + auto b = getLocalBounds(); + auto l = b.removeFromLeft(getWidth() / 3).toFloat().withSizeKeepingCentre(16.0f, 16.0f); + auto r = b.removeFromLeft(getWidth() / 3).toFloat().withSizeKeepingCentre(16.0f, 16.0f); + auto m = dragger.getBounds().toFloat(); m.removeFromLeft(m.getWidth() / 2.0f); + m = m.withSizeKeepingCentre(16.0f, 16.0f); + + ScriptnodeComboBoxLookAndFeel::drawScriptnodeDarkBackground(g, l.getUnion(r).expanded(6.0f, 6.0f), true); + + g.setColour(Colours::white.withAlpha(0.9f)); + g.drawEllipse(l, 2.0f); + g.drawEllipse(r, 2.0f); + g.drawEllipse(m, 2.0f); + + g.setFont(GLOBAL_MONOSPACE_FONT().withHeight(l.getHeight() - 1.0f)); + + using Comp = multilogic::compare::Comparator; + + String w; + + switch (lastData.comparator) + { + case Comp::EQ: w = "=="; + break; + case Comp::NEQ: w = "!="; + break; + case Comp::GT: w = ">"; + break; + case Comp::LT: w = "<"; + break; + case Comp::GET: w = ">="; + break; + case Comp::LET: w = "<="; + break; + case Comp::MIN: w = "min"; + break; + case Comp::MAX: w = "max"; + break; + case Comp::numComparators: + break; + default: ; + } + + g.drawText(w, l.getUnion(r), Justification::centred); + + g.fillEllipse(l.reduced(3.0f + 5.0f * (1.0 - lastData.leftValue))); + g.fillEllipse(r.reduced(3.0f + 5.0f * (1.0 - lastData.rightValue))); + + g.fillEllipse(m.reduced(3.0f + 5.0f * (1.0 - lastData.getValue()))); +} + +void compare_editor::timerCallback () +{ + auto thisData = getObject()->getUIData(); + + if (!(thisData == lastData)) + { + lastData = thisData; + repaint(); + } +} + +void compare_editor::resized () +{ + auto b = getLocalBounds(); + + b = b.removeFromRight(getWidth() / 3); + b = b.withSizeKeepingCentre(28 * 2, 28); + + dragger.setBounds(b); +} + minmax_editor::minmax_editor(MinMaxBase* b, PooledUIUpdater* u) : - ScriptnodeExtraComponent(b, u), - dragger(u) + ScriptnodeExtraComponent(b, u), + dragger(u) { addAndMakeVisible(rangePresets); addAndMakeVisible(dragger); diff --git a/hi_scripting/scripting/scriptnode/dynamic_elements/DynamicSmootherNode.h b/hi_scripting/scripting/scriptnode/dynamic_elements/DynamicSmootherNode.h index af40ccf476..82f5c52aca 100644 --- a/hi_scripting/scripting/scriptnode/dynamic_elements/DynamicSmootherNode.h +++ b/hi_scripting/scripting/scriptnode/dynamic_elements/DynamicSmootherNode.h @@ -61,6 +61,29 @@ namespace control control::multilogic::logic_op lastData; }; + struct compare_editor : public ScriptnodeExtraComponent> + { + using CompareBase = pimpl::combined_parameter_base; + + compare_editor(CompareBase* b, PooledUIUpdater* u); + + void paint (Graphics& g) override; + + void timerCallback () override; + + void resized () override; + + static Component* createExtraComponent(void* obj, PooledUIUpdater* updater) + { + auto typed = static_cast(obj); + return new compare_editor(dynamic_cast(typed), updater); + } + + ModulationSourceBaseComponent dragger; + + control::multilogic::compare lastData; + }; + struct blend_editor : public ScriptnodeExtraComponent> { using LogicBase = pimpl::combined_parameter_base; diff --git a/hi_scripting/scripting/scriptnode/node_library/HiseNodeFactory.cpp b/hi_scripting/scripting/scriptnode/node_library/HiseNodeFactory.cpp index 9a41065300..141def9a18 100644 --- a/hi_scripting/scripting/scriptnode/node_library/HiseNodeFactory.cpp +++ b/hi_scripting/scripting/scriptnode/node_library/HiseNodeFactory.cpp @@ -1289,7 +1289,7 @@ namespace control registerPolyNoProcessNode, control::bang, ModulationSourceBaseComponent>(); - + registerPolyNoProcessNode, control::compare, compare_editor>(); registerPolyNoProcessNode, control::change, ModulationSourceBaseComponent>();