Skip to content

Commit

Permalink
Bipolar Macros and Macros store natural values (#1098)
Browse files Browse the repository at this point in the history
1. Macros store natural and single value internally
   so are -1,1 or 0,1 with a setConstrained method
2. UI supports isBipolar to allow either-or and persists it
3. Data model has initial step support but no UI for this yet.
   Still just continous
  • Loading branch information
baconpaul authored Aug 13, 2024
1 parent 3f22a45 commit 6d3efc7
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 28 deletions.
35 changes: 31 additions & 4 deletions src-ui/components/multi/SingleMacroEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,24 @@ struct MacroValueAttachment : HasEditor, sst::jucegui::data::Continuous
}

std::string getLabel() const override { return macro().name; }
float getValue() const override { return macro().normalizedValue; }
float getValue() const override { return macro().value; }
void setValueFromGUI(const float &f) override
{
macro().normalizedValue = f;
sendToSerialization(scxt::messaging::client::SetMacroValue({part, index, f}));
macro().setValueConstrained(f);
sendToSerialization(scxt::messaging::client::SetMacroValue({part, index, macro().value}));
editor->setTooltipContents(getLabel(), getValueAsString());
}
void setValueFromModel(const float &) override {}
float getDefaultValue() const override { return 0; }
bool isBipolar() const override { return macro().isBipolar; }
float getMin() const override
{
if (macro().isBipolar)
return -1;
else
return 0;
}
float getMax() const override { return 1; }
};

struct NarrowVerticalMenu : HasEditor, juce::Component
Expand Down Expand Up @@ -163,7 +172,25 @@ void SingleMacroEditor::paint(juce::Graphics &g)
#endif
}

void SingleMacroEditor::showMenu() { SCLOG("Show Menu"); }
void SingleMacroEditor::showMenu()
{
assert(part >= 0 && part < scxt::numParts);
assert(index >= 0 && index < scxt::macrosPerPart);
const auto &macro = editor->macroCache[part][index];
juce::PopupMenu p;
p.addSectionHeader(macro.name);
p.addSeparator();
p.addItem("Bipolar", true, macro.isBipolar, [w = juce::Component::SafePointer(this)]() {
if (!w)
return;
auto &macro = w->editor->macroCache[w->part][w->index];
macro.setIsBipolar(!macro.isBipolar);
w->sendToSerialization(
scxt::messaging::client::SetMacroFullState({w->part, w->index, macro}));
w->repaint();
});
p.showMenuAsync(editor->defaultPopupMenuOptions(menuButton.get()));
}
void SingleMacroEditor::onStyleChanged()
{
// Update the text editor
Expand Down
7 changes: 1 addition & 6 deletions src/engine/macros.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,5 @@

namespace scxt::engine
{
sst::basic_blocks::params::ParamMetaData Macro::getMetadata() const { return {}; }
void Macro::setNormalizedValue(float f)
{
normalizedValue = f;
modulationValue = f;
}

} // namespace scxt::engine
34 changes: 28 additions & 6 deletions src/engine/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,43 @@
#ifndef SCXT_SRC_ENGINE_MACROS_H
#define SCXT_SRC_ENGINE_MACROS_H

#include <cassert>
#include <cstdint>
#include <cstddef>
#include <algorithm>

#include "sst/basic-blocks/params/ParamMetadata.h"

namespace scxt::engine
{
struct Macro
{
float normalizedValue{0.f}; // always 0...1
float modulationValue{0.f}; // Calcluated from normalized value
float value{0.f}; // -1 .. 1

bool isBipolar{false};
bool isBipolar{false}; // The value is expected in range -1..1
bool isStepped{false}; // The value has discrete stepped value
size_t stepCount{1}; // how many steps between min and max.
// So 1 means a 0..1 or -1..1 toggle
std::string name{};

void setNormalizedValue(float f);

sst::basic_blocks::params::ParamMetaData getMetadata() const;
void setIsBipolar(bool b)
{
isBipolar = b;
setValueConstrained(value);
}
void setValueConstrained(float f) { value = std::clamp(f, isBipolar ? -1.f : 0.f, 1.f); }
void setFrom01(float f)
{
assert(f >= 0.f && f <= 1.f);
if (isBipolar)
{
value = f * 2 - 1.0;
}
else
{
value = f;
}
}
};
} // namespace scxt::engine
#endif // SHORTCIRCUITXT_MACROS_H
11 changes: 5 additions & 6 deletions src/json/engine_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,16 @@ SC_STREAMDEF(scxt::engine::Patch, SC_FROM({

SC_STREAMDEF(scxt::engine::Macro, SC_FROM({
v = {
{"nv", t.normalizedValue},
{"bp", t.isBipolar},
{"nm", t.name},
{"v", t.value}, {"bp", t.isBipolar}, {"st", t.isStepped},
{"sc", t.stepCount}, {"nm", t.name},
};
}),
SC_TO({
float normVal;
findIf(v, "nv", normVal);
findIf(v, "v", result.value);
findIf(v, "bp", result.isBipolar);
findIf(v, "st", result.isStepped);
findIf(v, "sc", result.stepCount);
findIf(v, "nm", result.name);
result.setNormalizedValue(normVal);
}));

SC_STREAMDEF(
Expand Down
9 changes: 5 additions & 4 deletions src/messaging/client/macro_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ inline void updateMacroFullState(const macroFullState_t &t, const engine::Engine
cont.scheduleAudioThreadCallback(
[part = p, index = i, macro = m](auto &e) {
// Set everything except the value
auto v = e.getPatch()->getPart(part)->macros[index].normalizedValue;
auto v = e.getPatch()->getPart(part)->macros[index].value;
engine::Macro macroCopy = macro;
macroCopy.setNormalizedValue(v);
macroCopy.setValueConstrained(v);
e.getPatch()->getPart(part)->macros[index] = macroCopy;
},
[](const auto &e) {
Expand Down Expand Up @@ -84,8 +84,9 @@ inline void updateMacroValue(const macroValue_t &t, const engine::Engine &engine
{
const auto &[p, i, f] = t;
cont.scheduleAudioThreadCallback([part = p, index = i, value = f](auto &e) {
// Set everything except the value
e.getPatch()->getPart(part)->macros[index].setNormalizedValue(value);
// Set the value
auto &macro = e.getPatch()->getPart(part)->macros[index];
macro.setValueConstrained(value);
});
}
CLIENT_TO_SERIAL(SetMacroValue, c2s_set_macro_value, macroValue_t,
Expand Down
2 changes: 1 addition & 1 deletion src/modulation/group_matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ void GroupMatrixEndpoints::Sources::bind(scxt::modulation::GroupMatrix &m, engin
auto *part = g.parentPart;
for (int i = 0; i < macrosPerPart; ++i)
{
m.bindSourceValue(macroSources.macros[i], part->macros[i].modulationValue);
m.bindSourceValue(macroSources.macros[i], part->macros[i].value);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/modulation/voice_matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void MatrixEndpoints::Sources::bind(scxt::voice::modulation::Matrix &m, engine::
auto *part = z.parentGroup->parentPart;
for (int i = 0; i < macrosPerPart; ++i)
{
m.bindSourceValue(macroSources.macros[i], part->macros[i].modulationValue);
m.bindSourceValue(macroSources.macros[i], part->macros[i].value);
}
}

Expand Down

0 comments on commit 6d3efc7

Please sign in to comment.