AnalogTapeModel

Physical modelling signal processing for analog tape recording
Log | Files | Refs | Submodules | README | LICENSE

commit 7cc2afb5bc9e66326dc8d3b59445a1ec7ca8062d
parent 2baae13496804d66997e3de1911ddc9a858a0059
Author: jatinchowdhury18 <jatinchowdhury18@users.noreply.github.com>
Date:   Thu,  7 Feb 2019 17:31:18 -0800

Basic build

Diffstat:
MPlugin/CHOWTapeModel.jucer | 9++++++++-
MPlugin/JuceLibraryCode/AppConfig.h | 2+-
MPlugin/Source/Processors/HysteresisProcessing.cpp | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
MPlugin/Source/Processors/HysteresisProcessing.h | 41+++++++++++++++++++++++++++++++++--------
4 files changed, 115 insertions(+), 18 deletions(-)

diff --git a/Plugin/CHOWTapeModel.jucer b/Plugin/CHOWTapeModel.jucer @@ -1,8 +1,15 @@ <?xml version="1.0" encoding="UTF-8"?> -<JUCERPROJECT id="uS0OjK" name="CHOWTapeModel" projectType="audioplug" jucerVersion="5.4.2"> +<JUCERPROJECT id="uS0OjK" name="CHOWTapeModel" projectType="audioplug" jucerVersion="5.4.2" + pluginFormats="buildAU,buildStandalone,buildVST,buildVST3"> <MAINGROUP id="oKBSK1" name="CHOWTapeModel"> <GROUP id="{7659EE80-6477-48A0-C7B6-CD8900735F10}" name="Source"> + <GROUP id="{D2422983-A0E9-6A14-2092-2381CB1F3E7F}" name="Processors"> + <FILE id="SSdMYR" name="HysteresisProcessing.cpp" compile="1" resource="0" + file="Source/Processors/HysteresisProcessing.cpp"/> + <FILE id="vvuNZS" name="HysteresisProcessing.h" compile="0" resource="0" + file="Source/Processors/HysteresisProcessing.h"/> + </GROUP> <FILE id="y330sp" name="PluginProcessor.cpp" compile="1" resource="0" file="Source/PluginProcessor.cpp"/> <FILE id="FvqAFZ" name="PluginProcessor.h" compile="0" resource="0" diff --git a/Plugin/JuceLibraryCode/AppConfig.h b/Plugin/JuceLibraryCode/AppConfig.h @@ -299,7 +299,7 @@ // Audio plugin settings.. #ifndef JucePlugin_Build_VST - #define JucePlugin_Build_VST 0 + #define JucePlugin_Build_VST 1 #endif #ifndef JucePlugin_Build_VST3 #define JucePlugin_Build_VST3 1 diff --git a/Plugin/Source/Processors/HysteresisProcessing.cpp b/Plugin/Source/Processors/HysteresisProcessing.cpp @@ -1,11 +1,76 @@ -/* - ============================================================================== +#include "HysteresisProcessing.h" +#include <math.h> - HysteresisProcessing.cpp - Created: 7 Feb 2019 4:18:29pm - Author: jatin +HysteresisProcessor::HysteresisProcessor() +{ - ============================================================================== -*/ +} -#include "HysteresisProcessing.h" +float HysteresisProcessor::langevin (float x) +{ + if (std::abs (x) > (float) (10e-4)) + return (1.0f / (float) tanh (x)) - (1.0f / x); + else + return (x / 3.0f); +} + +float HysteresisProcessor::langevinD (float x) +{ + if (std::abs (x) > (float) (10e-4)) + { + float tanhRecip = 1.0f / tanh (x); + return (1.0f / (x * x)) - (tanhRecip * tanhRecip) + 1.0f; + } + else + return (1.0f / 3.0f); +} + +float HysteresisProcessor::deriv (float x_n, float x_n1, float x_d_n1) +{ + return ((2.0f * fs) * (x_n - x_n1)) - x_d_n1; +} + +float HysteresisProcessor::hysteresisFunc (float M, float H, float H_d) +{ + const float Q = (H + alpha * M) / a; + const float M_diff = M_s * langevin (Q) - M; + + const float delta = H_d > 0 ? 1.0f : -1.0f; + const float delta_M = signbit (delta) == signbit (M_diff) ? 1.0f : 0.0f; + + const float L_prime = langevinD (Q); + + const float denominator = 1 - (c * alpha * (M_s / a) * L_prime); + + const float t1_num = (1 - c) * delta_M * M_diff; + const float t1_den = ((1 - c) * delta * k) - (alpha * M_diff); + const float t1 = (t1_num / t1_den) * H_d; + + const float t2 = c * (M_s / a) * H_d * L_prime; + + return (t1 + t2) / denominator; +} + +float HysteresisProcessor::M_n (float prevM, float k1, float k2, float k3, float k4) +{ + return prevM + (k1 / 6.0f) + (k2 / 3.0f) + (k3 / 3.0f) + (k4 / 6.0f); +} + +float HysteresisProcessor::process (float H) +{ + const float H_d = deriv (H, H_n1, H_d_n1); + + const float T = (1.0f / fs); + const float k1 = T * hysteresisFunc (M_n1, H_n1, H_d_n1); + const float k2 = T * hysteresisFunc (M_n1 + (k1 / 2.0f), (H + H_n1) / 2.0f, (H_d + H_d_n1) / 2.0f); + const float k3 = T * hysteresisFunc (M_n1 + (k2 / 2.0f), (H + H_n1) / 2.0f, (H_d + H_d_n1) / 2.0f); + const float k4 = T * hysteresisFunc (M_n1 + k3, H, H_d); + + const float M = M_n (M_n1, k1, k2, k3, k4); + + M_n1 = M; + H_n1 = H; + H_d_n1 = H_d; + + return M; +} diff --git a/Plugin/Source/Processors/HysteresisProcessing.h b/Plugin/Source/Processors/HysteresisProcessing.h @@ -1,11 +1,36 @@ -/* - ============================================================================== +#ifndef HYSTERESISPROCESSOR_H_INCLUDED +#define HYSTERESISPROCESSOR_H_INCLUDED - HysteresisProcessing.h - Created: 7 Feb 2019 4:18:29pm - Author: jatin +#include "JuceHeader.h" - ============================================================================== -*/ +class HysteresisProcessor +{ +public: + HysteresisProcessor(); -#pragma once + float process (float H); + +private: + + float langevin (float x); + float langevinD (float x); + float deriv (float x_n, float x_n1, float x_d_n1); + + float hysteresisFunc (float M, float H, float H_d); + float M_n (float M_n1, float k1, float k2, float k3, float k4); + + float fs = 48000.0f; + const float M_s = 350000.0f; + const float a = (float) 2.2e4; + const float alpha = (float) 1.6e-3; + const float k = (float) 27.0e3; + const float c = (float) 1.7e-1; + + float M_n1 = 0.0; + float H_n1 = 0.0f; + float H_d_n1 = 0.0f; + + //JUCE_DECLARE_NONCOPYABLE_WITH_LEAK_DETECTOR (HysteresisProcessor) +}; + +#endif