diff --git a/src/param.hpp b/src/param.hpp new file mode 100644 index 0000000..6ac5e71 --- /dev/null +++ b/src/param.hpp @@ -0,0 +1,205 @@ +#include +#include +#include + +class Param +{ + std::string m_name; + std::string m_unit; + typedef struct _sparam_info_t + { + double pmin, pmax, pvalue, pinterval, pcenter, scenter, base, kexp; + + } param_info_t; + + param_info_t m_param_info; + + public: + + + Param( + std::string name, + std::string unit, + double pmin, + double pmax, + double pvalue, + double pinterval=1.0, + double pcenter=-1.0, + double scenter=0.0, + double base=1.0, + double kexp=1.0 + ) + : m_name(name) + , m_param_info({pmin, pmax, pvalue, pinterval, pcenter, scenter, base, kexp}) + { + + } + + std::string name() + { + return m_name; + } + + std::string unit() + { + return m_unit; + } + + double getParameter() + { + return m_param_info.pvalue; + } + + void setParameter(double p) + { + m_param_info.pvalue = p; + } + + double getSlider() + { + return toSlider(); + } + + // -------------------------------------------------------------- + // Exported functions + // -------------------------------------------------------------- + double quantizeParam(double p) + { + double k, pq; + if (m_param_info.pinterval == 0) + { + return p; + } + + k = (double)1/(m_param_info.pinterval - 0); + + if (p < 0) + { + pq = ((int)(p*k - 0.5))*m_param_info.pinterval; + } + else + { + pq = ((int)(p*k + 0.5))*m_param_info.pinterval; + } + + return pq; + } + + double clampParam(double p) + { + return (double)std::min(m_param_info.pmax, std::max(m_param_info.pmin, quantizeParam(p))); + } + + double fromSlider(double s) + { + double p, pcenter; + double pmax, pmin, base, kexp, scenter; + + pmax = m_param_info.pmax; + pmin = m_param_info.pmin; + if (pmin == pmax) + { + pmax += 1E-9; + } + base = m_param_info.base; + kexp = m_param_info.kexp; + if (kexp == 0) + { + kexp = 1E-9; + } + scenter = m_param_info.scenter; + pcenter = m_param_info.pcenter; + + if ((pcenter < pmin) || (pcenter > pmax)) + pcenter = pmax*scenter + pmin*(1-scenter); + + s = (double)std::min(1.0, std::max(0.0, s)); + if (s < scenter) + { + if (base == 1) + { + // pcenter-(pcenter-pmin)*(scenter-s)/scenter; + p = pcenter-(pcenter-pmin)*(scenter-s)/scenter; + } + else + { + // pcenter-(pcenter-pmin)*(B^(k*(scenter-s)/scenter)-1)/(B^k-1); + p = pcenter-(pcenter-pmin)*(pow(base,kexp*(scenter-s)/scenter)-1)/(pow(base,kexp)-1); + } + } + else + { + if (base == 1) + { + // pcenter+(pmax-pcenter)*(-scenter+s)/(1-scenter); + p = pcenter+(pmax-pcenter)*(-scenter+s)/(1-scenter); + } + else + { + // pcenter+(pmax-pcenter)*(B^(k*(-scenter+s)/(1-scenter))-1)/(B^k-1); + p = pcenter+(pmax-pcenter)*(pow(base,kexp*(-scenter+s)/(1-scenter))-1)/(pow(base,kexp)-1); + } + } + + m_param_info.pvalue = p; + return quantizeParam(p); + } + + double toSlider() + { + double p = m_param_info.pvalue; + + double s, pcenter; + double pmax, pmin, base, kexp, scenter; + + pmax = m_param_info.pmax; + pmin = m_param_info.pmin; + if (pmin == pmax) + { + pmax += 1E-9; + } + base = m_param_info.base; + kexp = m_param_info.kexp; + if (kexp == 0) + { + kexp = 1E-9; + } + scenter = m_param_info.scenter; + pcenter = m_param_info.pcenter; + + if ((pcenter < pmin) || (pcenter > pmax)) + { + pcenter = pmax*scenter + pmin*(1-scenter); + } + + p = clampParam(p); + if (p < pcenter) + { + if (base == 1) + { + // (-pmin+p)*scenter/(pcenter-pmin); + s = (-pmin+p)*scenter/(pcenter-pmin); + } + else + { + // scenter*(log(B)*k-log(-(-pcenter*B^k+pmin+p*B^k-p)/(pcenter-pmin)))/log(B)/k; + s = scenter*(log(base)*kexp-log(-(-pcenter*pow(base,kexp)+pmin+p*pow(base,kexp)-p)/(pcenter-pmin)))/log(base)/kexp; + } + } + else + { + if (base == 1) + { + // (pcenter-scenter*pmax-p+scenter*p)/(-pmax+pcenter); + s = (pcenter-scenter*pmax-p+scenter*p)/(-pmax+pcenter); + } + else + { + // (k*log(B)*scenter+log(-(-pcenter*B^k+pmax+p*B^k-p)/(-pmax+pcenter))-log(-(-pcenter*B^k+pmax+p*B^k-p)/(-pmax+pcenter))*scenter)/log(B)/k; + s = (kexp*log(base)*scenter+log(-(-pcenter*pow(base,kexp)+pmax+p*pow(base,kexp)-p)/(-pmax+pcenter))-log(-(-pcenter*pow(base,kexp)+pmax+p*pow(base,kexp)-p)/(-pmax+pcenter))*scenter)/log(base)/kexp; + } + } + + return s; + } +}; diff --git a/src/plugin.cpp b/src/plugin.cpp index 4288152..c573943 100755 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -9,33 +9,8 @@ #include #include -#define NUM_PARMS 8 #define MAX_ORDER 4 -const char * const pFTypeString[] = -{ - "Order", - "Size 1", - "Size 2", - "Size 3", - "Size 4", - "Feedback Delay Min", - "Feedback Delay Max", - "Feedback Gain", -}; - -const char * const pFUnitString[] = -{ - "", - "samples", - "samples", - "samples", - "samples", - "samples", - "samples", - "", -}; - enum {ORDER, SIZE_1, SIZE_2, SIZE_3, SIZE_4, FEEDBACK_DELAY_MIN, FEEDBACK_DELAY_XAX, FEEDBACK_GAIN}; AudioEffect* createEffectInstance (audioMasterCallback audioMaster) @@ -59,6 +34,15 @@ Plugin::Plugin(audioMasterCallback audioMaster) m_feedback_delay[0] = 0; m_feedback_delay[1] = 0; + + m_params[0] = new Param("Order", "", 0, 4, 4); + m_params[1] = new Param("Delay 1", "ms", 0, 1000, 50); + m_params[2] = new Param("Delay 2", "ms", 0, 1000, 100); + m_params[3] = new Param("Delay 3", "ms", 0, 1000, 250); + m_params[4] = new Param("Delay 4", "ms", 0, 1000, 500); + m_params[5] = new Param("Feedback Delay Min", "ms", 0, 1000, 100); + m_params[6] = new Param("Feedback Delay Max", "ms", 0, 1000, 200); + m_params[7] = new Param("Feedback Gain", "%", 0, 100, 0); } //----------------------------------------------------------------------------------------- @@ -84,31 +68,39 @@ void Plugin::setParameter(VstInt32 index, float value) { switch(index) { - case ORDER: - break; + case ORDER: + break; - case SIZE_1: - case SIZE_2: - case SIZE_3: - case SIZE_4: - { - uint delay = (uint)(value*DELAY_MAX); - m_reverb_1.setDelay(delay, index - SIZE_1); - m_reverb_2.setDelay(delay, index - SIZE_1); - break; - } + case SIZE_1: + case SIZE_2: + case SIZE_3: + case SIZE_4: + { + double p = m_params[index]->fromSlider(value); + uint delay = (uint)(p*sampleRate/1000); + m_reverb_1.setDelay(delay, index - SIZE_1); + m_reverb_2.setDelay(delay, index - SIZE_1); + break; + } - case FEEDBACK_GAIN: - m_reverb_1.setFeedbackGain(value); - m_reverb_2.setFeedbackGain(value); - break; + case FEEDBACK_GAIN: + { + double p = m_params[index]->fromSlider(value)/100; + m_reverb_1.setFeedbackGain(p); + m_reverb_2.setFeedbackGain(p); + break; + } - case FEEDBACK_DELAY_MIN: - case FEEDBACK_DELAY_XAX: - m_feedback_delay[index-FEEDBACK_DELAY_MIN] = (uint)(value * DELAY_MAX); - m_reverb_1.setFeedbackDelay(m_feedback_delay[0], m_feedback_delay[1]); - m_reverb_2.setFeedbackDelay(m_feedback_delay[0], m_feedback_delay[1]); - break; + case FEEDBACK_DELAY_MIN: + case FEEDBACK_DELAY_XAX: + { + double p = m_params[index]->fromSlider(value); + uint delay = (uint)(p*sampleRate/1000); + m_feedback_delay[index-FEEDBACK_DELAY_MIN] = delay; + m_reverb_1.setFeedbackDelay(m_feedback_delay[0], m_feedback_delay[1]); + m_reverb_2.setFeedbackDelay(m_feedback_delay[0], m_feedback_delay[1]); + break; + } } @@ -122,23 +114,14 @@ float Plugin::getParameter(VstInt32 index) switch(index) { case ORDER: - value = (float)MAX_ORDER; - break; - case SIZE_1: case SIZE_2: case SIZE_3: case SIZE_4: - value = m_reverb_1.getDelay(index - SIZE_1); - break; - case FEEDBACK_GAIN: - value = m_reverb_1.getFeedbackGain(); - break; - case FEEDBACK_DELAY_MIN: case FEEDBACK_DELAY_XAX: - value = m_feedback_delay[index-FEEDBACK_DELAY_MIN]; + value = m_params[index]->getSlider(); break; @@ -159,7 +142,7 @@ void Plugin::getParameterName(VstInt32 index, char *label) case FEEDBACK_DELAY_MIN: case FEEDBACK_DELAY_XAX: case FEEDBACK_GAIN: - strcpy(label,pFTypeString[index]); + strcpy(label,m_params[index]->name().c_str()); break; default: strcpy(label,"Unknown"); @@ -180,10 +163,8 @@ void Plugin::getParameterDisplay(VstInt32 index, char *text) case SIZE_4: case FEEDBACK_DELAY_MIN: case FEEDBACK_DELAY_XAX: - sprintf(text, "%d", (int)getParameter(index)); - break; case FEEDBACK_GAIN: - sprintf(text, "%f", getParameter(index)); + sprintf(text, "%f", m_params[index]->getParameter()); break; } } @@ -201,7 +182,7 @@ void Plugin::getParameterLabel(VstInt32 index, char *label) case FEEDBACK_DELAY_MIN: case FEEDBACK_DELAY_XAX: case FEEDBACK_GAIN: - strcpy(label, pFUnitString[index]); + strcpy(label,m_params[index]->unit().c_str()); break; } } diff --git a/src/plugin.hpp b/src/plugin.hpp index 8677ff2..d235cc7 100755 --- a/src/plugin.hpp +++ b/src/plugin.hpp @@ -8,10 +8,12 @@ #include "public.sdk/source/vst2.x/audioeffectx.h" #include +#include "param.hpp" class Plugin : public AudioEffectX { - const uint DELAY_MAX = 48000; + static const uint DELAY_MAX = 48000; + static const uint NUM_PARMS = 8; public: Plugin(audioMasterCallback audioMaster); @@ -42,6 +44,7 @@ private: Reverb m_reverb_1; Reverb m_reverb_2; uint m_feedback_delay[2]; + Param *m_params[NUM_PARMS]; }; #endif // __PLUGIN_H