Skip to content

Commit ebd1352

Browse files
authored
Support loading serialized plug-in states from v0.7.9 (#487)
1 parent ab9ea54 commit ebd1352

File tree

2 files changed

+100
-17
lines changed

2 files changed

+100
-17
lines changed

NeuralAmpModeler/NeuralAmpModeler.cpp

Lines changed: 94 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include <algorithm> // std::clamp
1+
#include <algorithm> // std::clamp, std::min
22
#include <cmath> // pow
33
#include <filesystem>
44
#include <iostream>
@@ -400,26 +400,28 @@ bool NeuralAmpModeler::SerializeState(IByteChunk& chunk) const
400400
int NeuralAmpModeler::UnserializeState(const IByteChunk& chunk, int startPos)
401401
{
402402
WDL_String header;
403-
startPos = chunk.GetStr(header, startPos);
404-
// TODO: Handle legacy plugin serialized states.
405-
// if strncmp (header.Get(), "###NeuralAmpModeler###")
406-
//{
407-
// return UnserializeStateLegacy(header, startPos); // (We'll assume 0.7.9).
408-
//}
409-
WDL_String version;
410-
startPos = chunk.GetStr(version, startPos);
411-
// Version-specific loading here if needed.
412-
// ...
413-
414-
// Current version loading:
415-
startPos = chunk.GetStr(mNAMPath, startPos);
416-
startPos = chunk.GetStr(mIRPath, startPos);
417-
int retcode = UnserializeParams(chunk, startPos);
403+
int pos = startPos;
404+
pos = chunk.GetStr(header, pos);
405+
// Unseralization:
406+
{
407+
// Handle legacy plugin serialized states:
408+
// In v0.7.9, this was the NAM filepath. So, if we dont' get the expected header, then we can attempt to unserialize
409+
// as v0.7.9:
410+
const char* kExpectedHeader = "###NeuralAmpModeler###";
411+
if (strcmp(header.Get(), kExpectedHeader) == 0)
412+
{
413+
pos = _UnserializeStateCurrent(chunk, pos);
414+
}
415+
else
416+
{
417+
pos = _UnserializeStateLegacy_0_7_9(chunk, startPos);
418+
}
419+
}
418420
if (mNAMPath.GetLength())
419421
_StageModel(mNAMPath);
420422
if (mIRPath.GetLength())
421423
_StageIR(mIRPath);
422-
return retcode;
424+
return pos;
423425
}
424426

425427
void NeuralAmpModeler::OnUIOpen()
@@ -804,6 +806,81 @@ void NeuralAmpModeler::_ProcessOutput(iplug::sample** inputs, iplug::sample** ou
804806
#endif
805807
}
806808

809+
int NeuralAmpModeler::_UnserializeStateCurrent(const IByteChunk& chunk, int pos)
810+
{
811+
WDL_String version;
812+
pos = chunk.GetStr(version, pos);
813+
// Post-v0.7.9 legacy loading here once needed:
814+
// ...
815+
816+
// Current version loading:
817+
pos = chunk.GetStr(mNAMPath, pos);
818+
pos = chunk.GetStr(mIRPath, pos);
819+
pos = UnserializeParams(chunk, pos);
820+
return pos;
821+
}
822+
823+
int NeuralAmpModeler::_UnserializeStateLegacy_0_7_9(const IByteChunk& chunk, int startPos)
824+
{
825+
WDL_String dir;
826+
int pos = startPos;
827+
pos = chunk.GetStr(mNAMPath, pos);
828+
pos = chunk.GetStr(mIRPath, pos);
829+
auto unserialize = [&](const IByteChunk& chunk, int startPos) {
830+
// cf IPluginBase::UnserializeParams(const IByteChunk& chunk, int startPos)
831+
832+
// These are the parameter names, in the order that they were serialized in v0.7.9.
833+
std::vector<std::string> oldParamNames{
834+
"Input", "Gate", "Bass", "Middle", "Treble", "Output", "NoiseGateActive", "ToneStack", "OutNorm", "IRToggle"};
835+
// These are their current names.
836+
// IF YOU CHANGE THE NAMES OF THE PARAMETERS, THEN YOU NEED TO UPDATE THIS!
837+
std::unordered_map<std::string, std::string> newNames{{"Gate", "Threshold"}};
838+
auto getParamByOldName = [&, newNames](std::string& oldName) {
839+
std::string name = newNames.find(oldName) != newNames.end() ? newNames.at(oldName) : oldName;
840+
// Could use a map but eh
841+
for (int i = 0; i < kNumParams; i++)
842+
{
843+
IParam* param = GetParam(i);
844+
if (strcmp(param->GetName(), name.c_str()) == 0)
845+
{
846+
return param;
847+
}
848+
}
849+
return (IParam*)nullptr;
850+
};
851+
TRACE
852+
int pos = startPos;
853+
ENTER_PARAMS_MUTEX
854+
int i = 0;
855+
for (auto it = oldParamNames.begin(); it != oldParamNames.end(); ++it, i++)
856+
{
857+
// Here's the change: instead of assuming that we can iterate through the parameters, we look for the one that now
858+
// holds this info.
859+
// IParam* pParam = mParams.Get(i);
860+
IParam* pParam = getParamByOldName(*it);
861+
862+
double v = 0.0;
863+
pos = chunk.Get(&v, pos);
864+
// It's possible that future versions will not have all of the params of previous versions. If that's the case,
865+
// then this is a null ptr and we skip it.
866+
if (pParam)
867+
{
868+
pParam->Set(v);
869+
Trace(TRACELOC, "%d %s %f", i, pParam->GetName(), pParam->Value());
870+
}
871+
else
872+
{
873+
Trace(TRACELOC, "%d NOT-FOUND", i);
874+
}
875+
}
876+
OnParamReset(kPresetRecall);
877+
LEAVE_PARAMS_MUTEX
878+
return pos;
879+
};
880+
pos = unserialize(chunk, pos);
881+
return pos;
882+
}
883+
807884
void NeuralAmpModeler::_UpdateMeters(sample** inputPointer, sample** outputPointer, const size_t nFrames,
808885
const size_t nChansIn, const size_t nChansOut)
809886
{

NeuralAmpModeler/NeuralAmpModeler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ class NeuralAmpModeler final : public iplug::Plugin
265265
// Resetting for models and IRs, called by OnReset
266266
void _ResetModelAndIR(const double sampleRate, const int maxBlockSize);
267267

268+
// Unserialize current-version plug-in data:
269+
int _UnserializeStateCurrent(const iplug::IByteChunk& chunk, int startPos);
270+
// Unserialize v0.7.9 legacy data:
271+
int _UnserializeStateLegacy_0_7_9(const iplug::IByteChunk& chunk, int startPos);
272+
// And other legacy unsrializations if/as needed...
273+
268274
// Update level meters
269275
// Called within ProcessBlock().
270276
// Assume _ProcessInput() and _ProcessOutput() were run immediately before.

0 commit comments

Comments
 (0)