Skip to content

Commit

Permalink
Rework the one-shot a bit (#77)
Browse files Browse the repository at this point in the history
OneShot is a feature not a mode of a trigger. So make it
a separate parameter and adjust accordingly

Patch version 7 patches with oneshots get set to D1 now.

Closes #72
  • Loading branch information
baconpaul authored Jan 3, 2025
1 parent 6cb71c3 commit 5ef3f0b
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 43 deletions.
1 change: 0 additions & 1 deletion src/clap/six-sines-clap-entry-impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ const clap_plugin *clap_create_plugin(const clap_plugin_factory *f, const clap_h

if (strcmp(plugin_id, getDescriptor()->id) == 0)
{
SXSNLOG("Asked for desc");
return makePlugin(host);
}
return nullptr;
Expand Down
1 change: 0 additions & 1 deletion src/clap/six-sines-clap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,6 @@ struct SixSinesClap : public plugHelper_t, sst::clap_juce_shim::EditorProvider

const clap_plugin *makePlugin(const clap_host *h)
{
SXSNLOG("makePlugin");
auto res = new baconpaul::six_sines::clapimpl::SixSinesClap(h);
return res->clapPlugin();
}
Expand Down
27 changes: 9 additions & 18 deletions src/dsp/node_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,29 @@ enum TriggerMode
NEW_VOICE,
KEY_PRESS,
PATCH_DEFAULT,
ON_RELEASE,
ONE_SHOT
ON_RELEASE
};

static const char *TriggerModeName[6]{"On Start or In Release (Legato)",
"On Start Voice Only",
"On Any Key Press",
"Patch Default",
"On Release",
"One Shot (w/ Default Retrigger)"};
static const char *TriggerModeName[5]{"On Start or In Release (Legato)", "On Start Voice Only",
"On Any Key Press", "Patch Default", "On Release"};

template <typename T> struct EnvelopeSupport
{
const MonoValues &monoValues;
const VoiceValues &voiceValues;

const float &delay, &attackv, &hold, &decay, &sustain, &release, &powerV, &tmV, &emV;
const float &delay, &attackv, &hold, &decay, &sustain, &release, &powerV, &tmV, &emV, &oneShV;
const float &ash, &dsh, &rsh;
EnvelopeSupport(const T &mn, const MonoValues &mv, const VoiceValues &vv)
: monoValues(mv), voiceValues(vv), env(&mv.sr), delay(mn.delay), attackv(mn.attack),
hold(mn.hold), decay(mn.decay), sustain(mn.sustain), release(mn.release),
powerV(mn.envPower), ash(mn.aShape), dsh(mn.dShape), rsh(mn.rShape), tmV(mn.triggerMode),
emV(mn.envIsMultiplcative)
emV(mn.envIsMultiplcative), oneShV(mn.envIsOneShot)
{
}

TriggerMode triggerMode{NEW_GATE};
bool envIsOneShot{false};
bool allowVoiceTrigger{true};

bool active{true}, constantEnv{false};
Expand All @@ -83,6 +79,7 @@ template <typename T> struct EnvelopeSupport
{
triggerMode = (TriggerMode)std::round(tmV);
envIsMult = emV > 0.5;
envIsOneShot = oneShV > 0.5;
if (triggerMode == NEW_VOICE && !allowVoiceTrigger)
triggerMode = NEW_GATE;

Expand Down Expand Up @@ -175,17 +172,11 @@ template <typename T> struct EnvelopeSupport
decay, sustain, release, ash, dsh, rsh, !voiceValues.gated,
needsCurve);
}
else if (triggerMode == ONE_SHOT)
{
env.processBlockWithDelay(delay, std::clamp(attackv + attackMod, minAttack, 1.f), hold,
decay, sustain, release, ash, dsh, rsh,
env.stage < env_t::s_sustain, needsCurve);
}
else
{
auto gate = envIsOneShot ? env.stage < env_t::s_sustain : voiceValues.gated;
env.processBlockWithDelay(delay, std::clamp(attackv + attackMod, minAttack, 1.f), hold,
decay, sustain, release, ash, dsh, rsh, voiceValues.gated,
needsCurve);
decay, sustain, release, ash, dsh, rsh, gate, needsCurve);
}
}

Expand Down
26 changes: 26 additions & 0 deletions src/synth/patch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ bool Patch::fromState(const std::string &idata)
par = par->NextSiblingElement("p");
}

if (ver != patchVersion)
migratePatchFromVersion(ver);
return true;
}

Expand Down Expand Up @@ -237,4 +239,28 @@ float Patch::migrateParamValueFromVersion(Param *p, float value, uint32_t versio
return value;
}

void Patch::migratePatchFromVersion(uint32_t version)
{
if (version == 7)
{
auto fixTrigMod = [](auto &a)
{
if (a.triggerMode.value == 5)
{
a.triggerMode.value = 3; // PATCH_DEFAULT
a.envIsOneShot.value = true;
}
};
for (auto &s : sourceNodes)
fixTrigMod(s);
for (auto &s : selfNodes)
fixTrigMod(s);
for (auto &s : matrixNodes)
fixTrigMod(s);
fixTrigMod(output);
fixTrigMod(fineTuneMod);
fixTrigMod(mainPanMod);
}
}

} // namespace baconpaul::six_sines
13 changes: 10 additions & 3 deletions src/synth/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct Param

struct Patch
{
static constexpr uint32_t patchVersion{7};
static constexpr uint32_t patchVersion{8};
std::vector<const Param *> params;
std::unordered_map<uint32_t, Param *> paramMap;

Expand Down Expand Up @@ -277,7 +277,12 @@ struct Patch
.withGroupName(name)
.withDefault(!alwaysAdd)
.withID(id0 + 11)
.withUnorderedMapFormatting({{0, "Add"}, {1, "Scale"}}))
.withUnorderedMapFormatting({{0, "Add"}, {1, "Scale"}})),
envIsOneShot(boolMd()
.withName(name + " Is OneShot")
.withGroupName(name)
.withDefault(false)
.withID(id0 + 12))
{
delay.adhocFeatures = Param::AdHocFeatureValues::ENVTIME;
attack.adhocFeatures = Param::AdHocFeatureValues::ENVTIME;
Expand All @@ -289,7 +294,7 @@ struct Patch
}

Param delay, attack, hold, decay, sustain, release, envPower;
Param aShape, dShape, rShape, triggerMode, envIsMultiplcative;
Param aShape, dShape, rShape, triggerMode, envIsMultiplcative, envIsOneShot;

void appendDAHDSRParams(std::vector<Param *> &res)
{
Expand All @@ -305,6 +310,7 @@ struct Patch
res.push_back(&rShape);
res.push_back(&triggerMode);
res.push_back(&envIsMultiplcative);
res.push_back(&envIsOneShot);
}
};

Expand Down Expand Up @@ -1132,6 +1138,7 @@ struct Patch
bool fromStateV1(const std::string &);

float migrateParamValueFromVersion(Param *p, float value, uint32_t version);
void migratePatchFromVersion(uint32_t version);
};
} // namespace baconpaul::six_sines
#endif // PATCH_H
3 changes: 1 addition & 2 deletions src/synth/voice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,7 @@ void Voice::retriggerAllEnvelopesForKeyPress()
return false;

auto res = (tm == TriggerMode::KEY_PRESS ||
((tm == TriggerMode::PATCH_DEFAULT || tm == ONE_SHOT) &&
dtm == TriggerMode::KEY_PRESS));
(tm == TriggerMode::PATCH_DEFAULT && dtm == TriggerMode::KEY_PRESS));
return res;
};
for (auto &s : src)
Expand Down
53 changes: 35 additions & 18 deletions src/ui/dahdsr-components.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ template <typename Comp, typename PatchPart> struct DAHDSRComponents
Comp *asComp() { return static_cast<Comp *>(this); }
DAHDSRComponents() {}

const Param *triggerModePtr{nullptr}; // bit of a hack since refs arent mutable
const PatchPart *patchPartPtr{nullptr}; // bit of a hack since refs arent mutable
void setupDAHDSR(SixSinesEditor &e, const PatchPart &v)
{
auto mk = [&e, this](auto id, auto idx, auto lb)
Expand Down Expand Up @@ -80,7 +80,7 @@ template <typename Comp, typename PatchPart> struct DAHDSRComponents
if (w)
w->setTriggerLabel();
};
triggerModePtr = &v.triggerMode;
patchPartPtr = &v;
setTriggerLabel();
}

Expand Down Expand Up @@ -128,44 +128,46 @@ template <typename Comp, typename PatchPart> struct DAHDSRComponents
std::unique_ptr<jcmp::TextPushButton> triggerButton;
void setTriggerLabel()
{
if (!triggerModePtr)
if (!patchPartPtr)
return;
auto tmv = (int)std::round(triggerModePtr->value);
auto tmv = (int)std::round(patchPartPtr->triggerMode.value);
auto osv = (int)std::round(patchPartPtr->envIsOneShot.value);

std::string LE = (osv ? u8"\U000000B9" : "");

switch (tmv)
{
case (int)TriggerMode::NEW_GATE:
triggerButton->setLabel("L");
triggerButton->setLabel("L" + LE);
break;
case (int)TriggerMode::NEW_VOICE:
triggerButton->setLabel("S");
triggerButton->setLabel("S" + LE);
break;
case (int)TriggerMode::KEY_PRESS:
triggerButton->setLabel("K");
triggerButton->setLabel("K" + LE);
break;
case (int)TriggerMode::ON_RELEASE:
triggerButton->setLabel("R");
break;
case (int)TriggerMode::ONE_SHOT:
triggerButton->setLabel("1");
triggerButton->setLabel("R"); // one shot does nothing with release
break;
case (int)TriggerMode::PATCH_DEFAULT:
triggerButton->setLabel("D");
triggerButton->setLabel("D" + LE);
break;
}
triggerButton->repaint();
}
void showTriggerPopup()
{
if (!triggerModePtr)
if (!patchPartPtr)
return;
auto tmv = (int)std::round(triggerModePtr->value);
auto tmv = (int)std::round(patchPartPtr->triggerMode.value);
auto osv = (bool)std::round(patchPartPtr->envIsOneShot.value);

auto genSet = [w = juce::Component::SafePointer(asComp())](int nv)
{
auto that = w;
return [nv, that]()
{
auto pid = that->triggerModePtr->meta.id;
auto pid = that->patchPartPtr->triggerMode.meta.id;
that->editor.patchCopy.paramMap.at(pid)->value = nv;
that->setTriggerLabel();

Expand All @@ -177,9 +179,9 @@ template <typename Comp, typename PatchPart> struct DAHDSRComponents
auto p = juce::PopupMenu();
p.addSectionHeader("Trigger Mode");
p.addSeparator();
for (auto v : {(int)TriggerMode::KEY_PRESS, (int)TriggerMode::NEW_GATE,
(int)TriggerMode::NEW_VOICE, (int)TriggerMode::ON_RELEASE,
(int)TriggerMode::ONE_SHOT, (int)TriggerMode::PATCH_DEFAULT})
for (auto v :
{(int)TriggerMode::KEY_PRESS, (int)TriggerMode::NEW_GATE, (int)TriggerMode::NEW_VOICE,
(int)TriggerMode::ON_RELEASE, (int)TriggerMode::PATCH_DEFAULT})
{
bool enabled = true;
if (v == (int)TriggerMode::NEW_VOICE && !voiceTrigerAllowed)
Expand All @@ -191,6 +193,21 @@ template <typename Comp, typename PatchPart> struct DAHDSRComponents
p.addItem(TriggerModeName[v], enabled, tmv == v, genSet(v));
}

p.addSeparator();
p.addItem("One Shot", tmv != (int)TriggerMode::ON_RELEASE, osv,
[osv, w = juce::Component::SafePointer(asComp())]()
{
if (!w)
return;

auto pid = w->patchPartPtr->envIsOneShot.meta.id;
w->editor.patchCopy.paramMap.at(pid)->value = !(osv);
w->setTriggerLabel();

w->editor.uiToAudio.push(
{Synth::UIToAudioMsg::Action::SET_PARAM, pid, (float)(!osv)});
w->editor.flushOperator();
});
p.showMenuAsync(juce::PopupMenu::Options().withParentComponent(&asComp()->editor));
}
};
Expand Down

0 comments on commit 5ef3f0b

Please sign in to comment.