diff --git a/NeuralAmpModeler/NeuralAmpModeler.cpp b/NeuralAmpModeler/NeuralAmpModeler.cpp index 7bf03bf8..4cac6063 100644 --- a/NeuralAmpModeler/NeuralAmpModeler.cpp +++ b/NeuralAmpModeler/NeuralAmpModeler.cpp @@ -64,9 +64,15 @@ NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info) mInputPointers(nullptr), mOutputPointers(nullptr), mDSP(nullptr), - mStagedDSP(nullptr) + mStagedDSP(nullptr), + mToneBass(), + mToneMid(), + mToneTreble() { GetParam(kInputLevel)->InitGain("Input", 0.0, -20.0, 20.0, 0.1); + GetParam(kToneBass)->InitDouble("Bass", 5.0, 0.0, 10.0, 0.1); + GetParam(kToneMid)->InitDouble("Middle", 5.0, 0.0, 10.0, 0.1); + GetParam(kToneTreble)->InitDouble("Treble", 5.0, 0.0, 10.0, 0.1); GetParam(kOutputLevel)->InitGain("Output", 0.0, -20.0, 20.0, 0.1); // try { @@ -98,6 +104,9 @@ NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info) const float knobHalfHeight = 70.0f; const auto knobs = content.GetReducedFromLeft(knobPad).GetReducedFromRight(knobPad).GetMidVPadded(knobHalfHeight); IRECT inputKnobArea = knobs.GetGridCell(0, kInputLevel, 1, kNumParams).GetPadded(-10); + IRECT bassKnobArea = knobs.GetGridCell(0, kToneBass, 1, kNumParams).GetPadded(-10); + IRECT middleKnobArea = knobs.GetGridCell(0, kToneMid, 1, kNumParams).GetPadded(-10); + IRECT trebleKnobArea = knobs.GetGridCell(0, kToneTreble, 1, kNumParams).GetPadded(-10); IRECT outputKnobArea =knobs.GetGridCell(0, kOutputLevel, 1, kNumParams).GetPadded(-10); const auto modelArea = content.GetFromBottom(30).GetMidHPadded(150); @@ -158,6 +167,9 @@ NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info) // The knobs pGraphics->AttachControl(new IVKnobControl(inputKnobArea, kInputLevel, "", style)); + pGraphics->AttachControl(new IVKnobControl(bassKnobArea, kToneBass, "", style)); + pGraphics->AttachControl(new IVKnobControl(middleKnobArea, kToneMid, "", style)); + pGraphics->AttachControl(new IVKnobControl(trebleKnobArea, kToneTreble, "", style)); pGraphics->AttachControl(new IVKnobControl(outputKnobArea, kOutputLevel, "", style)); // The meters @@ -216,6 +228,7 @@ NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info) void NeuralAmpModeler::ProcessBlock(iplug::sample** inputs, iplug::sample** outputs, int nFrames) { + const int nChans = this->NOutChansConnected(); this->_PrepareBuffers(nFrames); this->_ProcessInput(inputs, nFrames); if (mStagedDSP != nullptr) @@ -237,7 +250,35 @@ void NeuralAmpModeler::ProcessBlock(iplug::sample** inputs, iplug::sample** outp else { this->_FallbackDSP(nFrames); } - this->_ProcessOutput(outputs, nFrames); + // Tone stack + const double sampleRate = this->GetSampleRate(); + // 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 * (this->GetParam(kToneBass)->Value() - 5.0); // +/- 20 + const double midGainDB = 3.0 * (this->GetParam(kToneMid)->Value() - 5.0); // +/- 15 + const double trebleGainDB = 2.0 * (this->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::LowShelfParams bassParams(sampleRate, bassFrequency, bassQuality, bassGainDB); + recursive_linear_filter::PeakingParams midParams(sampleRate, midFrequency, midQuality, midGainDB); + recursive_linear_filter::HighShelfParams trebleParams(sampleRate, trebleFrequency, trebleQuality, trebleGainDB); + // Apply tone stack + sample** bassPointers = this->mToneBass.Process(this->mOutputPointers, nChans, nFrames, &bassParams); + sample** midPointers = this->mToneMid.Process(bassPointers, nChans, nFrames, &midParams); + sample** treblePointers = this->mToneTreble.Process(midPointers, nChans, nFrames, &trebleParams); + + // Let's get outta here + this->_ProcessOutput(treblePointers, outputs, nFrames); // * Output of input leveling (inputs -> mInputPointers), // * Output of output leveling (mOutputPointers -> outputs) this->_UpdateMeters(this->mInputPointers, outputs, nFrames); @@ -362,14 +403,14 @@ void NeuralAmpModeler::_ProcessInput(iplug::sample **inputs, const int nFrames) this->mInputArray[c][s] = gain * inputs[c][s]; } -void NeuralAmpModeler::_ProcessOutput(iplug::sample **outputs, const int nFrames) +void NeuralAmpModeler::_ProcessOutput(iplug::sample** inputs, iplug::sample **outputs, const int nFrames) { const double gain = pow(10.0, GetParam(kOutputLevel)->Value() / 10.0); const size_t nChans = this->NOutChansConnected(); // Assume _PrepareBuffers() was already called for (int c=0; cmOutputArray[c][s]; + outputs[c][s] = gain * inputs[c][s]; } void NeuralAmpModeler::_SetModelMsg(const WDL_String& modelPath) diff --git a/NeuralAmpModeler/NeuralAmpModeler.h b/NeuralAmpModeler/NeuralAmpModeler.h index 8ac37396..0bd7fcf5 100644 --- a/NeuralAmpModeler/NeuralAmpModeler.h +++ b/NeuralAmpModeler/NeuralAmpModeler.h @@ -3,6 +3,7 @@ #include "choc_DisableAllWarnings.h" #include "dsp.h" #include "choc_ReenableAllWarnings.h" +#include "dsp/RecursiveLinearFilter.h" #include "IPlug_include_in_plug_hdr.h" @@ -13,6 +14,9 @@ const int kNumPresets = 1; enum EParams { kInputLevel = 0, + kToneBass, + kToneMid, + kToneTreble, kOutputLevel, kNumParams }; @@ -65,7 +69,7 @@ class NeuralAmpModeler final : public iplug::Plugin // Copy the input buffer to the object, applying input level. void _ProcessInput(iplug::sample** inputs, const int nFrames); // Copy the output to the output buffer, applying output level. - void _ProcessOutput(iplug::sample** outputs, const int nFrames); + void _ProcessOutput(iplug::sample** inputs, iplug::sample** outputs, const int nFrames); // Update level meters // Called within ProcessBlock(). // Assume _ProcessInput() and _ProcessOutput() were run immediately before. @@ -84,6 +88,12 @@ class NeuralAmpModeler final : public iplug::Plugin // Manages switching what DSP is being used. std::unique_ptr mStagedDSP; + // Tone stack modules + // TODO low shelf, peaking, high shelf + recursive_linear_filter::LowShelf mToneBass; + recursive_linear_filter::Peaking mToneMid; + recursive_linear_filter::HighShelf mToneTreble; + WDL_String mModelPath; std::unordered_map mDSPParams = { diff --git a/NeuralAmpModeler/NeuralAmpModeler.xcworkspace/contents.xcworkspacedata b/NeuralAmpModeler/NeuralAmpModeler.xcworkspace/contents.xcworkspacedata index 6a070a73..dbf3f7ca 100644 --- a/NeuralAmpModeler/NeuralAmpModeler.xcworkspace/contents.xcworkspacedata +++ b/NeuralAmpModeler/NeuralAmpModeler.xcworkspace/contents.xcworkspacedata @@ -1,6 +1,12 @@ + + + + diff --git a/NeuralAmpModeler/config.h b/NeuralAmpModeler/config.h index 6b191b4e..73a56878 100644 --- a/NeuralAmpModeler/config.h +++ b/NeuralAmpModeler/config.h @@ -23,7 +23,7 @@ #define PLUG_DOES_MPE 0 #define PLUG_DOES_STATE_CHUNKS 0 #define PLUG_HAS_UI 1 -#define PLUG_WIDTH 500 +#define PLUG_WIDTH 600 #define PLUG_HEIGHT 300 #define PLUG_FPS 60 #define PLUG_SHARED_RESOURCES 0 diff --git a/NeuralAmpModeler/dsp/RecursiveLinearFilter.cpp b/NeuralAmpModeler/dsp/RecursiveLinearFilter.cpp new file mode 100644 index 00000000..5afdf12e --- /dev/null +++ b/NeuralAmpModeler/dsp/RecursiveLinearFilter.cpp @@ -0,0 +1,189 @@ +// +// RecursiveLinearFilter.cpp +// +// +// Created by Steven Atkinson on 12/28/22. +// +// See: https://webaudio.github.io/Audio-EQ-Cookbook/audio-eq-cookbook.html + +#include // std::fill +#include // pow, sin +#include + +#include "RecursiveLinearFilter.h" + +recursive_linear_filter::Base::Base(const size_t inputDegree, + const size_t outputDegree) : +mOutputPointers(nullptr), +mOutputPointersSize(0), +mInputStart(inputDegree), // 1 is subtracted before first use +mOutputStart(outputDegree) +{ + this->mInputCoefficients.resize(inputDegree); + this->mOutputCoefficients.resize(outputDegree); +} + +iplug::sample** recursive_linear_filter::Base::Process(iplug::sample** inputs, + const int numChannels, + const int numFrames, + const Params *params) +{ + this->_PrepareBuffers(numChannels, numFrames); + params->SetCoefficients(this->mInputCoefficients, this->mOutputCoefficients); + long inputStart=0; + long outputStart=0; + // Degree = longest history + // E.g. if y[n] explicitly depends on x[n-2], then input degree is 3 (n,n-1,n-2). + // NOTE: output degree is never 1 because y[n] is never used to explicitly calculate...itself! + // 0,2,3,... are fine. + const size_t inputDegree = this->_GetInputDegree(); + const size_t outputDegree = this->_GetOutputDegree(); + for (auto c=0; cmInputStart; // Should be plenty fine + outputStart = this->mOutputStart; + for (auto s=0; smInputHistory[c][inputStart] = inputs[c][s]; // Store current input + for (auto i=0; imInputCoefficients[i] * this->mInputHistory[c][(inputStart + i) % inputDegree]; + + // Output terms + outputStart -= 1; + if (outputStart < 0) + outputStart = outputDegree - 1; + for (auto i=1; imOutputCoefficients[i] * this->mOutputHistory[c][(outputStart + i) % outputDegree]; + // Store the output! + if (outputDegree >= 1) + this->mOutputHistory[c][outputStart] = out; + this->mOutputs[c][s] = out; + } + } + this->mInputStart = inputStart; + this->mOutputStart = outputStart; + return this->GetPointers(); +} + +iplug::sample** recursive_linear_filter::Base::GetPointers() +{ + for (auto c=0; c_GetNumChannels(); c++) + this->mOutputPointers[c] = this->mOutputs[c].data(); + return this->mOutputPointers; +} + + +void recursive_linear_filter::Base::_PrepareBuffers(const int numChannels, const int numFrames) +{ + if (this->_GetNumChannels() != numChannels) { + this->mInputHistory.resize(numChannels); + this->mOutputHistory.resize(numChannels); + this->mOutputs.resize(numChannels); + const size_t inputDegree = this->_GetInputDegree(); + const size_t outputDegree = this->_GetOutputDegree(); + for (auto c=0; cmInputHistory[c].resize(inputDegree); + this->mOutputHistory[c].resize(outputDegree); + this->mOutputs[c].resize(numFrames); + std::fill(this->mInputHistory[c].begin(), this->mInputHistory[c].end(), 0.0); + std::fill(this->mOutputHistory[c].begin(), this->mOutputHistory[c].end(), 0.0); + } + this->_ResizePointers((size_t) numChannels); + } +} + +void recursive_linear_filter::Base::_ResizePointers(const size_t numChannels) +{ + if (this->mOutputPointersSize == numChannels) + return; + if (this->mOutputPointers != nullptr) + delete[] this->mOutputPointers; + this->mOutputPointers = new iplug::sample*[numChannels]; + if (this->mOutputPointers == nullptr) + throw std::runtime_error("Failed to allocate pointer to output buffer!\n"); + this->mOutputPointersSize = numChannels; +} + +void recursive_linear_filter::LowShelfParams::SetCoefficients(std::vector &inputCoefficients, + std::vector &outputCoefficients) const +{ + const double a = pow(10.0, this->mGainDB / 40.0); + const double omega_0 = 2.0 * MATH_PI * this->mFrequency / this->mSampleRate; + const double alpha = sin(omega_0) / (2.0 * this->mQuality); + const double cosw = cos(omega_0); + + const double ap = a + 1.0; + const double am = a - 1.0; + const double roota2alpha = 2.0 * sqrt(a) * alpha; + + const double b0 = a * (ap - am * cosw + roota2alpha); + const double b1 = 2.0 * a * (am - ap * cosw); + const double b2 = a * (ap - am * cosw - roota2alpha); + const double a0 = ap + am * cosw + roota2alpha; + const double a1 = -2.0 * (am + ap * cosw); + const double a2 = ap + am * cosw - roota2alpha; + + inputCoefficients[0] = b0 / a0; + inputCoefficients[1] = b1 / a0; + inputCoefficients[2] = b2 / a0; + // outputCoefficients[0] = 0.0; // Always + // Sign flip due so we add during main loop (cf Eq. (4)) + outputCoefficients[1] = -a1 / a0; + outputCoefficients[2] = -a2 / a0; +} + +void recursive_linear_filter::PeakingParams::SetCoefficients(std::vector &inputCoefficients, + std::vector &outputCoefficients) const +{ + const double a = pow(10.0, this->mGainDB / 40.0); + const double omega_0 = 2.0 * MATH_PI * this->mFrequency / this->mSampleRate; + const double alpha = sin(omega_0) / (2.0 * this->mQuality); + const double cosw = cos(omega_0); + + const double b0 = 1.0 + alpha * a; + const double b1 = -2.0 * cosw; + const double b2 = 1.0 - alpha * a; + const double a0 = 1.0 + alpha / a; + const double a1 = -2.0 * cosw; + const double a2 = 1.0 - alpha / a; + + inputCoefficients[0] = b0 / a0; + inputCoefficients[1] = b1 / a0; + inputCoefficients[2] = b2 / a0; + // outputCoefficients[0] = 0.0; // Always + // Sign flip due so we add during main loop (cf Eq. (4)) + outputCoefficients[1] = -a1 / a0; + outputCoefficients[2] = -a2 / a0; +} + +void recursive_linear_filter::HighShelfParams::SetCoefficients(std::vector &inputCoefficients, + std::vector &outputCoefficients) const +{ + const double a = pow(10.0, this->mGainDB / 40.0); + const double omega_0 = 2.0 * MATH_PI * this->mFrequency / this->mSampleRate; + const double alpha = sin(omega_0) / (2.0 * this->mQuality); + const double cosw = cos(omega_0); + const double roota2alpha = 2.0 * sqrt(a) * alpha; + + const double ap = a + 1.0; + const double am = a - 1.0; + + const double b0 = a * (ap + am * cosw + roota2alpha); + const double b1 = -2.0 * a * (am + ap * cosw); + const double b2 = a * (ap + am * cosw - roota2alpha); + const double a0 = ap - am * cosw + roota2alpha; + const double a1 = 2.0 * (am - ap * cosw); + const double a2 = ap - am * cosw - roota2alpha; + + + inputCoefficients[0] = b0 / a0; + inputCoefficients[1] = b1 / a0; + inputCoefficients[2] = b2 / a0; + // outputCoefficients[0] = 0.0; // Always + // Sign flip due so we add during main loop (cf Eq. (4)) + outputCoefficients[1] = -a1 / a0; + outputCoefficients[2] = -a2 / a0; +} diff --git a/NeuralAmpModeler/dsp/RecursiveLinearFilter.h b/NeuralAmpModeler/dsp/RecursiveLinearFilter.h new file mode 100644 index 00000000..324a1313 --- /dev/null +++ b/NeuralAmpModeler/dsp/RecursiveLinearFilter.h @@ -0,0 +1,162 @@ +// +// RecursiveLinearFilter.h +// +// +// Created by Steven Atkinson on 12/28/22. +// +// Recursive linear filters (LPF, HPF, Peaking, Shelving) + +#ifndef RecursiveLinearFilter_h +#define RecursiveLinearFilter_h + +#include +#include "IPlugConstants.h" // sample + +#define MATH_PI 3.14159265358979323846 + +// TODO refactor base DSP into a common abstraction. + +namespace recursive_linear_filter { + class Params{ + public: + // Based on the parameters in this object, set the coefficients in the + // provided arrays for the filter. + virtual void SetCoefficients(std::vector& inputCoefficients, + std::vector& outputCoefficients) const=0; + }; + + class Base { // TODO: inherit from DSP + public: + Base(const size_t inputDegree, const size_t outputDegree); + + // Compute the DSP, saving to mOutputs, owned by this instance. + // Return a pointer-to-pointers of the output array + // TODO return const + iplug::sample** Process(iplug::sample** inputs, + const int numChannels, + const int numFrames, + const Params *params); + + // Return a pointer-to-pointers for the DSP's output buffers (all channels) + // Assumes that ._PrepareBuffers() was called recently enough. + iplug::sample** GetPointers(); + protected: + size_t _GetNumChannels() const {return this->mInputHistory.size();}; + size_t _GetInputDegree() const {return this->mInputCoefficients.size();}; + size_t _GetOutputDegree() const {return this->mOutputCoefficients.size();}; + void _PrepareBuffers(const int numChannels, const int numFrames); + // Resizes the pointer-to-pointers for the vector-of-vectors. + void _ResizePointers(const size_t numChannels); + + // Where the output will get written... + // Indexing is [channel][sample] + std::vector> mOutputs; + // ...And a pointer to it. + // Only the first level is allocated; the second level are duplicate + // pointers to the data that are primarily owned by the vectors. + iplug::sample** mOutputPointers; + size_t mOutputPointersSize; // Keep track of its size. + + // Coefficients for the DSP filter + std::vector mInputCoefficients; + std::vector mOutputCoefficients; + + // Arrays holding the history on which the filter depends recursively. + // First index is channel + // Second index, [0] is the current input/output, [1] is the previous, [2] is before that, etc. + std::vector> mInputHistory; + std::vector> mOutputHistory; + // Indices for history. + // Designates which index is currently "0". Use modulus to wrap around. + long mInputStart; + long mOutputStart; + }; + + class LevelParams : public Params { + public: + LevelParams(const double gain) : Params(), mGain(gain) {}; + void SetCoefficients(std::vector& inputCoefficients, + std::vector& outputCoefficients) const { + inputCoefficients[0] = this->mGain; + }; + private: + // The gain (multiplicative, i.e. not dB) + double mGain; + }; + + class Level : public Base { + public: + Level() : Base(1, 0) {}; + }; + + class LowShelfParams : public Params { + public: + LowShelfParams(const double sampleRate, const double frequency, const double quality, const double gainDB) : + Params(), + mSampleRate(sampleRate), + mFrequency(frequency), + mQuality(quality), + mGainDB(gainDB) {}; + + void SetCoefficients(std::vector& inputCoefficients, + std::vector& outputCoefficients) const; + private: + double mSampleRate; + double mFrequency; + double mQuality; + double mGainDB; + }; + + class LowShelf : public Base { + public: + LowShelf() : Base(3,3) {}; + }; + + class PeakingParams : public Params { + public: + PeakingParams(const double sampleRate, const double frequency, const double quality, const double gainDB) : + Params(), + mSampleRate(sampleRate), + mFrequency(frequency), + mQuality(quality), + mGainDB(gainDB) {}; + + void SetCoefficients(std::vector& inputCoefficients, + std::vector& outputCoefficients) const; + private: + double mSampleRate; + double mFrequency; + double mQuality; + double mGainDB; + }; + + class Peaking : public Base { + public: + Peaking() : Base(3,3) {}; + }; + + class HighShelfParams : public Params { + public: + HighShelfParams(const double sampleRate, const double frequency, const double quality, const double gainDB) : + Params(), + mSampleRate(sampleRate), + mFrequency(frequency), + mQuality(quality), + mGainDB(gainDB) {}; + + void SetCoefficients(std::vector& inputCoefficients, + std::vector& outputCoefficients) const; + private: + double mSampleRate; + double mFrequency; + double mQuality; + double mGainDB; + }; + + class HighShelf : public Base { + public: + HighShelf() : Base(3,3) {}; + }; +}; + +#endif /* RecursiveLinearFilter_h */ diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj b/NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj index b56f028e..045f0cef 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj @@ -414,6 +414,7 @@ + @@ -504,6 +505,7 @@ + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj.filters b/NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj.filters index c2f44e7f..49d4b893 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj.filters +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-aax.vcxproj.filters @@ -80,6 +80,9 @@ dsp + + dsp + @@ -256,6 +259,9 @@ dsp + + dsp + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj b/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj index d345d1cf..615c0abc 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj @@ -324,6 +324,7 @@ + @@ -374,6 +375,7 @@ + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj.filters b/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj.filters index 435eda57..0cda6585 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj.filters +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-app.vcxproj.filters @@ -98,6 +98,9 @@ dsp + + dsp + @@ -304,6 +307,9 @@ dsp + + dsp + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-iOS.xcodeproj/project.pbxproj b/NeuralAmpModeler/projects/NeuralAmpModeler-iOS.xcodeproj/project.pbxproj index 9080da7b..9db95ff8 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-iOS.xcodeproj/project.pbxproj +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-iOS.xcodeproj/project.pbxproj @@ -72,6 +72,7 @@ 4FDF6D7B2267CE540007B686 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FDF6D752267CE540007B686 /* AppDelegate.m */; }; 4FDF6D7F2267CEBA0007B686 /* IPlugAUPlayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FDF6D7D2267CEBA0007B686 /* IPlugAUPlayer.mm */; }; 91236D811B08F59300734C5E /* NeuralAmpModelerAppExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 91236D771B08F59300734C5E /* NeuralAmpModelerAppExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + AAD9F849295EC49D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F848295EC49D009DBBA2 /* RecursiveLinearFilter.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -314,6 +315,8 @@ 4FFF108820A1036200D3092F /* NeuralAmpModeler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NeuralAmpModeler.h; path = ../NeuralAmpModeler.h; sourceTree = ""; }; 91236D0D1B08F42B00734C5E /* NeuralAmpModeler.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NeuralAmpModeler.app; sourceTree = BUILT_PRODUCTS_DIR; }; 91236D771B08F59300734C5E /* NeuralAmpModelerAppExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NeuralAmpModelerAppExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + AAD9F848295EC49D009DBBA2 /* RecursiveLinearFilter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = RecursiveLinearFilter.cpp; path = /Users/steve/src/NeuralAmpModelerPlugin/NeuralAmpModeler/dsp/RecursiveLinearFilter.cpp; sourceTree = ""; }; + AAD9F84A295EC4A0009DBBA2 /* RecursiveLinearFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RecursiveLinearFilter.h; path = /Users/steve/src/NeuralAmpModelerPlugin/NeuralAmpModeler/dsp/RecursiveLinearFilter.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -356,6 +359,8 @@ 4F3EF90528DE0BA7002972F2 /* dsp */ = { isa = PBXGroup; children = ( + AAD9F84A295EC4A0009DBBA2 /* RecursiveLinearFilter.h */, + AAD9F848295EC49D009DBBA2 /* RecursiveLinearFilter.cpp */, 4F3EF90728DE0BA7002972F2 /* util.cpp */, 4F3EF90828DE0BA7002972F2 /* dsp.cpp */, 4F3EF90928DE0BA7002972F2 /* lstm.h */, @@ -957,6 +962,7 @@ 4FA61F7F22E89AFF00A92C58 /* IPlugAPIBase.cpp in Sources */, 4FA61F9222E8A2B500A92C58 /* NeuralAmpModeler.cpp in Sources */, 4F7C499B255DE03500DF7588 /* IPopupMenuControl.cpp in Sources */, + AAD9F849295EC49D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-macOS.xcodeproj/project.pbxproj b/NeuralAmpModeler/projects/NeuralAmpModeler-macOS.xcodeproj/project.pbxproj index 632df677..fe63d84b 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-macOS.xcodeproj/project.pbxproj +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-macOS.xcodeproj/project.pbxproj @@ -391,6 +391,18 @@ 4FFBB93520863B0E00DDD0E7 /* vstnoteexpressiontypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F81588E205D50EB00393585 /* vstnoteexpressiontypes.cpp */; }; AA355E2D295B688F0061AA3D /* Colors.h in Headers */ = {isa = PBXBuildFile; fileRef = AA355E2C295B688F0061AA3D /* Colors.h */; }; AA355E2E295B688F0061AA3D /* Colors.h in Headers */ = {isa = PBXBuildFile; fileRef = AA355E2C295B688F0061AA3D /* Colors.h */; }; + AAD9F83B295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F83C295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F83D295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F83E295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F83F295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F840295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F841295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F842295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F843295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F844295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */; }; + AAD9F846295E6CB7009DBBA2 /* RecursiveLinearFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = AAD9F845295E6CB7009DBBA2 /* RecursiveLinearFilter.h */; }; + AAD9F847295E6CB7009DBBA2 /* RecursiveLinearFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = AAD9F845295E6CB7009DBBA2 /* RecursiveLinearFilter.h */; }; B885CBC52304AE7300D73128 /* IPlugProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F8F61A8202807B9003F2573 /* IPlugProcessor.cpp */; }; B8E22A0C220268C4007CBF4C /* IPlugVST3_ProcessorBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B8E22A0A220268C4007CBF4C /* IPlugVST3_ProcessorBase.cpp */; }; B8E22A0D220268C4007CBF4C /* IPlugVST3_ProcessorBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B8E22A0A220268C4007CBF4C /* IPlugVST3_ProcessorBase.cpp */; }; @@ -942,6 +954,8 @@ AAD2484E29542F2800F55DD4 /* APPRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = APPRelease.entitlements; sourceTree = ""; }; AAD2484F2954325200F55DD4 /* AUv3Release.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AUv3Release.entitlements; sourceTree = ""; }; AAD248502954339400F55DD4 /* AUv3AppRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AUv3AppRelease.entitlements; sourceTree = ""; }; + AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecursiveLinearFilter.cpp; sourceTree = ""; }; + AAD9F845295E6CB7009DBBA2 /* RecursiveLinearFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecursiveLinearFilter.h; sourceTree = ""; }; B8E22A0A220268C4007CBF4C /* IPlugVST3_ProcessorBase.cpp */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugVST3_ProcessorBase.cpp; path = ../../iPlug2/IPlug/VST3/IPlugVST3_ProcessorBase.cpp; sourceTree = ""; tabWidth = 2; }; B8E22A0B220268C4007CBF4C /* IPlugVST3_ProcessorBase.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = IPlugVST3_ProcessorBase.h; path = ../../iPlug2/IPlug/VST3/IPlugVST3_ProcessorBase.h; sourceTree = ""; tabWidth = 2; }; B8EA6B932203868500D23A86 /* IPlugVST3_Common.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = IPlugVST3_Common.h; path = ../../iPlug2/IPlug/VST3/IPlugVST3_Common.h; sourceTree = ""; tabWidth = 2; }; @@ -1225,6 +1239,8 @@ 4F3EF8AA28DE03ED002972F2 /* dsp */ = { isa = PBXGroup; children = ( + AAD9F845295E6CB7009DBBA2 /* RecursiveLinearFilter.h */, + AAD9F83A295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp */, 4F3EF8AC28DE03ED002972F2 /* util.cpp */, 4F3EF8B328DE03ED002972F2 /* dsp.h */, 4F3EF8AD28DE03ED002972F2 /* dsp.cpp */, @@ -1877,6 +1893,7 @@ 4F3EF8EC28DE03ED002972F2 /* activations.h in Headers */, 4F3EF8D728DE03ED002972F2 /* wavenet.h in Headers */, AA355E2E295B688F0061AA3D /* Colors.h in Headers */, + AAD9F847295E6CB7009DBBA2 /* RecursiveLinearFilter.h in Headers */, 4F3EF90028DE03ED002972F2 /* cnpy.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1895,6 +1912,7 @@ 4F03A5B620A4621100EBDFFB /* IGraphics_select.h in Headers */, 4F03A5AB20A4621100EBDFFB /* IGraphics_include_in_plug_hdr.h in Headers */, 4FC3EFF22086CE5700BD11FA /* hostclasses.h in Headers */, + AAD9F846295E6CB7009DBBA2 /* RecursiveLinearFilter.h in Headers */, 4F03A5D420A4621100EBDFFB /* IGraphicsUtilities.h in Headers */, 4F03A5AA20A4621100EBDFFB /* IGraphicsLiveEdit.h in Headers */, 4F6369EA20A466470022C370 /* IControl.h in Headers */, @@ -2460,6 +2478,7 @@ 4FDAC0EB207D76C600299363 /* IPlugTimer.cpp in Sources */, 4F03A5AD20A4621100EBDFFB /* IGraphics.cpp in Sources */, 4F3EF8CF28DE03ED002972F2 /* cnpy.cpp in Sources */, + AAD9F83C295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4F3EF8D928DE03ED002972F2 /* lstm.cpp in Sources */, 4F3EF8E428DE03ED002972F2 /* numpy_util.cpp in Sources */, 4F5F344220C0226200487201 /* IPlugPaths.mm in Sources */, @@ -2489,6 +2508,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AAD9F841295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4F3EF8CA28DE03ED002972F2 /* dsp.cpp in Sources */, 4F4856892773CA76005BCF8E /* NeuralAmpModelerAUv3Appex.m in Sources */, 4F3EF8FD28DE03ED002972F2 /* get_dsp.cpp in Sources */, @@ -2531,6 +2551,7 @@ 4F78D95C13B63BA50032E0F3 /* IPlugParameter.cpp in Sources */, 4FB1F58C20E4B006004157C8 /* IGraphicsMac.mm in Sources */, 4F3862F22014BBEC0009F402 /* NeuralAmpModeler.cpp in Sources */, + AAD9F83E295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2565,6 +2586,7 @@ 4F3EE1D6231438D000004786 /* IPlugAPP.cpp in Sources */, 4F3EE1D7231438D000004786 /* IGraphics.cpp in Sources */, 4F3EE1D8231438D000004786 /* IPlugAPP_dialog.cpp in Sources */, + AAD9F844295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4F3EF8C328DE03ED002972F2 /* util.cpp in Sources */, 4F3EE1D9231438D000004786 /* RtAudio.cpp in Sources */, 4F3EE1DA231438D000004786 /* IGraphicsCoreText.mm in Sources */, @@ -2595,6 +2617,7 @@ 4F78BE1622E7406D00AD537E /* IGraphicsMac_view.mm in Sources */, 4F78BE1722E7406D00AD537E /* IGraphicsMac.mm in Sources */, 4F78BE1822E7406D00AD537E /* IGraphicsCoreText.mm in Sources */, + AAD9F843295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4F78BE1E22E7406D00AD537E /* IGraphicsNanoVG_src.m in Sources */, 4F78BE1F22E7406D00AD537E /* IGraphics.cpp in Sources */, 4F78BE2022E7406D00AD537E /* IGraphicsEditorDelegate.cpp in Sources */, @@ -2630,6 +2653,7 @@ 4F6FD2B322675B6300FC59E6 /* IGraphicsCoreText.mm in Sources */, 4F815973205D50EB00393585 /* vstinitiids.cpp in Sources */, 4F7C495B255DDFC400DF7588 /* IControls.cpp in Sources */, + AAD9F83D295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4F81597E205D50EB00393585 /* fdebug.cpp in Sources */, 4F9828B8140A9EB700F3FCC1 /* IPlugAPIBase.cpp in Sources */, 4F81597F205D50EB00393585 /* fdynlib.cpp in Sources */, @@ -2693,6 +2717,7 @@ 4F6369E120A464BB0022C370 /* IGraphicsNanoVG_src.m in Sources */, 4FB6001A1567CB0A0020189A /* IPlugAPIBase.cpp in Sources */, 4F6369EF20A466470022C370 /* IControl.cpp in Sources */, + AAD9F83F295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4F03A5B020A4621100EBDFFB /* IGraphics.cpp in Sources */, 4F35DEB1207E5C5A00867D8F /* IPlugPluginBase.cpp in Sources */, 4F5F344520C0226200487201 /* IPlugPaths.mm in Sources */, @@ -2722,6 +2747,7 @@ 4F7C4964255DDFC800DF7588 /* IControls.cpp in Sources */, 4F03A5B220A4621100EBDFFB /* IGraphics.cpp in Sources */, 4F7C4966255DDFC800DF7588 /* ITextEntryControl.cpp in Sources */, + AAD9F842295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4FB1F58F20E4B009004157C8 /* IGraphicsMac.mm in Sources */, 4F6369F120A466470022C370 /* IControl.cpp in Sources */, 4F6FD2B722675B6300FC59E6 /* IGraphicsCoreText.mm in Sources */, @@ -2768,6 +2794,7 @@ 4F1A5282205D913300CF2908 /* IPlugAPP.cpp in Sources */, 4F03A5AC20A4621100EBDFFB /* IGraphics.cpp in Sources */, 4F2EA978203A50EA008E4850 /* IPlugAPP_dialog.cpp in Sources */, + AAD9F83B295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4F3EF8BB28DE03ED002972F2 /* util.cpp in Sources */, 4FAFFE5821495A4800A6E72D /* RtAudio.cpp in Sources */, 4F6FD2B122675B6300FC59E6 /* IGraphicsCoreText.mm in Sources */, @@ -2818,6 +2845,7 @@ 4F3EF8E828DE03ED002972F2 /* numpy_util.cpp in Sources */, 4F3EF8D328DE03ED002972F2 /* cnpy.cpp in Sources */, 4FFBB92220863B0E00DDD0E7 /* IPlugVST3_Processor.cpp in Sources */, + AAD9F840295E6C8D009DBBA2 /* RecursiveLinearFilter.cpp in Sources */, 4F993F7623055C98000313AF /* IPlugProcessor.cpp in Sources */, 4FFBB92320863B0E00DDD0E7 /* conststringtable.cpp in Sources */, 4F3EF8DD28DE03ED002972F2 /* lstm.cpp in Sources */, diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-vst2.vcxproj b/NeuralAmpModeler/projects/NeuralAmpModeler-vst2.vcxproj index 66cf6878..4426d5e4 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-vst2.vcxproj +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-vst2.vcxproj @@ -301,6 +301,7 @@ + @@ -342,6 +343,7 @@ + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-vst2.vcxproj.filters b/NeuralAmpModeler/projects/NeuralAmpModeler-vst2.vcxproj.filters index 0b3ca03d..e965e4f7 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-vst2.vcxproj.filters +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-vst2.vcxproj.filters @@ -69,6 +69,9 @@ dsp + + dsp + @@ -239,6 +242,9 @@ dsp + + dsp + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-vst3.vcxproj b/NeuralAmpModeler/projects/NeuralAmpModeler-vst3.vcxproj index 27634429..8f7a0aa4 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-vst3.vcxproj +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-vst3.vcxproj @@ -333,6 +333,7 @@ + @@ -402,6 +403,7 @@ + diff --git a/NeuralAmpModeler/projects/NeuralAmpModeler-vst3.vcxproj.filters b/NeuralAmpModeler/projects/NeuralAmpModeler-vst3.vcxproj.filters index df231316..d6967fc3 100644 --- a/NeuralAmpModeler/projects/NeuralAmpModeler-vst3.vcxproj.filters +++ b/NeuralAmpModeler/projects/NeuralAmpModeler-vst3.vcxproj.filters @@ -155,6 +155,9 @@ dsp + + dsp + @@ -403,6 +406,9 @@ dsp + + dsp +