From b1a395d60d89678187abf14932f3804288100793 Mon Sep 17 00:00:00 2001 From: jatinchowdhury18 Date: Wed, 17 Jan 2024 21:27:23 -0800 Subject: [PATCH] Better approach for forwarding parameter stability (#346) * New approach for forwarding parameter stability * More work * More comprehensive tests * Trying to fix test failures * Apply clang-format * More test tweaking * CI changes (for now) * More logging for test failures * Smarter root directory determination for tests * Resetting CI * Don't save forwarding param slots for processors when saving presets --------- Co-authored-by: github-actions[bot] --- .github/workflows/cmake.yml | 2 +- CMakeLists.txt | 2 +- src/BYOD.cpp | 2 +- src/headless/CMakeLists.txt | 5 + src/headless/tests/AmpIRsSaveLoadTest.cpp | 4 +- .../tests/ForwardingParamStabilityTest.cpp | 208 +++++++++++++++++- .../tests/OldParamForwardStates/test_0.txt | 1 + .../tests/OldParamForwardStates/test_0.xml | 135 ++++++++++++ .../tests/OldParamForwardStates/test_1.txt | 1 + .../tests/OldParamForwardStates/test_1.xml | 134 +++++++++++ .../tests/OldParamForwardStates/test_2.txt | 1 + .../tests/OldParamForwardStates/test_2.xml | 140 ++++++++++++ .../tests/OldParamForwardStates/test_3.txt | 1 + .../tests/OldParamForwardStates/test_3.xml | 137 ++++++++++++ .../tests/OldParamForwardStates/test_4.txt | 1 + .../tests/OldParamForwardStates/test_4.xml | 125 +++++++++++ src/headless/tests/UnitTests.h | 8 +- src/processors/BaseProcessor.cpp | 7 +- src/processors/BaseProcessor.h | 6 +- .../chain/ProcessorChainStateHelper.cpp | 21 +- .../chain/ProcessorChainStateHelper.h | 5 +- src/state/ParamForwardManager.cpp | 105 +++++++-- src/state/ParamForwardManager.h | 10 + src/state/StateManager.cpp | 11 +- src/state/StateManager.h | 3 +- src/state/presets/PresetManager.cpp | 2 +- 26 files changed, 1028 insertions(+), 49 deletions(-) create mode 100644 src/headless/tests/OldParamForwardStates/test_0.txt create mode 100644 src/headless/tests/OldParamForwardStates/test_0.xml create mode 100644 src/headless/tests/OldParamForwardStates/test_1.txt create mode 100644 src/headless/tests/OldParamForwardStates/test_1.xml create mode 100644 src/headless/tests/OldParamForwardStates/test_2.txt create mode 100644 src/headless/tests/OldParamForwardStates/test_2.xml create mode 100644 src/headless/tests/OldParamForwardStates/test_3.txt create mode 100644 src/headless/tests/OldParamForwardStates/test_3.xml create mode 100644 src/headless/tests/OldParamForwardStates/test_4.txt create mode 100644 src/headless/tests/OldParamForwardStates/test_4.xml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 4f1ed363..692885ce 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -75,7 +75,7 @@ jobs: run: cmake --build build --config Release --parallel 3 --target BYOD_Standalone BYOD_VST3 BYOD_CLAP BYOD_headless - name: Unit Tests - if: runner.os == 'Linux' + if: runner.os == 'Linux' || runner.os == 'MacOS' run: build/BYOD --unit-tests --all - name: Validate diff --git a/CMakeLists.txt b/CMakeLists.txt index 810a1c0e..deec7242 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12" CACHE STRING "Minimum OS X deployment ta if(WIN32) set(CMAKE_SYSTEM_VERSION 7.1 CACHE STRING INTERNAL FORCE) # Windows SDK for Windows 7 and up endif() -project(BYOD VERSION 1.2.1) +project(BYOD VERSION 1.2.2) set(CMAKE_CXX_STANDARD 20) # Useful for testing with address sanitizer: diff --git a/src/BYOD.cpp b/src/BYOD.cpp index 8730a864..ccc65155 100644 --- a/src/BYOD.cpp +++ b/src/BYOD.cpp @@ -131,7 +131,7 @@ void BYOD::getStateInformation (MemoryBlock& destData) void BYOD::setStateInformation (const void* data, int sizeInBytes) { - stateManager->loadState (getXmlFromBinary (data, sizeInBytes).get()); + stateManager->loadState (getXmlFromBinary (data, sizeInBytes).get(), *paramForwarder); if (wrapperType == WrapperType::wrapperType_AudioUnitv3) { diff --git a/src/headless/CMakeLists.txt b/src/headless/CMakeLists.txt index 28e6dd7d..e580113e 100644 --- a/src/headless/CMakeLists.txt +++ b/src/headless/CMakeLists.txt @@ -57,4 +57,9 @@ target_link_libraries(BYOD_headless PUBLIC BYOD ) +target_compile_definitions(BYOD_headless + PRIVATE + BYOD_ROOT_DIR="${CMAKE_SOURCE_DIR}" +) + set_target_properties(BYOD_headless PROPERTIES CXX_VISIBILITY_PRESET hidden) diff --git a/src/headless/tests/AmpIRsSaveLoadTest.cpp b/src/headless/tests/AmpIRsSaveLoadTest.cpp index 0bb3bacf..137cf851 100644 --- a/src/headless/tests/AmpIRsSaveLoadTest.cpp +++ b/src/headless/tests/AmpIRsSaveLoadTest.cpp @@ -36,9 +36,7 @@ class AmpIRsSaveLoadTest : public UnitTest const auto testIRFile = [] { - auto rootDir = File::getSpecialLocation (File::currentExecutableFile); - while (rootDir.getFileName() != "BYOD") - rootDir = rootDir.getParentDirectory(); + const auto rootDir = juce::File { BYOD_ROOT_DIR }; return rootDir.getChildFile ("src/headless/tests/test_ir.wav"); }(); diff --git a/src/headless/tests/ForwardingParamStabilityTest.cpp b/src/headless/tests/ForwardingParamStabilityTest.cpp index ca4fdc97..f4779be6 100644 --- a/src/headless/tests/ForwardingParamStabilityTest.cpp +++ b/src/headless/tests/ForwardingParamStabilityTest.cpp @@ -2,6 +2,70 @@ #include "processors/chain/ProcessorChainActionHelper.h" #include "state/ParamForwardManager.h" +#include "processors/drive/BlondeDrive.h" +#include "processors/drive/RangeBooster.h" +#include "processors/drive/Warp.h" +#include "processors/drive/big_muff/BigMuffDrive.h" +#include "processors/drive/diode_circuits/DiodeClipper.h" +#include "processors/drive/diode_circuits/DiodeRectifier.h" +#include "processors/drive/flapjack/Flapjack.h" +#include "processors/drive/zen_drive/ZenDrive.h" +#include "processors/modulation/Chorus.h" +#include "processors/modulation/Rotary.h" +#include "processors/modulation/Tremolo.h" +#include "processors/modulation/phaser/Phaser4.h" +#include "processors/modulation/phaser/Phaser8.h" +#include "processors/modulation/scanner_vibrato/ScannerVibrato.h" +#include "processors/modulation/uni_vibe/UniVibe.h" +#include "processors/other/Compressor.h" +#include "processors/other/Delay.h" +#include "processors/other/EnvelopeFilter.h" +#include "processors/other/spring_reverb/SpringReverbProcessor.h" +#include "processors/tone/BassCleaner.h" +#include "processors/tone/BigMuffTone.h" +#include "processors/tone/BlondeTone.h" +#include "processors/tone/GraphicEQ.h" +#include "processors/tone/HighCut.h" +#include "processors/tone/LofiIrs.h" +#include "processors/tone/ladder_filter/LadderFilterProcessor.h" +#include "processors/tone/tube_screamer_tone/TubeScreamerTone.h" + +template +static std::unique_ptr processorFactory (UndoManager* um) +{ + return std::make_unique (um); +} + +ProcessorStore::StoreMap minimalStore = { + { "Blonde Drive", { &processorFactory, { ProcessorType::Drive, 1, 1 } } }, + { "Diode Clipper", { &processorFactory, { ProcessorType::Drive, 1, 1 } } }, + { "Diode Rectifier", { &processorFactory, { ProcessorType::Drive, 1, 1 } } }, + { "Flapjack", { &processorFactory, { ProcessorType::Drive, 1, 1 } } }, + { "Muff Drive", { &processorFactory, { ProcessorType::Drive, 1, 1 } } }, + { "Range Booster", { &processorFactory, { ProcessorType::Drive, 1, 1 } } }, + { "Warp", { &processorFactory, { ProcessorType::Drive, 1, 1 } } }, + { "Yen Drive", { &processorFactory, { ProcessorType::Drive, 1, 1 } } }, + { "Bass Cleaner", { &processorFactory, { ProcessorType::Tone, 1, 1 } } }, + { "Blonde Tone", { &processorFactory, { ProcessorType::Tone, 1, 1 } } }, + { "Graphic EQ", { &processorFactory, { ProcessorType::Tone, 1, 1 } } }, + { "High Cut", { &processorFactory, { ProcessorType::Tone, 1, 1 } } }, + { "LoFi IRs", { &processorFactory, { ProcessorType::Tone, 1, 1 } } }, + { "Muff Tone", { &processorFactory, { ProcessorType::Tone, 1, 1 } } }, + { "TS-Tone", { &processorFactory, { ProcessorType::Tone, 1, 1 } } }, + { "Ladder Filter", { &processorFactory, { ProcessorType::Tone, 1, 1 } } }, + { "Chorus", { &processorFactory, { ProcessorType::Modulation, Chorus::numInputs, Chorus::numOutputs } } }, + { "Phaser4", { &processorFactory, { ProcessorType::Modulation, Phaser4::numInputs, Phaser4::numOutputs } } }, + { "Phaser8", { &processorFactory, { ProcessorType::Modulation, Phaser8::numInputs, Phaser8::numOutputs } } }, + { "Rotary", { &processorFactory, { ProcessorType::Modulation, Rotary::numInputs, Rotary::numOutputs } } }, + { "Scanner Vibrato", { &processorFactory, { ProcessorType::Modulation, ScannerVibrato::numInputs, ScannerVibrato::numOutputs } } }, + { "Solo-Vibe", { &processorFactory, { ProcessorType::Modulation, UniVibe::numInputs, UniVibe::numOutputs } } }, + { "Tremolo", { &processorFactory, { ProcessorType::Modulation, Tremolo::numInputs, Tremolo::numOutputs } } }, + { "DC Blocker", { &processorFactory, { ProcessorType::Utility, 1, 1 } } }, + { "Compressor", { &processorFactory, { ProcessorType::Other, Compressor::numInputs, Compressor::numOutputs } } }, + { "Delay", { &processorFactory, { ProcessorType::Other, 1, 1 } } }, + { "Envelope Filter", { &processorFactory, { ProcessorType::Other, EnvelopeFilter::numInputs, EnvelopeFilter::numOutputs } } }, +}; + class ForwardingParamStabilityTest : public UnitTest { public: @@ -13,7 +77,7 @@ class ForwardingParamStabilityTest : public UnitTest bool addProcessor (ProcessorChain& chain, UndoManager* um) { // get random processor - auto& storeMap = ProcessorStore::getStoreMap(); + auto& storeMap = minimalStore; auto storeIter = storeMap.begin(); int storeIndex = rand.nextInt ((int) storeMap.size()); std::advance (storeIter, storeIndex); @@ -53,13 +117,19 @@ class ForwardingParamStabilityTest : public UnitTest }; std::vector actions { + { "Add Processor", [&] + { return addProcessor (procChain, undoManager); } }, { "Add Processor", [&] { return addProcessor (procChain, undoManager); } }, { "Remove Processor", [&] { return removeProcessor (procChain); } }, }; - for (int count = 0; count < 100;) +#if JUCE_DEBUG + for (int count = 0; count < 9;) +#else + for (int count = 0; count < 19;) +#endif { auto& action = actions[rand.nextInt ((int) actions.size())]; if (action.action()) @@ -93,23 +163,151 @@ class ForwardingParamStabilityTest : public UnitTest for (auto [idx, param] : chowdsp::enumerate (forwardingParams)) { if (auto* forwardedParam = param->getParam()) + { expectEquals (forwardedParam->getName (1024).toStdString(), paramNames[idx], "Parameter name mismatch"); + } else + { expectEquals (std::string {}, paramNames[idx], "Parameter name mismatch"); + } + } + } + + void testLegacyState (int i) + { + /* + BYOD plugin; + auto* undoManager = plugin.getVTS().undoManager; + auto& procChain = plugin.getProcChain(); + + struct Action + { + String name; + std::function action; + }; + + std::vector actions { + { "Add Processor", [&] + { return addProcessor (procChain, undoManager); } }, + }; + + for (int count = 0; count < 9;) + { + auto& action = actions[rand.nextInt ((int) actions.size())]; + if (action.action()) + { + int timeUntilNextAction = rand.nextInt ({ 5, 500 }); + juce::MessageManager::getInstance()->runDispatchLoopUntil (timeUntilNextAction); + count++; + } + } + + auto& forwardingParams = plugin.getParamForwarder().getForwardedParameters(); + juce::StringArray paramNames {}; + for (auto [idx, param] : chowdsp::enumerate (forwardingParams)) + { + if (auto* forwardedParam = param->getParam()) + paramNames.add (forwardedParam->getName (1024).toStdString()); + else + paramNames.add ("EMPTY"); + } + + juce::MemoryBlock state; + plugin.getStateInformation (state); + + const auto file = juce::File { "test_" + juce::String { i } }; + file.withFileExtension ("txt").replaceWithText (paramNames.joinIntoString (",")); + + plugin.getXmlFromBinary (state.getData(), state.getSize())->writeToFile (file.withFileExtension ("xml"), ""); + */ + + const auto [stateFile, paramsFile] = [i] + { + const auto rootDir = juce::File { BYOD_ROOT_DIR }; + const auto fileDir = rootDir.getChildFile ("src/headless/tests/OldParamForwardStates"); + return std::make_pair (fileDir.getChildFile ("test_" + juce::String { i } + ".xml"), + fileDir.getChildFile ("test_" + juce::String { i } + ".txt")); + }(); + + juce::Logger::writeToLog ("Loading legacy state from file: " + stateFile.getFullPathName()); + jassert (stateFile.existsAsFile()); + const auto stateXml = XmlDocument::parse (stateFile); + jassert (stateXml != nullptr); + BYOD plugin; + juce::MemoryBlock state; + plugin.copyXmlToBinary (*stateXml, state); + plugin.setStateInformation (state.getData(), state.getSize()); + + juce::StringArray paramNames; + paramNames.addTokens (paramsFile.loadFileAsString(), ",", {}); + jassert (paramNames.size() == 500); + for (auto& name : paramNames) + name = name.trimCharactersAtStart (" "); + + auto& forwardingParams = plugin.getParamForwarder().getForwardedParameters(); + for (auto [idx, param] : chowdsp::enumerate (forwardingParams)) + { + if (auto* forwardedParam = param->getParam()) + { + expectEquals (forwardedParam->getName (1024), + paramNames[idx], + "Parameter name mismatch"); + } + else + { + expectEquals (juce::String { "EMPTY" }, + paramNames[idx], + "Parameter name mismatch"); + } } + + for (int i = 0; i < 20; ++i) + removeProcessor (plugin.getProcChain()); + jassert (plugin.getProcChain().getProcessors().size() == 0); + + addProcessor (plugin.getProcChain(), &plugin.getUndoManager()); + auto* ip = reinterpret_cast (plugin.getProcChain().getProcessors()[0]->getParameters()[0]); + + const auto& paramForwarder = plugin.getParamForwarder(); + expect (paramForwarder.getForwardedParameterFromInternal (*ip) == paramForwarder.getForwardedParameters()[0], + "Newly added parameter is not in the first parameter slot!"); } void runTest() override { - rand = Random { 1234 }; // getRandom(); + beginTest ("Check Max Parameter Count"); + runTestForAllProcessors ( + this, + [this] (BaseProcessor* proc) + { + expectLessThan (proc->getParameters().size(), + ParamForwardManager::maxParameterCount, + ""); + }, + {}, + false); beginTest ("Forwarding Parameter Stability Test"); - const auto [paramNames, state] = runPlugin(); - testPlugin (paramNames, state); + rand = Random { 1245 }; +#if JUCE_DEBUG + for (int i = 0; i < 1; ++i) +#else + for (int i = 0; i < 10; ++i) +#endif + { + const auto [paramNames, state] = runPlugin(); + testPlugin (paramNames, state); + } + + beginTest ("Legacy Forwarding Parameter Compatibility Test"); + for (int i = 0; i < 5; ++i) + { + testLegacyState (i); + } } Random rand; diff --git a/src/headless/tests/OldParamForwardStates/test_0.txt b/src/headless/tests/OldParamForwardStates/test_0.txt new file mode 100644 index 00000000..53edd16a --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_0.txt @@ -0,0 +1 @@ +On/Off,Cutoff,On/Off,IR,Gain,Mix,On/Off,Drive,Presence,Low Cut,Level,Mode,On/Off,Range,Boost,High Quality,On/Off,Tone,On/Off,Resonance,Freq.,Speed,Sensitivity,Freq. Mod,Type,Direct Control,On/Off,Rate,Depth,Feedback,Mix,Delay Type,On/Off,Delay Time,Cutoff,Feedback,Mix,Delay Rhythm,Tempo Sync,Delay Type,Ping-Pong,On/Off,Rate,Depth,Feedback,Mix,Delay Type,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY \ No newline at end of file diff --git a/src/headless/tests/OldParamForwardStates/test_0.xml b/src/headless/tests/OldParamForwardStates/test_0.xml new file mode 100644 index 00000000..bef9f83e --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_0.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/headless/tests/OldParamForwardStates/test_1.txt b/src/headless/tests/OldParamForwardStates/test_1.txt new file mode 100644 index 00000000..2f48f875 --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_1.txt @@ -0,0 +1 @@ +On/Off,Delay Time,Cutoff,Feedback,Mix,Delay Rhythm,Tempo Sync,Delay Type,Ping-Pong,On/Off,Cutoff,Drive,Diodes,# Diodes,On/Off,Cutoff,On/Off,Bass,Mids,Treble,On/Off,Sustain,Harmonics,Smoothing,Level,,High Quality,On/Off,Rate,Depth,Mix,Mode,Stereo,On/Off,Rate,Depth,Mix,Mode,Stereo,On/Off,HP CUT,HP RES,LP RES,LP CUT,DRIVE,FILTER MODE,On/Off,Cutoff,Drive,Diodes,# Diodes,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY \ No newline at end of file diff --git a/src/headless/tests/OldParamForwardStates/test_1.xml b/src/headless/tests/OldParamForwardStates/test_1.xml new file mode 100644 index 00000000..a0e99dde --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_1.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/headless/tests/OldParamForwardStates/test_2.txt b/src/headless/tests/OldParamForwardStates/test_2.txt new file mode 100644 index 00000000..4b069a7c --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_2.txt @@ -0,0 +1 @@ +On/Off,Cutoff,Drive,Diodes,# Diodes,On/Off,Drive,Presence,Low Cut,Level,Mode,On/Off,IR,Gain,Mix,On/Off,Rate,Wave,Depth,Stereo,V1 Wave,On/Off,Tone,Mids,Type,On/Off,HP CUT,HP RES,LP RES,LP CUT,DRIVE,FILTER MODE,On/Off,Rate,Depth,Feedback,Mix,Delay Type,On/Off,HP CUT,HP RES,LP RES,LP CUT,DRIVE,FILTER MODE,On/Off,100,220,500,1k,2.2k,5k,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY \ No newline at end of file diff --git a/src/headless/tests/OldParamForwardStates/test_2.xml b/src/headless/tests/OldParamForwardStates/test_2.xml new file mode 100644 index 00000000..c3517e0f --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_2.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/headless/tests/OldParamForwardStates/test_3.txt b/src/headless/tests/OldParamForwardStates/test_3.txt new file mode 100644 index 00000000..aa4df9cd --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_3.txt @@ -0,0 +1 @@ +On/Off,Cutoff,Drive,Diodes,# Diodes,On/Off,Rate,Depth,Feedback,Mix,FB Stage,Stereo,On/Off,Threshold,Ratio,Knee,Attack,Release,Gain,On/Off,Bass,Mids,Treble,On/Off,Clean,On/Off,Sustain,Harmonics,Smoothing,Level,,High Quality,On/Off,Speed,Intensity,# Stages,Stereo,Mix,On/Off,Delay Time,Cutoff,Feedback,Mix,Delay Rhythm,Tempo Sync,Delay Type,Ping-Pong,On/Off,Drive,Character,Bias,High Quality,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY \ No newline at end of file diff --git a/src/headless/tests/OldParamForwardStates/test_3.xml b/src/headless/tests/OldParamForwardStates/test_3.xml new file mode 100644 index 00000000..6cfd5b60 --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_3.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/headless/tests/OldParamForwardStates/test_4.txt b/src/headless/tests/OldParamForwardStates/test_4.txt new file mode 100644 index 00000000..0928b660 --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_4.txt @@ -0,0 +1 @@ +On/Off,Freq,Gain,Feedback,FB Drive,On/Off,Drive,Character,Bias,High Quality,On/Off,Resonance,Freq.,Speed,Sensitivity,Freq. Mod,Type,Direct Control,On/Off,Tone,On/Off,Cutoff,On/Off,IR,Gain,Mix,On/Off,Bass,Mids,Treble,On/Off,Range,Boost,High Quality,On/Off,Rate,Depth,Feedback,Mix,Delay Type,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY \ No newline at end of file diff --git a/src/headless/tests/OldParamForwardStates/test_4.xml b/src/headless/tests/OldParamForwardStates/test_4.xml new file mode 100644 index 00000000..314ed686 --- /dev/null +++ b/src/headless/tests/OldParamForwardStates/test_4.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/headless/tests/UnitTests.h b/src/headless/tests/UnitTests.h index 5cf98d7a..9a2b4031 100644 --- a/src/headless/tests/UnitTests.h +++ b/src/headless/tests/UnitTests.h @@ -1,6 +1,9 @@ #include "../../BYOD.h" -static inline void runTestForAllProcessors (UnitTest* ut, const std::function& testFunc, const StringArray& procsToSkip = {}) +static inline void runTestForAllProcessors (UnitTest* ut, + const std::function& testFunc, + const StringArray& procsToSkip = {}, + bool startNewTest = true) { PlayheadHelpers playheadHelper; for (auto [name, storeEntry] : ProcessorStore::getStoreMap()) @@ -13,7 +16,8 @@ static inline void runTestForAllProcessors (UnitTest* ut, const std::functionplayheadHelpers = &playheadHelper; - ut->beginTest (proc->getName() + " Test"); + if (startNewTest) + ut->beginTest (proc->getName() + " Test"); testFunc (proc.get()); proc->freeInternalMemory(); } diff --git a/src/processors/BaseProcessor.cpp b/src/processors/BaseProcessor.cpp index bdf645dd..726d05a4 100644 --- a/src/processors/BaseProcessor.cpp +++ b/src/processors/BaseProcessor.cpp @@ -1,6 +1,7 @@ #include "BaseProcessor.h" #include "gui/pedalboard/editors/ProcessorEditor.h" #include "netlist_helpers/NetlistViewer.h" +#include "state/ParamForwardManager.h" BaseProcessor::BaseProcessor (const String& name, ParamLayout params, @@ -139,7 +140,7 @@ std::unique_ptr BaseProcessor::toXML() xml->setAttribute ("x_pos", (double) editorPosition.x); xml->setAttribute ("y_pos", (double) editorPosition.y); - xml->setAttribute ("forwarding_params_offset", forwardingParamsStartIndex); + xml->setAttribute (chowdsp::toString (ParamForwardManager::processorSlotIndexTag), forwardingParamsSlotIndex); if (netlistCircuitQuantities != nullptr) { @@ -164,6 +165,8 @@ void BaseProcessor::fromXML (XmlElement* xml, const chowdsp::Version&, bool load vts.state = ValueTree::fromXml (*xml); // don't use `replaceState()` otherwise UndoManager will clear + forwardingParamsSlotIndex = xml->getIntAttribute (chowdsp::toString (ParamForwardManager::processorSlotIndexTag), -1); + if (loadPosition) loadPositionInfoFromXML (xml); @@ -205,8 +208,6 @@ void BaseProcessor::loadPositionInfoFromXML (XmlElement* xml) auto xPos = (float) xml->getDoubleAttribute ("x_pos"); auto yPos = (float) xml->getDoubleAttribute ("y_pos"); editorPosition = juce::Point { xPos, yPos }; - - forwardingParamsStartIndex = xml->getIntAttribute ("forwarding_params_offset", -1); } void BaseProcessor::addConnection (ConnectionInfo&& info) diff --git a/src/processors/BaseProcessor.h b/src/processors/BaseProcessor.h index b2083ebb..bb67d951 100644 --- a/src/processors/BaseProcessor.h +++ b/src/processors/BaseProcessor.h @@ -186,8 +186,8 @@ class BaseProcessor : private JuceProcWrapper juce::Point getPosition (Rectangle parentBounds); const auto& getParameters() const { return AudioProcessor::getParameters(); } - int getForwardingParametersIndexOffset() const noexcept { return forwardingParamsStartIndex; } - void setForwardingParametersIndexOffset (int offset) { forwardingParamsStartIndex = offset; } + int getForwardingParameterSlotIndex() const noexcept { return forwardingParamsSlotIndex; } + void setForwardingParameterSlotIndex (int index) { forwardingParamsSlotIndex = index; } bool isOutputModulationPortConnected(); const std::vector* getParametersToDisableWhenInputIsConnected (int portIndex) const noexcept; @@ -314,7 +314,7 @@ class BaseProcessor : private JuceProcWrapper std::unordered_map> paramsToDisableWhenInputConnected {}; std::unordered_map> paramsToEnableWhenInputConnected {}; - int forwardingParamsStartIndex = -1; + int forwardingParamsSlotIndex = -1; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BaseProcessor) }; diff --git a/src/processors/chain/ProcessorChainStateHelper.cpp b/src/processors/chain/ProcessorChainStateHelper.cpp index 6593504a..9a1bb603 100644 --- a/src/processors/chain/ProcessorChainStateHelper.cpp +++ b/src/processors/chain/ProcessorChainStateHelper.cpp @@ -42,7 +42,8 @@ void ProcessorChainStateHelper::loadProcChain (const XmlElement* xml, const chowdsp::Version& stateVersion, bool loadingPreset, Component* associatedComponent, - WaitableEvent* waiter) + WaitableEvent* waiter, + ParamForwardManager* paramForwardManager) { if (xml == nullptr) { @@ -56,22 +57,34 @@ void ProcessorChainStateHelper::loadProcChain (const XmlElement* xml, loadingPreset, xmlState = *xml, safeComp = Component::SafePointer { associatedComponent }, - waiter] + waiter, + paramForwardManager] { + using namespace chowdsp::version_literals; + if (paramForwardManager != nullptr && stateVersion <= "1.2.1"_v) + paramForwardManager->setUsingLegacyMode (true); + loadProcChainInternal (&xmlState, stateVersion, loadingPreset, safeComp.getComponent()); + + if (paramForwardManager != nullptr && stateVersion <= "1.2.1"_v) + paramForwardManager->setUsingLegacyMode (false); + if (waiter != nullptr) waiter->signal(); }); } -std::unique_ptr ProcessorChainStateHelper::saveProcChain() +std::unique_ptr ProcessorChainStateHelper::saveProcChain (bool savingPreset) { auto xml = std::make_unique (procChainStateTag); auto saveProcessor = [&] (BaseProcessor* proc) { auto procXml = std::make_unique (ChainStateHelperFuncs::getProcessorTagName (proc)); - procXml->addChildElement (proc->toXML().release()); + auto procParamsXml = proc->toXML(); + if (savingPreset) + procParamsXml->removeAttribute (chowdsp::toString (ParamForwardManager::processorSlotIndexTag)); + procXml->addChildElement (procParamsXml.release()); for (int portIdx = 0; portIdx < proc->getNumOutputs(); ++portIdx) { diff --git a/src/processors/chain/ProcessorChainStateHelper.h b/src/processors/chain/ProcessorChainStateHelper.h index ac854a42..ae1ba5f2 100644 --- a/src/processors/chain/ProcessorChainStateHelper.h +++ b/src/processors/chain/ProcessorChainStateHelper.h @@ -7,12 +7,13 @@ class ProcessorChainStateHelper public: ProcessorChainStateHelper (ProcessorChain& thisChain, chowdsp::DeferredAction& deferredAction); - std::unique_ptr saveProcChain(); + std::unique_ptr saveProcChain (bool savingPreset = false); void loadProcChain (const XmlElement* xml, const chowdsp::Version& stateVersion, bool loadingPreset = false, Component* associatedComponent = nullptr, - WaitableEvent* waiter = nullptr); + WaitableEvent* waiter = nullptr, + ParamForwardManager* paramForwardManager = nullptr); static bool validateProcChainState (const XmlElement* xml, const ProcessorStore& processorStore); diff --git a/src/state/ParamForwardManager.cpp b/src/state/ParamForwardManager.cpp index 293aa191..6b5e94d2 100644 --- a/src/state/ParamForwardManager.cpp +++ b/src/state/ParamForwardManager.cpp @@ -46,13 +46,24 @@ const RangedAudioParameter* ParamForwardManager::getForwardedParameterFromIntern return nullptr; } +int ParamForwardManager::getNextUnusedParamSlot() const +{ + for (int i = 0; i < numParamSlots; ++i) + if (! paramSlotUsed[i]) + return i; + + return -1; +} + void ParamForwardManager::processorAdded (BaseProcessor* proc) { auto& procParams = proc->getParameters(); const auto numParams = procParams.size(); - const auto setForwardParameterRange = [this, &procParams, &proc, numParams] (int startOffset) + const auto setForwardParameterRange = [this, &procParams, &proc, numParams] (int slotIndex) { + paramSlotUsed[slotIndex] = true; + const auto startOffset = slotIndex * maxParameterCount; setParameterRange (startOffset, startOffset + numParams, [&procParams, &proc, startOffset] (int index) -> chowdsp::ParameterForwardingInfo @@ -67,12 +78,10 @@ void ParamForwardManager::processorAdded (BaseProcessor* proc) }); }; - if (const auto savedOffset = proc->getForwardingParametersIndexOffset(); savedOffset >= 0) - { - setForwardParameterRange (savedOffset); - } - else + if (usingLegacyMode) { + jassert (proc->getForwardingParameterSlotIndex() < 0); + // Find a range in forwardedParams with numParams empty params in a row int count = 0; for (int i = 0; i < (int) forwardedParams.size(); ++i) @@ -84,42 +93,100 @@ void ParamForwardManager::processorAdded (BaseProcessor* proc) if (count == numParams) { - int startOffset = [i, numParams, proc] - { - const auto savedOffset = proc->getForwardingParametersIndexOffset(); - if (savedOffset >= 0) - return savedOffset; - return i + 1 - numParams; - }(); - proc->setForwardingParametersIndexOffset (startOffset); - setForwardParameterRange (startOffset); - break; + int startOffset = i + 1 - numParams; + setParameterRange (startOffset, + startOffset + numParams, + [&procParams, &proc, startOffset] (int index) -> chowdsp::ParameterForwardingInfo + { + auto* procParam = procParams[index - startOffset]; + + if (auto* paramCast = dynamic_cast (procParam)) + return { paramCast, proc->getName() + ": " + paramCast->name }; + + jassertfalse; + return {}; + }); + + const auto startSlot = startOffset / maxParameterCount; + const auto endSlot = ((startOffset + numParams) / maxParameterCount); + std::fill (paramSlotUsed + startSlot, paramSlotUsed + endSlot + 1, true); + + return; } } } + + if (auto slotIndex = proc->getForwardingParameterSlotIndex(); slotIndex >= 0) + { + jassert (! paramSlotUsed[slotIndex]); + setForwardParameterRange (slotIndex); + } + else + { + slotIndex = getNextUnusedParamSlot(); + if (slotIndex < 0) + { + juce::Logger::writeToLog ("Unable to set up forwarding parameters for " + proc->getName() + " - no free slots available!"); + return; + } + + proc->setForwardingParameterSlotIndex (slotIndex); + setForwardParameterRange (slotIndex); + } } void ParamForwardManager::processorRemoved (const BaseProcessor* proc) { auto& procParams = proc->getParameters(); + const auto numParams = procParams.size(); - if (const auto savedOffset = proc->getForwardingParametersIndexOffset(); savedOffset >= 0) + if (const auto slotIndex = proc->getForwardingParameterSlotIndex(); slotIndex >= 0) { - clearParameterRange (savedOffset, savedOffset + procParams.size()); + paramSlotUsed[slotIndex] = false; + const auto startOffset = slotIndex * maxParameterCount; + clearParameterRange (startOffset, startOffset + numParams); } else { + int startIndex = -1; for (auto [index, param] : sst::cpputils::enumerate (forwardedParams)) { if (auto* internalParam = param->getParam(); internalParam == procParams[0]) { - clearParameterRange ((int) index, (int) index + procParams.size()); + startIndex = static_cast (index); + clearParameterRange (startIndex, startIndex + numParams); break; } } + + if (startIndex >= 0) + { + const auto startSlot = startIndex / maxParameterCount; + const auto endSlot = ((startIndex + numParams) / maxParameterCount); + for (int checkSlotIndex = startSlot; checkSlotIndex <= endSlot; ++checkSlotIndex) + { + bool slotUsed = false; + for (int i = checkSlotIndex * maxParameterCount; i < (checkSlotIndex + 1) * maxParameterCount; ++i) + { + if (forwardedParams[i]->getParam() != nullptr) + { + slotUsed = true; + break; + } + } + + if (! slotUsed) + paramSlotUsed[checkSlotIndex] = false; + } + } } } +void ParamForwardManager::setUsingLegacyMode (bool useLegacy) +{ + usingLegacyMode = useLegacy; +} + void ParamForwardManager::deferHostNotificationsGlobalSettingChanged (SettingID settingID) { if (settingID != refreshParamTreeID) diff --git a/src/state/ParamForwardManager.h b/src/state/ParamForwardManager.h index 8616455c..43badd08 100644 --- a/src/state/ParamForwardManager.h +++ b/src/state/ParamForwardManager.h @@ -8,6 +8,10 @@ class ParamForwardManager : public chowdsp::ForwardingParametersManager deferHostNotifs {}; + bool paramSlotUsed[numParamSlots] {}; + bool usingLegacyMode = false; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParamForwardManager) }; diff --git a/src/state/StateManager.cpp b/src/state/StateManager.cpp index 9db45a5d..00d9d1b8 100644 --- a/src/state/StateManager.cpp +++ b/src/state/StateManager.cpp @@ -39,7 +39,7 @@ std::unique_ptr StateManager::saveState() return xml; } -void StateManager::loadState (XmlElement* xmlState) +void StateManager::loadState (XmlElement* xmlState, ParamForwardManager& paramForwardManager) { if (xmlState == nullptr) // invalid XML return; @@ -69,9 +69,14 @@ void StateManager::loadState (XmlElement* xmlState) std::unique_ptr waiter; if (pluginWrapperType != AudioProcessor::WrapperType::wrapperType_AAX) waiter = std::make_unique(); - procChain.getStateHelper().loadProcChain (procChainXml, pluginVersion, false, nullptr, waiter.get()); + procChain.getStateHelper().loadProcChain (procChainXml, + pluginVersion, + false, + nullptr, + waiter.get(), + ¶mForwardManager); if (waiter != nullptr) - waiter->wait (1000); + waiter->wait (5000); std::optional mml {}; if (pluginWrapperType != AudioProcessor::WrapperType::wrapperType_AAX) diff --git a/src/state/StateManager.h b/src/state/StateManager.h index e6696ec8..7fd73bb2 100644 --- a/src/state/StateManager.h +++ b/src/state/StateManager.h @@ -2,6 +2,7 @@ #include "processors/chain/ProcessorChain.h" +class ParamForwardManager; class StateManager { public: @@ -10,7 +11,7 @@ class StateManager chowdsp::PresetManager& presetManager); std::unique_ptr saveState(); - void loadState (XmlElement* xml); + void loadState (XmlElement* xml, ParamForwardManager& paramForwardManager); auto& getUIState() { return uiState; } diff --git a/src/state/presets/PresetManager.cpp b/src/state/presets/PresetManager.cpp index 4f4c0de7..fb42da12 100644 --- a/src/state/presets/PresetManager.cpp +++ b/src/state/presets/PresetManager.cpp @@ -283,7 +283,7 @@ void PresetManager::filterPresets (std::vector& presets, const std::unique_ptr PresetManager::savePresetState() { - auto xml = procChain->getStateHelper().saveProcChain(); + auto xml = procChain->getStateHelper().saveProcChain (true); StateManager::setCurrentPluginVersionInXML (xml.get()); return xml; }