From f5ec036cc9132704b803e71a8fa7b01beeb7a1f6 Mon Sep 17 00:00:00 2001 From: jatin Date: Tue, 4 Jul 2023 18:58:58 -0700 Subject: [PATCH] Working Fuzz Machine NDK model --- src/CMakeLists.txt | 2 +- .../drive/fuzz_machine/FuzzFaceNDK.cpp | 211 ++++++++++++++++++ .../drive/fuzz_machine/FuzzFaceNDK.h | 72 ++++++ .../drive/fuzz_machine/FuzzFaceSolver.cpp | 71 ------ .../drive/fuzz_machine/FuzzFaceSolver.h | 29 --- .../drive/fuzz_machine/FuzzMachine.cpp | 53 ++++- .../drive/fuzz_machine/FuzzMachine.h | 9 +- .../fuzz_machine/fuzz_face_ndk_config.json | 50 +++++ 8 files changed, 384 insertions(+), 113 deletions(-) create mode 100644 src/processors/drive/fuzz_machine/FuzzFaceNDK.cpp create mode 100644 src/processors/drive/fuzz_machine/FuzzFaceNDK.h delete mode 100644 src/processors/drive/fuzz_machine/FuzzFaceSolver.cpp delete mode 100644 src/processors/drive/fuzz_machine/FuzzFaceSolver.h create mode 100644 src/processors/drive/fuzz_machine/fuzz_face_ndk_config.json diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0aa3ba3a..94e05a2f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,7 +75,7 @@ target_sources(BYOD PRIVATE processors/drive/diode_circuits/DiodeRectifier.cpp processors/drive/flapjack/Flapjack.cpp processors/drive/fuzz_machine/FuzzMachine.cpp - processors/drive/fuzz_machine/FuzzFaceSolver.cpp + processors/drive/fuzz_machine/FuzzFaceNDK.cpp processors/drive/hysteresis/Hysteresis.cpp processors/drive/hysteresis/HysteresisProcessing.cpp processors/drive/junior_b/JuniorB.cpp diff --git a/src/processors/drive/fuzz_machine/FuzzFaceNDK.cpp b/src/processors/drive/fuzz_machine/FuzzFaceNDK.cpp new file mode 100644 index 00000000..52405bad --- /dev/null +++ b/src/processors/drive/fuzz_machine/FuzzFaceNDK.cpp @@ -0,0 +1,211 @@ +/* + * This file was generated on 2023-07-04 18:56:50.025991 + * using the command: `/Users/jatin/ChowDSP/Research/NDK-Framework/generate_ndk_cpp.py fuzz_face_ndk_config.json` + */ +#include "FuzzFaceNDK.h" + +namespace +{ +// START USER ENTRIES +constexpr auto C1 = 2.2e-6; +constexpr auto C2 = 20.0e-6; +constexpr auto C3 = 0.01e-6; +constexpr auto R1 = 33.0e3; +constexpr auto R2 = 470.0; +constexpr auto R3 = 8.2e3; +constexpr auto R4 = 100.0e3; +constexpr auto RL = 500.0e3; +constexpr auto Vcc = 9.0; +constexpr auto Vt = 26.0e-3; +constexpr auto Is_Q1 = 20.3e-15; +constexpr auto BetaF_Q1 = 1430.0; +constexpr auto AlphaF_Q1 = (1.0 + BetaF_Q1) / BetaF_Q1; +constexpr auto BetaR_Q1 = 4.0; +constexpr auto Is_Q2 = 20.3e-15; +constexpr auto BetaF_Q2 = 1430.0; +constexpr auto AlphaF_Q2 = (1.0 + BetaF_Q2) / BetaF_Q2; +constexpr auto BetaR_Q2 = 4.0; +// END USER ENTRIES +} // namespace + +void FuzzFaceNDK::reset_state() +{ + // reset state vectors + for (size_t ch = 0; ch < MAX_NUM_CHANNELS; ++ch) + { + x_n[ch].setZero(); + v_n[ch] = Eigen::Vector { 1.43236, 1.77569, -0.636511, 0.021566 }; + } +} + +void FuzzFaceNDK::reset (T fs) +{ + const auto Gr = Eigen::DiagonalMatrix { (T) 1 / R1, (T) 1 / R2, (T) 1 / R3, (T) 1 / R4, (T) 1 / RL }; + const auto Gx = Eigen::DiagonalMatrix { (T) 2 * fs * C1, (T) 2 * fs * C2, (T) 2 * fs * C3 }; + const auto Z = Eigen::DiagonalMatrix { 1, 1, 1 }; + + // Set up component-defined matrices + const Eigen::Matrix Nr { + { +0, +0, +1, +0, +0, +0, +0, -1, +0 }, + { +0, +0, +0, +0, +0, +1, +0, -1, +0 }, + { +0, +0, +0, +0, +0, -1, +0, +0, +1 }, + { +0, +1, +0, -1, +0, +0, +0, +0, +0 }, + { +0, +0, +0, +0, +0, +0, +1, +0, +0 }, + }; + + const Eigen::Matrix Nv { + { +0, +0, +0, +1, -1, +0, +0, +0, +0 }, + { +0, +0, +0, +0, +1, +0, +0, +0, +0 }, + }; + + const Eigen::Matrix Nx { + { +1, -1, +0, +0, +0, +0, +0, +0, +0 }, + { +0, +0, +0, +0, +1, +0, +0, +0, +0 }, + { +0, +0, +0, +0, +0, +1, -1, +0, +0 }, + }; + + const Eigen::Matrix Nu { + { +1, +0, +0, +0, +0, +0, +0, +0, +0 }, + { +0, +0, +0, +0, +0, +0, +0, +1, +0 }, + }; + + const Eigen::Matrix Nn { + { +0, -1, +1, +0, +0, +0, +0, +0, +0 }, + { +0, +0, +1, +0, +0, +0, +0, +0, +0 }, + { +0, +0, -1, +0, +0, +0, +0, +0, +1 }, + { +0, +0, +0, -1, +0, +0, +0, +0, +1 }, + }; + + const Eigen::Matrix No { + { +0, +0, +0, +0, +0, +0, +1, +0, +0 }, + }; + + static constexpr auto S_dim = num_nodes + num_voltages; + Eigen::Matrix Nx_0 = Eigen::Matrix::Zero(); + Nx_0.block (0, 0) = Nx; + Eigen::Matrix Nn_0 = Eigen::Matrix::Zero(); + Nn_0.block (0, 0) = Nn; + Eigen::Matrix No_0 = Eigen::Matrix::Zero(); + No_0.block (0, 0) = No; + Eigen::Matrix Nv_0 = Eigen::Matrix::Zero(); + Nv_0.block (0, 0) = Nv; + Eigen::Matrix Zero_I = Eigen::Matrix::Zero(); + Zero_I.block<2, 2> (0, 9).setIdentity(); + + Eigen::Matrix S0_mat = Eigen::Matrix::Zero(); + S0_mat.block (0, 0) = Nr.transpose() * Gr * Nr + Nx.transpose() * Gx * Nx; + S0_mat.block (0, num_nodes) = Nu.transpose(); + S0_mat.block (num_nodes, 0) = Nu; + Eigen::Matrix S0_inv = S0_mat.inverse(); + + // Pre-compute NDK and intermediate matrices + Q = Nv_0 * (S0_inv * Nv_0.transpose()); + Ux = Nx_0 * (S0_inv * Nv_0.transpose()); + Uo = No_0 * (S0_inv * Nv_0.transpose()); + Un = Nn_0 * (S0_inv * Nv_0.transpose()); + Uu = Zero_I * (S0_inv * Nv_0.transpose()); + A0_mat = (T) 2 * (Z * (Gx * (Nx_0 * (S0_inv * Nx_0.transpose())))) - Z.toDenseMatrix(); + B0_mat = (T) 2 * (Z * (Gx * (Nx_0 * (S0_inv * Zero_I.transpose())))); + C0_mat = (T) 2 * (Z * (Gx * (Nx_0 * (S0_inv * Nn_0.transpose())))); + D0_mat = No_0 * (S0_inv * Nx_0.transpose()); + E0_mat = No_0 * (S0_inv * Zero_I.transpose()); + F0_mat = No_0 * (S0_inv * Nn_0.transpose()); + G0_mat = Nn_0 * (S0_inv * Nx_0.transpose()); + H0_mat = Nn_0 * (S0_inv * Zero_I.transpose()); + K0_mat = Nn_0 * (S0_inv * Nn_0.transpose()); + two_Z_Gx = (T) 2 * (Z.toDenseMatrix() * Gx.toDenseMatrix()); + + reset_state(); +} + +void FuzzFaceNDK::update_pots (const std::array& pot_values) +{ + Eigen::Matrix Rv = Eigen::Matrix::Zero(); + Rv (0, 0) = pot_values[0]; // Rfp + Rv (1, 1) = pot_values[1]; // Rfm + Eigen::Matrix Rv_Q_inv = (Rv + Q).inverse(); + + A_mat = A0_mat - (two_Z_Gx * (Ux * (Rv_Q_inv * Ux.transpose()))); + Eigen::Matrix B_mat = B0_mat - (two_Z_Gx * (Ux * (Rv_Q_inv * Uu.transpose()))); + B_mat_var = B_mat.leftCols(); + B_u_fix = B_mat.rightCols() * Eigen::Vector { Vcc }; + C_mat = C0_mat - (two_Z_Gx * (Ux * (Rv_Q_inv * Un.transpose()))); + D_mat = D0_mat - (Uo * (Rv_Q_inv * Ux.transpose())); + Eigen::Matrix E_mat = E0_mat - (Uo * (Rv_Q_inv * Uu.transpose())); + E_mat_var = E_mat.leftCols(); + E_u_fix = E_mat.rightCols() * Eigen::Vector { Vcc }; + F_mat = F0_mat - (Uo * (Rv_Q_inv * Un.transpose())); + G_mat = G0_mat - (Un * (Rv_Q_inv * Ux.transpose())); + Eigen::Matrix H_mat = H0_mat - (Un * (Rv_Q_inv * Uu.transpose())); + H_mat_var = H_mat.leftCols(); + H_u_fix = H_mat.rightCols() * Eigen::Vector { Vcc }; + K_mat = K0_mat - (Un * (Rv_Q_inv * Un.transpose())); +} + +void FuzzFaceNDK::process (std::span channel_data, size_t ch) noexcept +{ + Eigen::Vector u_n_var; + Eigen::Vector p_n; + Eigen::Matrix Jac = Eigen::Matrix::Zero(); + Eigen::Vector i_n; + Eigen::Vector F_min; + Eigen::Matrix A_solve; + const Eigen::Matrix eye = Eigen::Matrix::Identity(); + Eigen::Vector delta_v; + Eigen::Vector y_n; + + for (auto& sample : channel_data) + { + u_n_var (0) = (T) sample; + p_n.noalias() = G_mat * x_n[ch] + H_mat_var * u_n_var + H_u_fix; + + T exp_v1_v0; + T exp_mv0; + T exp_v3_v2; + T exp_mv2; + const auto calc_currents = [&] + { + exp_v1_v0 = std::exp ((v_n[ch](1) - v_n[ch](0)) / Vt); + exp_mv0 = std::exp (-v_n[ch](0) / Vt); + i_n (0) = Is_Q1 * ((exp_v1_v0 - (T) 1) / BetaF_Q1 + (exp_mv0 - (T) 1) / BetaR_Q1); + i_n (1) = -Is_Q1 * (-(exp_mv0 - (T) 1) + AlphaF_Q1 * (exp_v1_v0 - (T) 1)); + + exp_v3_v2 = std::exp ((v_n[ch](3) - v_n[ch](2)) / Vt); + exp_mv2 = std::exp (-v_n[ch](2) / Vt); + i_n (2) = Is_Q2 * ((exp_v3_v2 - (T) 1) / BetaF_Q2 + (exp_mv2 - (T) 1) / BetaR_Q2); + i_n (3) = -Is_Q2 * (-(exp_mv2 - (T) 1) + AlphaF_Q2 * (exp_v3_v2 - (T) 1)); + }; + + const auto calc_jacobian = [&] + { + Jac (0, 0) = (Is_Q1 / Vt) * (-exp_v1_v0 / BetaF_Q1 - exp_mv0 / BetaR_Q1); + Jac (0, 1) = (Is_Q1 / Vt) * (exp_v1_v0 / BetaF_Q1); + Jac (1, 0) = (Is_Q1 / Vt) * (-exp_mv0 + AlphaF_Q1 * exp_v1_v0); + Jac (1, 1) = (Is_Q1 / Vt) * (-AlphaF_Q1 * exp_v1_v0); + + Jac (2, 2) = (Is_Q2 / Vt) * (-exp_v3_v2 / BetaF_Q2 - exp_mv2 / BetaR_Q2); + Jac (2, 3) = (Is_Q2 / Vt) * (exp_v3_v2 / BetaF_Q2); + Jac (3, 2) = (Is_Q2 / Vt) * (-exp_mv2 + AlphaF_Q2 * exp_v3_v2); + Jac (3, 3) = (Is_Q2 / Vt) * (-AlphaF_Q2 * exp_v3_v2); + }; + + T delta; + int nIters = 0; + do + { + calc_currents(); + calc_jacobian(); + + F_min.noalias() = p_n + K_mat * i_n - v_n[ch]; + A_solve.noalias() = K_mat * Jac - eye; + delta_v.noalias() = A_solve.householderQr().solve (F_min); + v_n[ch] -= delta_v; + delta = delta_v.array().abs().sum(); + } while (delta > 1.0e-2 && ++nIters < 8); + calc_currents(); + + y_n.noalias() = D_mat * x_n[ch] + E_mat_var * u_n_var + E_u_fix + F_mat * i_n; + sample = (float) y_n (0); + x_n[ch] = A_mat * x_n[ch] + B_mat_var * u_n_var + B_u_fix + C_mat * i_n; + } +} diff --git a/src/processors/drive/fuzz_machine/FuzzFaceNDK.h b/src/processors/drive/fuzz_machine/FuzzFaceNDK.h new file mode 100644 index 00000000..308a5f6a --- /dev/null +++ b/src/processors/drive/fuzz_machine/FuzzFaceNDK.h @@ -0,0 +1,72 @@ +/* + * This file was generated on 2023-07-04 18:56:50.025866 + * using the command: `/Users/jatin/ChowDSP/Research/NDK-Framework/generate_ndk_cpp.py fuzz_face_ndk_config.json` + */ +#pragma once + +#include +#include +#include + +// START USER INCLUDES +#include +// END USER INCLUDES + +struct FuzzFaceNDK +{ + // START USER ENTRIES + static constexpr size_t MAX_NUM_CHANNELS = 2; + static constexpr double VRfuzz = 1.0e3; + // END USER ENTRIES + + using T = double; + static constexpr int num_nodes = 9; + static constexpr int num_resistors = 5; + static constexpr int num_pots = 2; + static constexpr int num_states = 3; + static constexpr int num_nl_ports = 4; + static constexpr int num_voltages_variable = 1; + static constexpr int num_voltages_constant = 1; + static constexpr int num_voltages = num_voltages_variable + num_voltages_constant; + static constexpr int num_outputs = 1; + + // State Variables + std::array, MAX_NUM_CHANNELS> x_n; + std::array, MAX_NUM_CHANNELS> v_n; + + // NDK Matrices + Eigen::Matrix A_mat; + Eigen::Matrix B_mat_var; + Eigen::Vector B_u_fix; + Eigen::Matrix C_mat; + Eigen::Matrix D_mat; + Eigen::Matrix E_mat_var; + Eigen::Vector E_u_fix; + Eigen::Matrix F_mat; + Eigen::Matrix G_mat; + Eigen::Matrix H_mat_var; + Eigen::Vector H_u_fix; + Eigen::Matrix K_mat; + + // Intermediate matrices for NDK matrix updates; + Eigen::Matrix Q; + Eigen::Matrix Ux; + Eigen::Matrix Uo; + Eigen::Matrix Un; + Eigen::Matrix Uu; + Eigen::Matrix A0_mat; + Eigen::Matrix B0_mat; + Eigen::Matrix C0_mat; + Eigen::Matrix D0_mat; + Eigen::Matrix E0_mat; + Eigen::Matrix F0_mat; + Eigen::Matrix G0_mat; + Eigen::Matrix H0_mat; + Eigen::Matrix K0_mat; + Eigen::Matrix two_Z_Gx; + + void reset_state(); + void reset (T fs); + void update_pots (const std::array& pot_values); + void process (std::span channel_data, size_t channel_index) noexcept; +}; diff --git a/src/processors/drive/fuzz_machine/FuzzFaceSolver.cpp b/src/processors/drive/fuzz_machine/FuzzFaceSolver.cpp deleted file mode 100644 index d448b289..00000000 --- a/src/processors/drive/fuzz_machine/FuzzFaceSolver.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "FuzzFaceSolver.h" - -namespace -{ -constexpr auto vt = 0.026 * 0.5; -constexpr auto Iq = 1.0e-10; -} // namespace - -void FuzzFaceSolver::prepare (double sample_rate) -{ - fs = sample_rate; - gc1 = 2.0 * fs * C1; - gc2 = 2.0 * fs * C2; - - reset(); -} - -void FuzzFaceSolver::reset() -{ - std::fill (ic1eq.begin(), ic1eq.end(), 0.0); - std::fill (ic2eq.begin(), ic2eq.end(), 0.0); - std::fill (vo.begin(), vo.end(), 0.0); - std::fill (io.begin(), io.end(), 0.0); -} - -void FuzzFaceSolver::set_gain (double gain_01) noexcept -{ - const auto gain_factor = chowdsp::Power::ipow<4> (gain_01 * 0.98 + 0.01); - grfp = 1.0 / ((1.0 - gain_factor) * Rf); - grfm = 1.0 / (gain_factor * Rf); -} - -void FuzzFaceSolver::process (std::span data, size_t ch) noexcept -{ - for (auto& sample : data) - { - const auto vi = std::tanh (0.1 * (double) sample); - - // initial guess - auto v1 = -((-gr4 * (grfp * ic2eq[ch] + (gc2 + grfm + grfp) * io[ch]) + (gr4 * (gc2 + grfm) + (gc2 + gr4 + grfm) * grfp) * (ic1eq[ch] + io[ch] - gc1 * vi)) / (gc1 * gr4 * (gc2 + grfm) + gr4 * (gc2 + grfm) * grfp + gc1 * (gc2 + gr4 + grfm) * grfp)); - - // Newton-Raphson Solver - double delta; - int n_iters = 0; - auto v1_exp = std::exp (-v1 / vt); - do - { - io[ch] = Iq * v1_exp; - vo[ch] = (ic1eq[ch] + io[ch] + (gc1 + gr4) * v1 - gc1 * vi) / gr4; - - const auto F = (gc1 * (vi - v1) - ic1eq[ch]) + gr4 * (vo[ch] - v1) - io[ch]; - const auto F_p = -gc1 - gr4 + (Iq / vt) * v1_exp; - delta = F / F_p; - v1 -= delta; - - v1_exp = std::exp (-v1 / vt); - n_iters++; - } while (std::abs (delta) > 1.0e-5 && n_iters < 5); - - // compute output - io[ch] = Iq * v1_exp; - vo[ch] = (ic1eq[ch] + io[ch] + (gc1 + gr4) * v1 - gc1 * vi) / gr4; - - //update state - const auto v2 = -((io[ch] + gr4 * v1 - (gr4 + grfp) * vo[ch]) / grfp); - ic1eq[ch] = 2.0 * gc1 * (vi - v1) - ic1eq[ch]; - ic2eq[ch] = 2.0 * gc2 * (v2) -ic2eq[ch]; - - sample = float (-100.0 * vo[ch]); - } -} diff --git a/src/processors/drive/fuzz_machine/FuzzFaceSolver.h b/src/processors/drive/fuzz_machine/FuzzFaceSolver.h deleted file mode 100644 index 75feedd7..00000000 --- a/src/processors/drive/fuzz_machine/FuzzFaceSolver.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -struct FuzzFaceSolver -{ - double fs = 48000.0; - - double gr4 = 1.0 / 100.0e3; - double Rf = 1.0e3; - double grfp = 1.0 / (0.5 * Rf); - double grfm = 1.0 / (0.5 * Rf); - - double C1 = 2.2e-6; - double C2 = 20.0e-6; - double gc1 = 2.0 * fs * C1; - double gc2 = 2.0 * fs * C2; - - std::array ic1eq {}; - std::array ic2eq {}; - std::array vo {}; - std::array io {}; - - void prepare (double sample_rate); - void reset(); - - void set_gain (double gain_01) noexcept; - void process (std::span data, size_t channel_index) noexcept; -}; diff --git a/src/processors/drive/fuzz_machine/FuzzMachine.cpp b/src/processors/drive/fuzz_machine/FuzzMachine.cpp index 080c7ba6..bd6dfe8f 100644 --- a/src/processors/drive/fuzz_machine/FuzzMachine.cpp +++ b/src/processors/drive/fuzz_machine/FuzzMachine.cpp @@ -1,6 +1,11 @@ #include "FuzzMachine.h" #include "processors/ParameterHelpers.h" +namespace +{ +constexpr int osRatio = 2; +} + FuzzMachine::FuzzMachine (UndoManager* um) : BaseProcessor ("Fuzz Machine", createParameterLayout(), um) { @@ -27,11 +32,17 @@ ParamLayout FuzzMachine::createParameterLayout() void FuzzMachine::prepare (double sampleRate, int samplesPerBlock) { - model.prepare (sampleRate); - + fuzzParam.mappingFunction = [](float x) { return 0.9f * x + 0.05f; }; fuzzParam.setRampLength (0.025); fuzzParam.prepare (sampleRate, samplesPerBlock); + upsampler.prepare ({ sampleRate, (uint32_t) samplesPerBlock, 2 }, osRatio); + downsampler.prepare ({ osRatio * sampleRate, osRatio * (uint32_t) samplesPerBlock, 2 }, osRatio); + + model_ndk.reset (sampleRate * osRatio); + model_ndk.update_pots ({ FuzzFaceNDK::VRfuzz * (1.0 - (double) fuzzParam.getCurrentValue()), + FuzzFaceNDK::VRfuzz * (double) fuzzParam.getCurrentValue() }); + const auto spec = juce::dsp::ProcessSpec { sampleRate, (uint32_t) samplesPerBlock, 2 }; dcBlocker.prepare (spec); dcBlocker.calcCoefs (30.0f, (float) sampleRate); @@ -43,11 +54,13 @@ void FuzzMachine::prepare (double sampleRate, int samplesPerBlock) // pre-buffering AudioBuffer buffer (2, samplesPerBlock); float level = 100.0f; - while (level > 1.0e-4f) + int count = 0; + while (level > 1.0e-4f || count < 100) { buffer.clear(); processAudio (buffer); level = buffer.getMagnitude (0, samplesPerBlock); + count++; } } @@ -56,18 +69,40 @@ void FuzzMachine::processAudio (AudioBuffer& buffer) const auto numSamples = buffer.getNumSamples(); fuzzParam.process (numSamples); - for (auto [ch, n, data] : chowdsp::buffer_iters::sub_blocks<32, true> (buffer)) + for (auto [ch, data] : chowdsp::buffer_iters::channels (buffer)) { - if (ch == 0) - model.set_gain (fuzzParam.getSmoothedBuffer()[n]); - model.process (data, ch); + for (auto& sample : data) + sample = chowdsp::Math::algebraicSigmoid (sample); } + chowdsp::BufferMath::applyGain (buffer, Decibels::decibelsToGain (-72.0f)); + + const auto osBuffer = upsampler.process (buffer); + if (fuzzParam.isSmoothing()) + { + for (auto [ch, n, data] : chowdsp::buffer_iters::sub_blocks<32, true> (osBuffer)) + { + if (ch == 0) + { + const auto fuzzAmt = fuzzParam.getSmoothedBuffer()[n / osRatio]; + model_ndk.update_pots ({ FuzzFaceNDK::VRfuzz * (1.0 - (double) fuzzAmt), + FuzzFaceNDK::VRfuzz * (double) fuzzAmt }); + } + model_ndk.process (data, ch); + } + } + else + { + for (auto [ch, data] : chowdsp::buffer_iters::channels (osBuffer)) + model_ndk.process (data, ch); + } + downsampler.process (osBuffer, buffer); + if (! chowdsp::BufferMath::sanitizeBuffer (buffer)) - model.reset(); + model_ndk.reset_state(); dcBlocker.processBlock (buffer); - volume.setGainLinear (volumeParam->getCurrentValue()); + volume.setGainLinear (volumeParam->getCurrentValue() * 5.0f); volume.process (buffer); } diff --git a/src/processors/drive/fuzz_machine/FuzzMachine.h b/src/processors/drive/fuzz_machine/FuzzMachine.h index 576a1270..0e169354 100644 --- a/src/processors/drive/fuzz_machine/FuzzMachine.h +++ b/src/processors/drive/fuzz_machine/FuzzMachine.h @@ -1,9 +1,8 @@ #pragma once +#include "FuzzFaceNDK.h" #include "processors/BaseProcessor.h" -#include "FuzzFaceSolver.h" - class FuzzMachine : public BaseProcessor { public: @@ -19,7 +18,11 @@ class FuzzMachine : public BaseProcessor chowdsp::SmoothedBufferValue fuzzParam; chowdsp::PercentParameter* volumeParam = nullptr; - FuzzFaceSolver model; + FuzzFaceNDK model_ndk; + + using AAFilter = chowdsp::EllipticFilter<4>; + chowdsp::Upsampler upsampler; + chowdsp::Downsampler downsampler; chowdsp::FirstOrderHPF dcBlocker; chowdsp::Gain volume; diff --git a/src/processors/drive/fuzz_machine/fuzz_face_ndk_config.json b/src/processors/drive/fuzz_machine/fuzz_face_ndk_config.json new file mode 100644 index 00000000..cfb7e1e1 --- /dev/null +++ b/src/processors/drive/fuzz_machine/fuzz_face_ndk_config.json @@ -0,0 +1,50 @@ +{ + "struct_name": "FuzzFaceNDK", + "netlist": [ + "Vi 1 0", + "C1 1 2", + "C2 5 0", + "C3 6 7", + "R1 3 8", + "R2 6 8", + "R3 9 6", + "R4 2 4", + "RL 7 0", + "Rfp 4 5 VARIABLE", + "Rfm 5 0 VARIABLE", + "Q1 2 3 0 # Base Collector Emitter", + "Q2 3 9 4 # Base Collector Emitter", + "Vcc 8 0 FIXED" + ], + "output_nodes": [ 7 ], + "header_includes": [ + "#include " + ], + "cpp_struct_entries": [ + " static constexpr size_t MAX_NUM_CHANNELS = 2;", + " static constexpr double VRfuzz = 1.0e3;" + ], + "cpp_namespace_entries": [ + "constexpr auto C1 = 2.2e-6;", + "constexpr auto C2 = 20.0e-6;", + "constexpr auto C3 = 0.01e-6;", + "constexpr auto R1 = 33.0e3;", + "constexpr auto R2 = 470.0;", + "constexpr auto R3 = 8.2e3;", + "constexpr auto R4 = 100.0e3;", + "constexpr auto RL = 500.0e3;", + "constexpr auto Vcc = 9.0;", + "constexpr auto Vt = 26.0e-3;", + "constexpr auto Is_Q1 = 20.3e-15;", + "constexpr auto BetaF_Q1 = 1430.0;", + "constexpr auto AlphaF_Q1 = (1.0 + BetaF_Q1) / BetaF_Q1;", + "constexpr auto BetaR_Q1 = 4.0;", + "constexpr auto Is_Q2 = 20.3e-15;", + "constexpr auto BetaF_Q2 = 1430.0;", + "constexpr auto AlphaF_Q2 = (1.0 + BetaF_Q2) / BetaF_Q2;", + "constexpr auto BetaR_Q2 = 4.0;" + ], + "initial_state_v_n": "1.43236, 1.77569, -0.636511, 0.021566", + "nr_exit_condition": "delta > 1.0e-2 && ++nIters < 8", + "process_data_type": "float" +}