diff --git a/src/clap/six-sines-clap-entry-impl.cpp b/src/clap/six-sines-clap-entry-impl.cpp index 975ec47..a9b5966 100644 --- a/src/clap/six-sines-clap-entry-impl.cpp +++ b/src/clap/six-sines-clap-entry-impl.cpp @@ -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; diff --git a/src/clap/six-sines-clap.cpp b/src/clap/six-sines-clap.cpp index e0cc923..1b7f780 100644 --- a/src/clap/six-sines-clap.cpp +++ b/src/clap/six-sines-clap.cpp @@ -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(); } diff --git a/src/dsp/node_support.h b/src/dsp/node_support.h index 5213de1..c4005f2 100644 --- a/src/dsp/node_support.h +++ b/src/dsp/node_support.h @@ -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 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, ↱ 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}; @@ -83,6 +79,7 @@ template struct EnvelopeSupport { triggerMode = (TriggerMode)std::round(tmV); envIsMult = emV > 0.5; + envIsOneShot = oneShV > 0.5; if (triggerMode == NEW_VOICE && !allowVoiceTrigger) triggerMode = NEW_GATE; @@ -175,17 +172,11 @@ template 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); } } diff --git a/src/synth/patch.cpp b/src/synth/patch.cpp index a4665c8..4be76ed 100644 --- a/src/synth/patch.cpp +++ b/src/synth/patch.cpp @@ -127,6 +127,8 @@ bool Patch::fromState(const std::string &idata) par = par->NextSiblingElement("p"); } + if (ver != patchVersion) + migratePatchFromVersion(ver); return true; } @@ -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 \ No newline at end of file diff --git a/src/synth/patch.h b/src/synth/patch.h index e11e61b..2e388c4 100644 --- a/src/synth/patch.h +++ b/src/synth/patch.h @@ -56,7 +56,7 @@ struct Param struct Patch { - static constexpr uint32_t patchVersion{7}; + static constexpr uint32_t patchVersion{8}; std::vector params; std::unordered_map paramMap; @@ -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; @@ -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 &res) { @@ -305,6 +310,7 @@ struct Patch res.push_back(&rShape); res.push_back(&triggerMode); res.push_back(&envIsMultiplcative); + res.push_back(&envIsOneShot); } }; @@ -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 diff --git a/src/synth/voice.cpp b/src/synth/voice.cpp index 81bbce0..0d3250d 100644 --- a/src/synth/voice.cpp +++ b/src/synth/voice.cpp @@ -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) diff --git a/src/ui/dahdsr-components.h b/src/ui/dahdsr-components.h index eae7242..0f93a79 100644 --- a/src/ui/dahdsr-components.h +++ b/src/ui/dahdsr-components.h @@ -33,7 +33,7 @@ template struct DAHDSRComponents Comp *asComp() { return static_cast(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) @@ -80,7 +80,7 @@ template struct DAHDSRComponents if (w) w->setTriggerLabel(); }; - triggerModePtr = &v.triggerMode; + patchPartPtr = &v; setTriggerLabel(); } @@ -128,44 +128,46 @@ template struct DAHDSRComponents std::unique_ptr 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(); @@ -177,9 +179,9 @@ template 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) @@ -191,6 +193,21 @@ template 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)); } };