Skip to content

Commit

Permalink
Merge branch 'sdatkinson:main' into themeColors
Browse files Browse the repository at this point in the history
  • Loading branch information
fichl authored May 11, 2024
2 parents c862787 + 3c05ec1 commit 2915141
Show file tree
Hide file tree
Showing 25 changed files with 258 additions and 68 deletions.
82 changes: 49 additions & 33 deletions NeuralAmpModeler/NeuralAmpModeler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ EMsgBoxResult _ShowMessageBox(iplug::igraphics::IGraphics* pGraphics, const char
NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info)
: Plugin(info, MakeConfig(kNumParams, kNumPresets))
{
_InitToneStack();
nam::activations::Activation::enable_fast_tanh();
GetParam(kInputLevel)->InitGain("Input", 0.0, -20.0, 20.0, 0.1);
GetParam(kToneBass)->InitDouble("Bass", 5.0, 0.0, 10.0, 0.1);
Expand Down Expand Up @@ -325,38 +326,8 @@ void NeuralAmpModeler::ProcessBlock(iplug::sample** inputs, iplug::sample** outp
sample** gateGainOutput =
noiseGateActive ? mNoiseGateGain.Process(mOutputPointers, numChannelsInternal, numFrames) : mOutputPointers;

sample** toneStackOutPointers = gateGainOutput;
if (toneStackActive)
{
// Translate params from knob 0-10 to dB.
// Tuned ranges based on my ear. E.g. seems treble doesn't need nearly as
// much swing as bass can use.
const double bassGainDB = 4.0 * (GetParam(kToneBass)->Value() - 5.0); // +/- 20
const double midGainDB = 3.0 * (GetParam(kToneMid)->Value() - 5.0); // +/- 15
const double trebleGainDB = 2.0 * (GetParam(kToneTreble)->Value() - 5.0); // +/- 10

const double bassFrequency = 150.0;
const double midFrequency = 425.0;
const double trebleFrequency = 1800.0;
const double bassQuality = 0.707;
// Wider EQ on mid bump up to sound less honky.
const double midQuality = midGainDB < 0.0 ? 1.5 : 0.7;
const double trebleQuality = 0.707;

// Define filter parameters
recursive_linear_filter::BiquadParams bassParams(sampleRate, bassFrequency, bassQuality, bassGainDB);
recursive_linear_filter::BiquadParams midParams(sampleRate, midFrequency, midQuality, midGainDB);
recursive_linear_filter::BiquadParams trebleParams(sampleRate, trebleFrequency, trebleQuality, trebleGainDB);
// Apply tone stack
// Set parameters
mToneBass.SetParams(bassParams);
mToneMid.SetParams(midParams);
mToneTreble.SetParams(trebleParams);
sample** bassPointers = mToneBass.Process(gateGainOutput, numChannelsInternal, numFrames);
sample** midPointers = mToneMid.Process(bassPointers, numChannelsInternal, numFrames);
sample** treblePointers = mToneTreble.Process(midPointers, numChannelsInternal, numFrames);
toneStackOutPointers = treblePointers;
}
sample** toneStackOutPointers = (toneStackActive && mToneStack != nullptr) ? mToneStack->Process(gateGainOutput, numChannelsInternal, numFrames)
: gateGainOutput;

sample** irPointers = toneStackOutPointers;
if (mIR != nullptr && GetParam(kIRToggle)->Value())
Expand Down Expand Up @@ -387,6 +358,8 @@ void NeuralAmpModeler::ProcessBlock(iplug::sample** inputs, iplug::sample** outp
void NeuralAmpModeler::OnReset()
{
const auto sampleRate = GetSampleRate();
const int maxBlockSize = GetBlockSize();

// Tail is because the HPF DC blocker has a decay.
// 10 cycles should be enough to pass the VST3 tests checking tail behavior.
// I'm ignoring the model & IR, but it's not the end of the world.
Expand All @@ -397,6 +370,7 @@ void NeuralAmpModeler::OnReset()
mCheckSampleRateWarning = true;
// If there is a model or IR loaded, they need to be checked for resampling.
_ResetModelAndIR(sampleRate, GetBlockSize());
mToneStack->Reset(sampleRate, maxBlockSize);
}

void NeuralAmpModeler::OnIdle()
Expand All @@ -419,6 +393,12 @@ void NeuralAmpModeler::OnIdle()

bool NeuralAmpModeler::SerializeState(IByteChunk& chunk) const
{
// If this isn't here when unserializing, then we know we're dealing with something before v0.8.0.
WDL_String header("###NeuralAmpModeler###"); // Don't change this!
chunk.PutStr(header.Get());
// Plugin version, so we can load legacy serialized states in the future!
WDL_String version(PLUG_VERSION_STR);
chunk.PutStr(version.Get());
// Model directory (don't serialize the model itself; we'll just load it again
// when we unserialize)
chunk.PutStr(mNAMPath.Get());
Expand All @@ -429,7 +409,19 @@ bool NeuralAmpModeler::SerializeState(IByteChunk& chunk) const

int NeuralAmpModeler::UnserializeState(const IByteChunk& chunk, int startPos)
{
WDL_String dir;
WDL_String header;
startPos = chunk.GetStr(header, startPos);
// TODO: Handle legacy plugin serialized states.
//if strncmp (header.Get(), "###NeuralAmpModeler###")
//{
// return UnserializeStateLegacy(header, startPos); // (We'll assume 0.7.9).
//}
WDL_String version;
startPos = chunk.GetStr(version, startPos);
// Version-specific loading here if needed.
// ...

// Current version loading:
startPos = chunk.GetStr(mNAMPath, startPos);
startPos = chunk.GetStr(mIRPath, startPos);
startPos = chunk.GetStr(mHighLightColor, startPos);
Expand Down Expand Up @@ -480,6 +472,23 @@ void NeuralAmpModeler::OnUIOpen()
});
}

void NeuralAmpModeler::OnParamChange(int paramIdx)
{
switch (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;
default: break;
}
}

void NeuralAmpModeler::OnParamChangeUI(int paramIdx, EParamSource source)
{
if (auto pGraphics = GetUI())
Expand Down Expand Up @@ -555,6 +564,7 @@ void NeuralAmpModeler::_ApplyDSPStaging()
mNAMPath.Set("");
mShouldRemoveModel = false;
mCheckSampleRateWarning = true;
SetLatency(0);
}
if (mShouldRemoveIR)
{
Expand All @@ -570,6 +580,7 @@ void NeuralAmpModeler::_ApplyDSPStaging()
mStagedModel = nullptr;
mNewModelLoadedInDSP = true;
mCheckSampleRateWarning = true;
SetLatency(mModel->GetLatency());
}
if (mStagedIR != nullptr)
{
Expand Down Expand Up @@ -753,6 +764,11 @@ size_t NeuralAmpModeler::_GetBufferNumFrames() const
return mInputArray[0].size();
}

void NeuralAmpModeler::_InitToneStack()
{
// If you want to customize the tone stack, then put it here!
mToneStack = std::make_unique<dsp::tone_stack::BasicNamToneStack>();
}
void NeuralAmpModeler::_PrepareBuffers(const size_t numChannels, const size_t numFrames)
{
const bool updateChannels = numChannels != _GetBufferNumChannels();
Expand Down
11 changes: 7 additions & 4 deletions NeuralAmpModeler/NeuralAmpModeler.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
#include "NeuralAmpModelerCore/NAM/dsp.h"
#include "AudioDSPTools/dsp/ImpulseResponse.h"
#include "AudioDSPTools/dsp/NoiseGate.h"
#include "AudioDSPTools/dsp/RecursiveLinearFilter.h"
#include "AudioDSPTools/dsp/dsp.h"
#include "AudioDSPTools/dsp/wav.h"
#include "AudioDSPTools/dsp/ResamplingContainer/ResamplingContainer.h"

#include "ToneStack.h"

#include "IPlug_include_in_plug_hdr.h"
#include "ISender.h"

Expand Down Expand Up @@ -156,6 +157,8 @@ class ResamplingNAM : public nam::DSP
mFinalized = true;
};

int GetLatency() const { return mResampler.GetLatency(); };

void Reset(const double sampleRate, const int maxBlockSize)
{
mExpectedSampleRate = sampleRate;
Expand Down Expand Up @@ -216,6 +219,7 @@ class NeuralAmpModeler final : public iplug::Plugin
void OnUIOpen() override;
bool OnHostRequestingSupportedViewConfiguration(int width, int height) override { return true; }

void OnParamChange(int paramIdx) override;
void OnParamChangeUI(int paramIdx, iplug::EParamSource source) override;
bool OnMessage(int msgTag, int ctrlTag, int dataSize, const void* pData) override;

Expand All @@ -237,6 +241,7 @@ class NeuralAmpModeler final : public iplug::Plugin
// Sizes based on mInputArray
size_t _GetBufferNumChannels() const;
size_t _GetBufferNumFrames() const;
void _InitToneStack();
// Apply the normalization for the model output (if possible)
void _NormalizeModelOutput(iplug::sample** buffer, const size_t numChannels, const size_t numFrames);
// Loads a NAM model and stores it to mStagedNAM
Expand Down Expand Up @@ -299,9 +304,7 @@ class NeuralAmpModeler final : public iplug::Plugin
std::atomic<bool> mCheckSampleRateWarning = true;

// Tone stack modules
recursive_linear_filter::LowShelf mToneBass;
recursive_linear_filter::Peaking mToneMid;
recursive_linear_filter::HighShelf mToneTreble;
std::unique_ptr<dsp::tone_stack::AbstractToneStack> mToneStack;

// Post-IR filters
recursive_linear_filter::HighPass mHighPass;
Expand Down
2 changes: 1 addition & 1 deletion NeuralAmpModeler/NeuralAmpModelerCore
58 changes: 58 additions & 0 deletions NeuralAmpModeler/ToneStack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "ToneStack.h"

DSP_SAMPLE** dsp::tone_stack::BasicNamToneStack::Process(DSP_SAMPLE** inputs, const int numChannels,
const int numFrames)
{
DSP_SAMPLE** bassPointers = mToneBass.Process(inputs, numChannels, numFrames);
DSP_SAMPLE** midPointers = mToneMid.Process(bassPointers, numChannels, numFrames);
DSP_SAMPLE** treblePointers = mToneTreble.Process(midPointers, numChannels, numFrames);
return treblePointers;
}

void dsp::tone_stack::BasicNamToneStack::Reset(const double sampleRate, const int maxBlockSize)
{
dsp::tone_stack::AbstractToneStack::Reset(sampleRate, maxBlockSize);

// Refresh the params!
SetParam("bass", mBassVal);
SetParam("middle", mMiddleVal);
SetParam("treble", mTrebleVal);
}

void dsp::tone_stack::BasicNamToneStack::SetParam(const std::string name, const double val)
{
if (name == "bass")
{
// HACK: Store for refresh
mBassVal = val;
const double sampleRate = GetSampleRate();
const double bassGainDB = 4.0 * (val - 5.0); // +/- 20
const double bassFrequency = 150.0;
const double bassQuality = 0.707;
recursive_linear_filter::BiquadParams bassParams(sampleRate, bassFrequency, bassQuality, bassGainDB);
mToneBass.SetParams(bassParams);
}
else if (name == "middle")
{
// HACK: Store for refresh
mMiddleVal = val;
const double sampleRate = GetSampleRate();
const double midGainDB = 3.0 * (val - 5.0); // +/- 15
const double midFrequency = 425.0;
// Wider EQ on mid bump up to sound less honky.
const double midQuality = midGainDB < 0.0 ? 1.5 : 0.7;
recursive_linear_filter::BiquadParams midParams(sampleRate, midFrequency, midQuality, midGainDB);
mToneMid.SetParams(midParams);
}
else if (name == "treble")
{
// HACK: Store for refresh
mTrebleVal = val;
const double sampleRate = GetSampleRate();
const double trebleGainDB = 2.0 * (val - 5.0); // +/- 10
const double trebleFrequency = 1800.0;
const double trebleQuality = 0.707;
recursive_linear_filter::BiquadParams trebleParams(sampleRate, trebleFrequency, trebleQuality, trebleGainDB);
mToneTreble.SetParams(trebleParams);
}
}
60 changes: 60 additions & 0 deletions NeuralAmpModeler/ToneStack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#pragma once

#include <string>
#include "AudioDSPTools/dsp/dsp.h"
#include "AudioDSPTools/dsp/RecursiveLinearFilter.h"

namespace dsp
{
namespace tone_stack
{
class AbstractToneStack
{
public:
// Compute in the real-time loop
virtual DSP_SAMPLE** Process(DSP_SAMPLE** inputs, const int numChannels, const int numFrames) = 0;
// Any preparation. Call from Reset() in the plugin
virtual void Reset(const double sampleRate, const int maxBlockSize)
{
mSampleRate = sampleRate;
mMaxBlockSize = maxBlockSize;
};
// Set the various parameters of your tone stack by name.
// Call this during OnParamChange()
virtual void SetParam(const std::string name, const double val) = 0;

protected:
double GetSampleRate() const { return mSampleRate; };
double mSampleRate = 0.0;
int mMaxBlockSize = 0;
};

class BasicNamToneStack : public AbstractToneStack
{
public:
BasicNamToneStack()
{
SetParam("bass", 5.0);
SetParam("middle", 5.0);
SetParam("treble", 5.0);
};
~BasicNamToneStack() = default;

DSP_SAMPLE** Process(DSP_SAMPLE** inputs, const int numChannels, const int numFrames);
virtual void Reset(const double sampleRate, const int maxBlockSize) override;
// :param val: Assumed to be between 0 and 10, 5 is "noon"
void SetParam(const std::string name, const double val);


protected:
recursive_linear_filter::LowShelf mToneBass;
recursive_linear_filter::Peaking mToneMid;
recursive_linear_filter::HighShelf mToneTreble;

// HACK not DRY w knob defs
double mBassVal = 5.0;
double mMiddleVal = 5.0;
double mTrebleVal = 5.0;
};
}; // namespace tone_stack
}; // namespace dsp
4 changes: 2 additions & 2 deletions NeuralAmpModeler/config.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#define PLUG_NAME "NeuralAmpModeler"
#define PLUG_MFR "Steven Atkinson"
#define PLUG_VERSION_HEX 0x00000708
#define PLUG_VERSION_STR "0.7.8"
#define PLUG_VERSION_HEX 0x00000709
#define PLUG_VERSION_STR "0.7.9"
#define PLUG_UNIQUE_ID '1YEo'
#define PLUG_MFR_ID 'SDAa'
#define PLUG_URL_STR "https://github.com/sdatkinson/NeuralAmpModelerPlugin"
Expand Down
2 changes: 1 addition & 1 deletion NeuralAmpModeler/installer/NeuralAmpModeler.iss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ AppCopyright=Copyright (C) 2020 MANUFACTURER
AppPublisher=MANUFACTURER
AppPublisherURL=http://www.spam.com
AppSupportURL=http://www.spam.com
AppVersion=0.7.8
AppVersion=0.7.9
VersionInfoVersion=1.0.0
DefaultDirName={pf}\NeuralAmpModeler
DefaultGroupName=NeuralAmpModeler
Expand Down
1 change: 1 addition & 0 deletions NeuralAmpModeler/installer/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ https://github.com/sdatkinson/NeuralAmpModelerPlugin
12/06/2023 - v0.7.6
12/13/2023 - v0.7.7
01/30/2024 - v0.7.8
04/04/2024 - v0.7.9

2 changes: 2 additions & 0 deletions NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@
<ClCompile Include="..\NeuralAmpModelerCore\NAM\lstm.cpp" />
<ClCompile Include="..\NeuralAmpModelerCore\NAM\util.cpp" />
<ClCompile Include="..\NeuralAmpModelerCore\NAM\wavenet.cpp" />
<ClCompile Include="..\ToneStack.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuildStep Include="..\..\AAX_SDK\Libs\Release\AAXLibrary.lib">
Expand Down Expand Up @@ -534,6 +535,7 @@
<ClInclude Include="..\NeuralAmpModelerCore\NAM\version.h" />
<ClInclude Include="..\NeuralAmpModelerCore\NAM\wavenet.h" />
<ClInclude Include="..\resources\resource.h" />
<ClInclude Include="..\ToneStack.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\resources\main.rc" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<ClCompile Include="..\AudioDSPTools\dsp\wav.cpp">
<Filter>dsp</Filter>
</ClCompile>
<ClCompile Include="..\ToneStack.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\resources\resource.h">
Expand Down Expand Up @@ -311,6 +312,7 @@
<ClInclude Include="..\AudioDSPTools\dsp\ResamplingContainer\Dependencies\WDL\wdltypes.h">
<Filter>dsp\ResamplingContainer\Dependencies\WDL</Filter>
</ClInclude>
<ClInclude Include="..\ToneStack.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="resources">
Expand Down
Loading

0 comments on commit 2915141

Please sign in to comment.