Skip to content

Commit

Permalink
Add UI options for overriding current tuning with patch embedded one (s…
Browse files Browse the repository at this point in the history
…urge-synthesizer#5625)

Add UI options for overriding current tuning with patch embedded one
Update the internal tuning state according to the truth table in surge-synthesizer#1044
Keep the patch loaded tuning available and show it in the tuning menu
Fix the failing regtests from this change
Show MTS-ESP option only if loaded as plugin

Co-authored-by: Paul Walker <[email protected]>
  • Loading branch information
mkruselj and baconpaul authored Dec 13, 2021
1 parent 779111a commit a95c11f
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 110 deletions.
3 changes: 3 additions & 0 deletions src/common/SurgeStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,9 @@ class alignas(16) SurgeStorage
Tunings::KeyboardMapping currentMapping;
bool isStandardTuning = true, isStandardScale = true, isStandardMapping = true;

Tunings::Tuning patchStoredTuning;
bool hasPatchStoredTuning{false};

std::atomic<bool> mapChannelToOctave; // When other midi modes come along, clean this up.

enum TuningApplicationMode
Expand Down
127 changes: 66 additions & 61 deletions src/common/SurgeSynthesizerIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,84 +272,89 @@ bool SurgeSynthesizer::loadPatchByPath(const char *fxpPath, int categoryId, cons
*/
if (storage.getPatch().patchTuning.tuningStoredInPatch)
{
if (storage.isStandardTuning)
/*
* This code changed radically at the end of the XT 1.0 cycle. Previously we would
* check and prompt. Now the semantic is:
*
* 1. If the patch has a tuning, always parse it onto the patchStreamedTuning member
* (which we reset below if the patch doesn't have it)
* 2. based on the tuning setting, override the tuning if there's a patch tuning
*/
bool ot = Surge::Storage::getUserDefaultValue(
&storage, Surge::Storage::OverrideTuningOnPatchLoad, false);
bool om = Surge::Storage::getUserDefaultValue(
&storage, Surge::Storage::OverrideMappingOnPatchLoad, false);

if (ot || om)
{
try
{
if (storage.getPatch().patchTuning.scaleContents.size() > 1)
if (ot)
{
storage.retuneToScale(
Tunings::parseSCLData(storage.getPatch().patchTuning.scaleContents));
}
else
{
storage.retuneTo12TETScale();
}
if (storage.getPatch().patchTuning.mappingContents.size() > 1)
{
auto kb = Tunings::parseKBMData(storage.getPatch().patchTuning.mappingContents);
if (storage.getPatch().patchTuning.mappingName.size() > 1)
kb.name = storage.getPatch().patchTuning.mappingName;
std::cout << "Resetting Tuning" << std::endl;
if (storage.getPatch().patchTuning.scaleContents.size() > 1)
{
storage.retuneToScale(
Tunings::parseSCLData(storage.getPatch().patchTuning.scaleContents));
}
else
kb.name = storage.guessAtKBMName(kb);
storage.remapToKeyboard(kb);
{
storage.retuneTo12TETScale();
}
}
else

if (om)
{
storage.remapToConcertCKeyboard();
if (storage.getPatch().patchTuning.mappingContents.size() > 1)
{
std::cout << "Resetting Mapping" << std::endl;
auto kb =
Tunings::parseKBMData(storage.getPatch().patchTuning.mappingContents);
if (storage.getPatch().patchTuning.mappingName.size() > 1)
kb.name = storage.getPatch().patchTuning.mappingName;
else
kb.name = storage.guessAtKBMName(kb);
storage.remapToKeyboard(kb);
}
else
{
storage.remapToConcertCKeyboard();
}
}
}
catch (Tunings::TuningError &e)
{
storage.reportError(e.what(), "Error restoring tuning!");
storage.reportError(e.what(), "Error applying tuning!");
storage.retuneTo12TETScaleC261Mapping();
}
}
else

try
{
storage.okCancelProvider(
std::string("Loaded patch contains a custom tuning, but there is ") +
"already a user-selected tuning in place. Do you want to replace the currently "
"loaded tuning with the tuning stored in the patch?" +
"The rest of the patch will load normally.",
"Replace Tuning", SurgeStorage::CANCEL, [this](SurgeStorage::OkCancel okc) {
if (okc == SurgeStorage::OK)
{
try
{
if (storage.getPatch().patchTuning.scaleContents.size() > 1)
{
storage.retuneToScale(Tunings::parseSCLData(
storage.getPatch().patchTuning.scaleContents));
}
else
{
storage.retuneTo12TETScale();
}
if (storage.getPatch().patchTuning.mappingContents.size() > 1)
{
auto kb = Tunings::parseKBMData(
storage.getPatch().patchTuning.mappingContents);
if (storage.getPatch().patchTuning.mappingName.size() > 1)
kb.name = storage.getPatch().patchTuning.mappingName;
else
kb.name = storage.guessAtKBMName(kb);
storage.remapToKeyboard(kb);
}
else
{
storage.remapToConcertCKeyboard();
}
}
catch (Tunings::TuningError &e)
{
storage.reportError(e.what(), "Error Restoring Tuning");
storage.retuneTo12TETScaleC261Mapping();
}
}
});
auto s = Tunings::evenTemperament12NoteScale();
auto m = Tunings::KeyboardMapping();
if (storage.getPatch().patchTuning.scaleContents.size() > 1)
{
s = Tunings::parseSCLData(storage.getPatch().patchTuning.scaleContents);
}
if (storage.getPatch().patchTuning.mappingContents.size() > 1)
{
m = Tunings::parseKBMData(storage.getPatch().patchTuning.mappingContents);
}
storage.patchStoredTuning = Tunings::Tuning(s, m);
storage.hasPatchStoredTuning = true;
}
catch (Tunings::TuningError &e)
{
storage.hasPatchStoredTuning = false;
storage.patchStoredTuning = Tunings::Tuning();
}
}
else
{
storage.hasPatchStoredTuning = false;
storage.patchStoredTuning = Tunings::Tuning();
}

masterfade = 1.f;
/*
Expand Down
7 changes: 6 additions & 1 deletion src/common/UserDefaults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ void initMaps()
case PatchJogWraparound:
r = "patchJogWraparound";
break;
case OverrideTuningOnPatchLoad:
r = "overrideTuningOnPatchLoad";
break;
case OverrideMappingOnPatchLoad:
r = "overrideMappingOnPatchLoad";
break;
case DefaultPatchAuthor:
r = "defaultPatchAuthor";
break;
Expand Down Expand Up @@ -158,7 +164,6 @@ void initMaps()
case InfoWindowPopupOnIdle:
r = "infoWindowPopupOnIdle";
break;

case TuningOverlayLocation:
r = "tuningOverlayLocation";
break;
Expand Down
3 changes: 3 additions & 0 deletions src/common/UserDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ enum DefaultKey // streamed as strings so feel free to change the order to whate
RememberTabPositionsPerScene,
PatchJogWraparound,

OverrideTuningOnPatchLoad,
OverrideMappingOnPatchLoad,

DefaultPatchAuthor,
DefaultPatchComment,
AppendOriginalPatchBy,
Expand Down
23 changes: 20 additions & 3 deletions src/surge-testrunner/UnitTestsIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <chrono>
#include <thread>

#include "UserDefaults.h"
#include <unordered_map>

using namespace Surge::Test;
Expand Down Expand Up @@ -415,34 +416,50 @@ TEST_CASE("Stream WaveTable Names", "[io]")
}
}

TEST_CASE("Load Patches with Embedded KBM")
TEST_CASE("Load Patches with Embedded KBM", "[io]")
{
std::vector<std::string> patches = {};
SECTION("Check Restore")
{
{
auto surge = Surge::Headless::createSurge(44100);
surge->storage.userPrefOverrides[Surge::Storage::OverrideTuningOnPatchLoad] = {true,
""};
surge->storage.userPrefOverrides[Surge::Storage::OverrideMappingOnPatchLoad] = {true,
""};
surge->loadPatchByPath("resources/test-data/patches/HasKBM.fxp", -1, "Test");
REQUIRE(!surge->storage.isStandardTuning);
REQUIRE(!surge->storage.isStandardScale);
REQUIRE(!surge->storage.isStandardMapping);
}

{
auto surge = Surge::Headless::createSurge(44100);
surge->storage.userPrefOverrides[Surge::Storage::OverrideTuningOnPatchLoad] = {true,
""};
surge->storage.userPrefOverrides[Surge::Storage::OverrideMappingOnPatchLoad] = {true,
""};
surge->loadPatchByPath("resources/test-data/patches/HasSCL.fxp", -1, "Test");
REQUIRE(!surge->storage.isStandardTuning);
REQUIRE(!surge->storage.isStandardScale);
REQUIRE(surge->storage.isStandardMapping);
}

{
auto surge = Surge::Headless::createSurge(44100);
surge->storage.userPrefOverrides[Surge::Storage::OverrideTuningOnPatchLoad] = {true,
""};
surge->storage.userPrefOverrides[Surge::Storage::OverrideMappingOnPatchLoad] = {true,
""};
surge->loadPatchByPath("resources/test-data/patches/HasSCLandKBM.fxp", -1, "Test");
REQUIRE(!surge->storage.isStandardTuning);
REQUIRE(!surge->storage.isStandardMapping);
}

{
auto surge = Surge::Headless::createSurge(44100);
surge->storage.userPrefOverrides[Surge::Storage::OverrideTuningOnPatchLoad] = {true,
""};
surge->storage.userPrefOverrides[Surge::Storage::OverrideMappingOnPatchLoad] = {true,
""};
surge->loadPatchByPath("resources/test-data/patches/HasSCL_165Vintage.fxp", -1, "Test");
REQUIRE(!surge->storage.isStandardTuning);
REQUIRE(surge->storage.isStandardMapping);
Expand Down
Loading

0 comments on commit a95c11f

Please sign in to comment.