Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make NAM disablable - bypass dry signal #494

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 53 additions & 8 deletions NeuralAmpModeler/NeuralAmpModeler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info)
GetParam(kEQActive)->InitBool("ToneStack", true);
GetParam(kOutNorm)->InitBool("OutNorm", true);
GetParam(kIRToggle)->InitBool("IRToggle", true);
GetParam(kNamToggle)->InitBool("NAMToggle", mNamActive);

mNoiseGateTrigger.AddListener(&mNoiseGateGain);

Expand Down Expand Up @@ -201,7 +202,7 @@ NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info)

pGraphics->AttachBackground(BACKGROUND_FN);
pGraphics->AttachControl(new IBitmapControl(b, linesBitmap));
pGraphics->AttachControl(new IVLabelControl(titleArea, "NEURAL AMP MODELER", titleStyle));
pGraphics->AttachControl(new NAMTitleToggleControl(titleArea, kNamToggle, titleStyle.valueText));
pGraphics->AttachControl(new ISVGControl(modelIconArea, modelIconSVG));

#ifdef NAM_PICK_DIRECTORY
Expand Down Expand Up @@ -256,7 +257,10 @@ NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info)
pControl->SetMouseOverWhenDisabled(true);
});

pGraphics->GetControlWithTag(kCtrlTagOutNorm)->SetMouseEventsWhenDisabled(false);
pGraphics->GetControlWithParamIdx(kOutNorm)->SetMouseEventsWhenDisabled(false);
pGraphics->GetControlWithParamIdx(kNoiseGateActive)->SetMouseEventsWhenDisabled(false);
pGraphics->GetControlWithParamIdx(kEQActive)->SetMouseEventsWhenDisabled(false);
pGraphics->GetControlWithParamIdx(kIRToggle)->SetMouseEventsWhenDisabled(false);
};
}

Expand All @@ -273,6 +277,13 @@ void NeuralAmpModeler::ProcessBlock(iplug::sample** inputs, iplug::sample** outp
const size_t numFrames = (size_t)nFrames;
const double sampleRate = GetSampleRate();

if (!mNamActive)
{
_ProcessOutput(inputs, outputs, numFrames, numChannelsInternal, numChannelsExternalOut);
_UpdateMeters(inputs, outputs, numFrames, numChannelsInternal, numChannelsExternalOut);
return;
sdatkinson marked this conversation as resolved.
Show resolved Hide resolved
}

// Disable floating point denormals
std::fenv_t fe_state;
std::feholdexcept(&fe_state);
Expand Down Expand Up @@ -376,7 +387,10 @@ void NeuralAmpModeler::OnIdle()
if (mNewModelLoadedInDSP)
{
if (auto* pGraphics = GetUI())
pGraphics->GetControlWithTag(kCtrlTagOutNorm)->SetDisabled(!mModel->HasLoudness());
{
pGraphics->GetControlWithTag(kCtrlTagOutNorm)
->SetDisabled(!mModel->HasLoudness() || !GetParam(kNamToggle)->Value());
}

mNewModelLoadedInDSP = false;
}
Expand Down Expand Up @@ -410,7 +424,17 @@ int NeuralAmpModeler::UnserializeState(const IByteChunk& chunk, int startPos)
const char* kExpectedHeader = "###NeuralAmpModeler###";
if (strcmp(header.Get(), kExpectedHeader) == 0)
{
pos = _UnserializeStateCurrent(chunk, pos);
WDL_String version;
pos = chunk.GetStr(version, pos);

if (strcmp(version.Get(), "0.7.10") == 0)
{
pos = _UnserializeStateLegacy_0_7_9(chunk, pos);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, as I think of this, it might not be right--I think that one of the params' names was changed in v0.7.10:

ddd5ff8#diff-583ead9e08b2afc1f331a5073c88faea9cc55bdbfde16d357dee55438e63f19dL78

I think I thought that would make the unserialization behave differently. Let me check...

Yeah: ebd1352#diff-583ead9e08b2afc1f331a5073c88faea9cc55bdbfde16d357dee55438e63f19dR839

But the funny thing is that I managed to code it (I think) in a way that still works for v0.7.10--newNames.find(oldName) will miss on "Threshold" and will just use "Threshold"...which will work (I think)! Not sure if past me did that on purpose, but I'm glad he did 😉

If you could double-check this for me that it does in fact work as expected (after I bump the version) that'd be super-appreciated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like, it works as you described.
After bumping the plugin version to 0.7.11 locally, I was able to properly open my DAW session (saved with 0.7.10) and restore correct params values.

}
else
{
pos = _UnserializeStateCurrent(chunk, pos);
}
}
else
{
Expand Down Expand Up @@ -455,6 +479,7 @@ void NeuralAmpModeler::OnParamChange(int paramIdx)
case kToneBass: mToneStack->SetParam("bass", GetParam(paramIdx)->Value()); break;
case kToneMid: mToneStack->SetParam("middle", GetParam(paramIdx)->Value()); break;
case kToneTreble: mToneStack->SetParam("treble", GetParam(paramIdx)->Value()); break;
case kNamToggle: mNamActive = GetParam(paramIdx)->Value(); break;
default: break;
}
}
Expand All @@ -471,7 +496,8 @@ void NeuralAmpModeler::OnParamChangeUI(int paramIdx, EParamSource source)
case kEQActive:
pGraphics->ForControlInGroup("EQ_KNOBS", [active](IControl* pControl) { pControl->SetDisabled(!active); });
break;
case kIRToggle: pGraphics->GetControlWithTag(kCtrlTagIRFileBrowser)->SetDisabled(!active);
case kIRToggle: pGraphics->GetControlWithTag(kCtrlTagIRFileBrowser)->SetDisabled(!active); break;
case kNamToggle: _SetDisabledForAllControl(!active); break;
default: break;
}
}
Expand Down Expand Up @@ -790,7 +816,7 @@ void NeuralAmpModeler::_ProcessInput(iplug::sample** inputs, const size_t nFrame
void NeuralAmpModeler::_ProcessOutput(iplug::sample** inputs, iplug::sample** outputs, const size_t nFrames,
const size_t nChansIn, const size_t nChansOut)
{
const double gain = pow(10.0, GetParam(kOutputLevel)->Value() / 20.0);
const double gain = mNamActive ? pow(10.0, GetParam(kOutputLevel)->Value() / 20.0) : 1;
// Assume _PrepareBuffers() was already called
if (nChansIn != 1)
throw std::runtime_error("Plugin is supposed to process in mono.");
Expand All @@ -808,8 +834,6 @@ void NeuralAmpModeler::_ProcessOutput(iplug::sample** inputs, iplug::sample** ou

int NeuralAmpModeler::_UnserializeStateCurrent(const IByteChunk& chunk, int pos)
{
WDL_String version;
pos = chunk.GetStr(version, pos);
// Post-v0.7.9 legacy loading here once needed:
// ...

Expand Down Expand Up @@ -900,3 +924,24 @@ void NeuralAmpModeler::_UpdateMeters(sample** inputPointer, sample** outputPoint
mInputSender.ProcessBlock(inputPointer, (int)nFrames, kCtrlTagInputMeter, nChansHack);
mOutputSender.ProcessBlock(outputPointer, (int)nFrames, kCtrlTagOutputMeter, nChansHack);
}

void NeuralAmpModeler::_SetDisabledForAllControl(const bool disabled)
sdatkinson marked this conversation as resolved.
Show resolved Hide resolved
{
if (const auto ui = GetUI(); ui != nullptr)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something that makes this try again later if GetUI() returns null?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but (although I am not very familiar with iPlug) I think that GetUI() should never return null when GUI was attached unless there's there's some problem, but please correct me if I am wrong.

{
ui->GetControlWithParamIdx(kEQActive)->SetDisabled(disabled);
ui->GetControlWithParamIdx(kOutNorm)->SetDisabled(disabled);

ui->GetControlWithTag(kCtrlTagModelFileBrowser)->SetDisabled(disabled);
ui->GetControlWithTag(kCtrlTagIRFileBrowser)->SetDisabled(disabled);

ui->GetControlWithParamIdx(kNoiseGateActive)->SetDisabled(disabled);
ui->GetControlWithParamIdx(kNoiseGateThreshold)->SetDisabled(disabled || !GetParam(kNoiseGateActive)->Value());
ui->GetControlWithParamIdx(kInputLevel)->SetDisabled(disabled);
ui->GetControlWithParamIdx(kOutputLevel)->SetDisabled(disabled);
ui->GetControlWithParamIdx(kIRToggle)->SetDisabled(disabled);

ui->ForControlInGroup(
"EQ_KNOBS", [disabled, this](auto* ctrl) { ctrl->SetDisabled(disabled || !GetParam(kEQActive)->Value()); });
}
}
6 changes: 6 additions & 0 deletions NeuralAmpModeler/NeuralAmpModeler.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum EParams
kEQActive,
kOutNorm,
kIRToggle,
kNamToggle,
kNumParams
};

Expand Down Expand Up @@ -243,6 +244,9 @@ class NeuralAmpModeler final : public iplug::Plugin
void _UpdateMeters(iplug::sample** inputPointer, iplug::sample** outputPointer, const size_t nFrames,
const size_t nChansIn, const size_t nChansOut);

// Toggles Disabled flag for all controls
void _SetDisabledForAllControl(const bool disabled);

// Member data

// Input arrays to NAM
Expand Down Expand Up @@ -286,4 +290,6 @@ class NeuralAmpModeler final : public iplug::Plugin
std::unordered_map<std::string, double> mNAMParams = {{"Input", 0.0}, {"Output", 0.0}};

NAMSender mInputSender, mOutputSender;

bool mNamActive{true};
};
27 changes: 26 additions & 1 deletion NeuralAmpModeler/NeuralAmpModelerControls.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ class NAMFileBrowserControl : public IDirBrowseControlBase
auto clearFileFunc = [&](IControl* pCaller) {
pCaller->GetDelegate()->SendArbitraryMsgFromUI(mClearMsgTag);
mFileNameControl->SetLabelAndTooltip(mDefaultLabelStr.Get());
pCaller->GetUI()->GetControlWithTag(kCtrlTagOutNorm)->SetDisabled(false);

const bool namActive = pCaller->GetUI()->GetControlWithParamIdx(kNamToggle)->GetValue();
sdatkinson marked this conversation as resolved.
Show resolved Hide resolved
pCaller->GetUI()->GetControlWithTag(kCtrlTagOutNorm)->SetDisabled(!namActive);
};

auto chooseFileFunc = [&, loadFileFunc](IControl* pCaller) {
Expand Down Expand Up @@ -558,3 +560,26 @@ class NAMAboutBoxControl : public IContainerBase
int mAnimationTime = 200;
bool mWillHide = false;
};

class NAMTitleToggleControl : public ITextToggleControl
sdatkinson marked this conversation as resolved.
Show resolved Hide resolved
{
public:
NAMTitleToggleControl(const IRECT& bounds, int paramIdx, const IText& text)
: ITextToggleControl(bounds, paramIdx, "NEURAL AMP MODELER", "NEURAL AMP MODELER", text)
{
}

void Draw(IGraphics& g) override
{
if (GetValue())
{
SetText(mText.WithFGColor(COLOR_WHITE));
}
else
{
SetText(mText.WithFGColor(COLOR_BLACK));
}

ITextToggleControl::Draw(g);
}
};