From 04be2a123ef5ec28c1edea6213fe2eb61e836027 Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Thu, 9 Dec 2021 08:13:38 -0500 Subject: [PATCH] A set of minor beta fixes 1. Add a regtest to show FTZ works properly. 2. Don't allow -ve typeins to nan A2bx. Closes #5607 3. Deal with command toggle on/off during drag to change states even more properly. Closes #5606 4. Don't linger hover from Type onto Step Seq Shift. Closes #5605 5. Formula/Modulator cross-scene tearout works. Closes #5590 --- src/common/Parameter.cpp | 4 +++ src/surge-testrunner/UnitTestsDSP.cpp | 25 +++++++++++++++ src/surge-xt/gui/SurgeGUIEditor.h | 6 +++- src/surge-xt/gui/SurgeGUIEditorOverlays.cpp | 8 ++--- .../gui/SurgeGUIEditorValueCallbacks.cpp | 32 ++++++++++--------- .../gui/widgets/LFOAndStepDisplay.cpp | 9 ++++++ 6 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/common/Parameter.cpp b/src/common/Parameter.cpp index d31ab02e773..d650f432229 100644 --- a/src/common/Parameter.cpp +++ b/src/common/Parameter.cpp @@ -4232,6 +4232,10 @@ bool Parameter::set_value_from_string_onto(const std::string &s, pdata &ontoThis ** log2(v/a) = bx ** log2(v/a)/b = x; */ + if (nv <= 0 || !std::isfinite(nv)) + { + return false; + } float res = log2f(nv / displayInfo.a) / displayInfo.b; if (res < val_min.f || res > val_max.f) diff --git a/src/surge-testrunner/UnitTestsDSP.cpp b/src/surge-testrunner/UnitTestsDSP.cpp index 18d7dee519e..690f0aa41b8 100644 --- a/src/surge-testrunner/UnitTestsDSP.cpp +++ b/src/surge-testrunner/UnitTestsDSP.cpp @@ -17,6 +17,7 @@ #include #include "LanczosResampler.h" +#include "CPUFeatures.h" using namespace Surge::Test; @@ -1054,4 +1055,28 @@ TEST_CASE("Wavehaper LUT", "[dsp]") } } } +} + +TEST_CASE("FTZ", "[dsp]") +{ + auto g = Surge::CPUFeatures::FPUStateGuard(); + + unsigned char min_float[4] = {0x00, 0x00, 0x80, 0x00}; + float f_min; + memcpy(&f_min, min_float, 4); + REQUIRE(f_min != 0.f); + + unsigned char res_float[4]; + for (int i = 0; i < 100; ++i) + { + // don't let the compiler optimize me away! + auto r = 1.0 / (fabs(rand() % 10) + 1.1); // a number < 1 + float ftz_float = f_min * r; + memcpy(res_float, &ftz_float, 4); + for (int i = 0; i < 4; ++i) + { + REQUIRE(res_float[i] == 0); + } + REQUIRE(ftz_float == 0.f); + } } \ No newline at end of file diff --git a/src/surge-xt/gui/SurgeGUIEditor.h b/src/surge-xt/gui/SurgeGUIEditor.h index 7bca5391fbe..111a3728e7b 100644 --- a/src/surge-xt/gui/SurgeGUIEditor.h +++ b/src/surge-xt/gui/SurgeGUIEditor.h @@ -371,7 +371,11 @@ class SurgeGUIEditor : public Surge::GUI::IComponentTagValue::Listener, } Surge::Overlays::OverlayWrapper *getOverlayWrapperIfOpen(OverlayTags tag); - void refreshOverlayWithOpenClose(OverlayTags tag); + void refreshOverlayWithOpenClose(OverlayTags tag) + { + refreshAndMorphOverlayWithOpenClose(tag, tag); + } + void refreshAndMorphOverlayWithOpenClose(OverlayTags tag, OverlayTags newTag); void updateWaveshaperOverlay(); // this is the only overlay which updates from patch values diff --git a/src/surge-xt/gui/SurgeGUIEditorOverlays.cpp b/src/surge-xt/gui/SurgeGUIEditorOverlays.cpp index c34a1165fa5..e39ae9986b5 100644 --- a/src/surge-xt/gui/SurgeGUIEditorOverlays.cpp +++ b/src/surge-xt/gui/SurgeGUIEditorOverlays.cpp @@ -573,7 +573,7 @@ void SurgeGUIEditor::rezoomOverlays() } } -void SurgeGUIEditor::refreshOverlayWithOpenClose(OverlayTags tag) +void SurgeGUIEditor::refreshAndMorphOverlayWithOpenClose(OverlayTags tag, OverlayTags newTag) { if (!isAnyOverlayPresent(tag)) return; @@ -590,7 +590,7 @@ void SurgeGUIEditor::refreshOverlayWithOpenClose(OverlayTags tag) * Some editors can do better than a forced open-clsoe */ bool couldRefresh = true; - switch (tag) + switch (newTag) { case TUNING_EDITOR: { @@ -624,10 +624,10 @@ void SurgeGUIEditor::refreshOverlayWithOpenClose(OverlayTags tag) if (!couldRefresh) { closeOverlay(tag); - showOverlay(tag); + showOverlay(newTag); if (to) { - olw = getOverlayWrapperIfOpen(tag); + olw = getOverlayWrapperIfOpen(newTag); if (olw) olw->doTearOut(tol); } diff --git a/src/surge-xt/gui/SurgeGUIEditorValueCallbacks.cpp b/src/surge-xt/gui/SurgeGUIEditorValueCallbacks.cpp index 434a6497a71..abce4acafec 100644 --- a/src/surge-xt/gui/SurgeGUIEditorValueCallbacks.cpp +++ b/src/surge-xt/gui/SurgeGUIEditorValueCallbacks.cpp @@ -278,35 +278,37 @@ void SurgeGUIEditor::changeSelectedScene(int value) synth->release_if_latched[synth->storage.getPatch().scene_active.val.i] = true; synth->storage.getPatch().scene_active.val.i = current_scene; - if (isAnyOverlayPresent(MSEG_EDITOR)) + bool hasMSEG = isAnyOverlayPresent(MSEG_EDITOR); + bool hasForm = isAnyOverlayPresent(FORMULA_EDITOR); + + if (hasForm || hasMSEG) { auto ld = &(synth->storage.getPatch() .scene[current_scene] .lfo[modsource_editor[current_scene] - ms_lfo1]); - if (ld->shape.val.i == lt_mseg) + if (ld->shape.val.i == lt_mseg && hasMSEG) { refreshOverlayWithOpenClose(SurgeGUIEditor::MSEG_EDITOR); } - else + else if (ld->shape.val.i == lt_formula && hasForm) { - closeOverlay(SurgeGUIEditor::MSEG_EDITOR); + refreshOverlayWithOpenClose(SurgeGUIEditor::FORMULA_EDITOR); } - } - - if (isAnyOverlayPresent(FORMULA_EDITOR)) - { - auto ld = &(synth->storage.getPatch() - .scene[current_scene] - .lfo[modsource_editor[current_scene] - ms_lfo1]); - - if (ld->shape.val.i == lt_formula) + else if (ld->shape.val.i == lt_mseg && hasForm) { - refreshOverlayWithOpenClose(SurgeGUIEditor::FORMULA_EDITOR); + refreshAndMorphOverlayWithOpenClose(FORMULA_EDITOR, MSEG_EDITOR); + } + else if (ld->shape.val.i == lt_formula && hasMSEG) + { + refreshAndMorphOverlayWithOpenClose(MSEG_EDITOR, FORMULA_EDITOR); } else { - closeOverlay(SurgeGUIEditor::FORMULA_EDITOR); + if (hasForm) + closeOverlay(SurgeGUIEditor::FORMULA_EDITOR); + if (hasMSEG) + closeOverlay(SurgeGUIEditor::MSEG_EDITOR); } } diff --git a/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp b/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp index f72354ef0f9..7d6c42551cc 100644 --- a/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp +++ b/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp @@ -1528,6 +1528,8 @@ void LFOAndStepDisplay::mouseMove(const juce::MouseEvent &event) } } + // reset for the step hover + nextHover = -1; if (ss_shift_left.contains(event.position)) { nextHover = 0; @@ -1670,6 +1672,12 @@ void LFOAndStepDisplay::mouseDrag(const juce::MouseEvent &event) setStepToDefault(event); return; } + else + { + dragMode = VALUES; + setStepValue(event); + return; + } break; } case TRIGGERS: @@ -1700,6 +1708,7 @@ void LFOAndStepDisplay::mouseDrag(const juce::MouseEvent &event) { if (event.mods.isCommandDown()) { + dragMode = RESET_VALUE; setStepToDefault(event); } else