Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,39 @@
/*
* helpers.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "pluginterfaces/base/ftypes.h"
#if BYTEORDER == kBigEndian
#define SWAP64_LE(x)
#define SWAP64_BE(x) SWAP_64(x)
#define SWAP32_LE(x)
#define SWAP32_BE(x) SWAP_32(x)
#else
#define SWAP64_LE(x) SWAP_64(x)
#define SWAP64_BE(x)
#define SWAP32_LE(x) SWAP_32(x)
#define SWAP32_BE(x)
#endif
@@ -0,0 +1,63 @@
/*
* mdaAmbienceController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/13/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaAmbienceController.h"
#include "pluginterfaces/base/ibstream.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
AmbienceController::AmbienceController ()
{
}
//-----------------------------------------------------------------------------
AmbienceController::~AmbienceController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API AmbienceController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING("Size"), USTRING("m"), 0, 0.7, ParameterInfo::kCanAutomate, pid++, 0, 10));
parameters.addParameter (new ScaledParameter (USTRING("HF Damp"), USTRING("%"), 0, 0.7, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Mix"), USTRING("%"), 0, 0.9, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -20, 20));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API AmbienceController::terminate ()
{
return BaseController::terminate ();
}
}}} // namespaces
@@ -0,0 +1,49 @@
/*
* mdaAmbienceController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/13/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaAmbienceProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class AmbienceController : public BaseController
{
public:
AmbienceController ();
~AmbienceController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new AmbienceController; }
inline static DECLARE_UID (uid, 0x0D9DD331, 0xCCF044FF, 0xB7DCB8B9, 0xDF977096);
};
}}} // namespaces
@@ -0,0 +1,204 @@
/*
* mdaAmbienceProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/13/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaAmbienceProcessor.h"
#include "mdaAmbienceController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
AmbienceProcessor::AmbienceProcessor ()
: buf1 (nullptr)
, buf2 (nullptr)
, buf3 (nullptr)
, buf4 (nullptr)
{
setControllerClass (AmbienceController::uid);
allocParameters (4);
}
//-----------------------------------------------------------------------------
AmbienceProcessor::~AmbienceProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API AmbienceProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
//inits here!
params[0] = 0.7; //size
params[1] = 0.7; //hf
params[2] = 0.9; //mix
params[3] = 0.5; //output
buf1 = new float[1024];
buf2 = new float[1024];
buf3 = new float[1024];
buf4 = new float[1024];
fil = 0.0f;
den = pos = 0;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API AmbienceProcessor::terminate ()
{
if (buf1)
delete [] buf1;
if (buf2)
delete [] buf2;
if (buf3)
delete [] buf3;
if (buf4)
delete [] buf4;
buf1 = buf2 = buf3 = buf4 = nullptr;
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API AmbienceProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API AmbienceProcessor::setProcessing (TBool state)
{
if (state)
clearBuffers ();
BaseProcessor::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void AmbienceProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, r;
float t, f=fil, fb=fbak, dmp=damp, y =dry, w=wet;
int32 p = pos, d1, d2, d3, d4;
if (rdy ==0)
clearBuffers();
d1 = (p + (int32)(107 * size)) & 1023;
d2 = (p + (int32)(142 * size)) & 1023;
d3 = (p + (int32)(277 * size)) & 1023;
d4 = (p + (int32)(379 * size)) & 1023;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
f += dmp * (w * (a + b) - f); //HF damping
r = f;
t = *(buf1 + p);
r -= fb * t;
*(buf1 + d1) = r; //allpass
r += t;
t = *(buf2 + p);
r -= fb * t;
*(buf2 + d2) = r; //allpass
r += t;
t = *(buf3 + p);
r -= fb * t;
*(buf3 + d3) = r; //allpass
r += t;
a = y * a + r - f; //left output
t = *(buf4 + p);
r -= fb * t;
*(buf4 + d4) = r; //allpass
r += t;
b = y * b + r - f; //right output
++p &= 1023;
++d1 &= 1023;
++d2 &= 1023;
++d3 &= 1023;
++d4 &= 1023;
*++out1 = a;
*++out2 = b;
}
pos=p;
if (fabs (f)>1.0e-10) { fil=f; den=0; } //catch denormals
else { fil=0.0f; if (den==0) { den=1; clearBuffers(); } }
}
//-----------------------------------------------------------------------------
void AmbienceProcessor::clearBuffers ()
{
memset (buf1, 0, 1024 * sizeof (float));
memset (buf2, 0, 1024 * sizeof (float));
memset (buf3, 0, 1024 * sizeof (float));
memset (buf4, 0, 1024 * sizeof (float));
rdy = 1;
}
//-----------------------------------------------------------------------------
void AmbienceProcessor::recalculate ()
{
float tmp;
fbak = 0.8f;
damp = static_cast<float> (0.05f + 0.9f * params[1]);
tmp = powf (10.0f, static_cast<float> (2.0f * params[3] - 1.0f));
dry = static_cast<float> (tmp - params[2] * params[2] * tmp);
wet = static_cast<float> (0.8f * params[2] * tmp);
tmp = static_cast<float> (0.025f + 2.665f * params[0]);
if (size != tmp)
rdy = 0; // need to flush buffer
size = tmp;
}
}}} // namespaces
@@ -0,0 +1,62 @@
/*
* mdaAmbienceProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/13/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class AmbienceProcessor : public BaseProcessor
{
public:
AmbienceProcessor ();
~AmbienceProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaA'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new AmbienceProcessor; }
inline static DECLARE_UID (uid, 0xAF799E3A, 0xC94B444A, 0xB5B24FD5, 0xD3E3F9E4);
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
void clearBuffers ();
float *buf1, *buf2, *buf3, *buf4;
float fil, fbak, damp, wet, dry, size;
int32 pos, den, rdy;
};
}}} // namespaces
@@ -0,0 +1,125 @@
/*
* mdaBandistoController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaBandistoController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
BandistoController::BandistoController ()
{
}
//-----------------------------------------------------------------------------
BandistoController::~BandistoController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BandistoController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
auto* listenParam = new IndexedParameter (USTRING("Listen"), nullptr, 3, 0, ParameterInfo::kCanAutomate | ParameterInfo::kIsList, kParam0);
listenParam->setIndexString (0, UString128("Low"));
listenParam->setIndexString (1, UString128("Mid"));
listenParam->setIndexString (2, UString128("High"));
listenParam->setIndexString (3, UString128("Output"));
parameters.addParameter (listenParam);
parameters.addParameter (USTRING("L <> M"), USTRING("Hz"), 0, 0.4, ParameterInfo::kCanAutomate, kParam1);
parameters.addParameter (USTRING("M <> H"), USTRING("Hz"), 0, 0.5, ParameterInfo::kCanAutomate, kParam2);
parameters.addParameter (new ScaledParameter (USTRING("L Dist"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam3, 0, 60));
parameters.addParameter (new ScaledParameter (USTRING("M Dist"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam4, 0, 60));
parameters.addParameter (new ScaledParameter (USTRING("H Dist"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam5, 0, 60));
parameters.addParameter (new ScaledParameter (USTRING("L Out"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam6, -20, 20));
parameters.addParameter (new ScaledParameter (USTRING("M Out"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam7, -20, 20));
parameters.addParameter (new ScaledParameter (USTRING("H Out"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam8, -20, 20));
auto* modeParam = new IndexedParameter (USTRING("Mode"), nullptr, 1, 0., ParameterInfo::kCanAutomate | ParameterInfo::kIsList, kParam9);
modeParam->setIndexString (0, UString128("Bipolar"));
modeParam->setIndexString (1, UString128("Unipolar"));
parameters.addParameter (modeParam);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BandistoController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BandistoController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case kParam1:
{
double fi1 = pow (10.0,valueNormalized - 1.70);
fi1 = sampleRate * fi1 * (0.098 + 0.09*fi1 + 0.5*pow (fi1,8.2));
result.printFloat (fi1, 1);
break;
}
case kParam2:
{
double fi1 = pow (10.0,valueNormalized - 1.05);
fi1 = sampleRate * fi1 * (0.015 + 0.15*fi1 + 0.9*pow (fi1,8.2));
result.printFloat (fi1, 1);
break;
}
default:
return EditController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BandistoController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
switch (tag)
{
case kParam1:
{
break;
}
case kParam2:
{
break;
}
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;
}
}}} // namespaces
@@ -0,0 +1,73 @@
/*
* mdaBandistoController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaBandistoProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class BandistoController : public BaseController
{
public:
BandistoController ();
~BandistoController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kParam6,
kParam7,
kParam8,
kParam9,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new BandistoController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
//-----------------------------------------------------------------------------
inline static DECLARE_UID (uid, 0x5653456D, 0x6461446D, 0x64612062, 0x616E6469);
#else
//-----------------------------------------------------------------------------
inline static DECLARE_UID (uid, 0x302EA341, 0xB6AC46C6, 0xB54D65E5, 0x95E63FAB);
#endif
};
}}} // namespaces
@@ -0,0 +1,161 @@
/*
* mdaBandistoProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaBandistoProcessor.h"
#include "mdaBandistoController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
BandistoProcessor::BandistoProcessor ()
{
setControllerClass (BandistoController::uid);
allocParameters(10);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BandistoProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
//inits here!
params[0] = (float)1.00; //Listen: L/M/H/out
params[1] = (float)0.40; //xover1
params[2] = (float)0.50; //xover2
params[3] = (float)0.50; //L drive (1)
params[4] = (float)0.50; //M drive
params[5] = (float)0.50; //H drive
params[6] = (float)0.50; //L trim (2)
params[7] = (float)0.50; //M trim
params[8] = (float)0.50; //H trim
params[9] = (float)0.4; //transistor/valve
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
void BandistoProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, c, d, g, l=fb3, m, h, s, sl=slev;
float f1i=fi1, f1o=fo1, f2i=fi2, f2o=fo2, b1=fb1, b2=fb2;
float g1, d1=driv1, t1=trim1;
float g2, d2=driv2, t2=trim2;
float g3, d3=driv3, t3=trim3;
int v=valve;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2; //process from here...
s = (a - b) * sl; //keep stereo component for later
a += (float)(b + 0.00002); //dope filter at low level
b2 = (f2i * a) + (f2o * b2); //crossovers
b1 = (f1i * b2) + (f1o * b1);
l = (f1i * b1) + (f1o * l);
m=b2-l; h=a-b2;
g = (l>0)? l : -l;
g = (float)(1.0 / (1.0 + d1 * g) ); //distort
g1=g;
g = (m > 0)? m : -m;
g = (float)(1.0 / (1.0 + d2 * g) );
g2=g;
g = (h>0)? h : -h;
g = (float)(1.0 / (1.0 + d3 * g) );
g3=g;
if (v) { if (l>0)g1=1.0; if (m > 0)g2=1.0; if (h>0)g3=1.0; }
a = (l*g1*t1) + (m*g2*t2) + (h*g3*t3);
c = a + s; // output
d = a - s;
*++out1 = c;
*++out2 = d;
}
fb1=b1; fb2=b2, fb3=l;
}
//-----------------------------------------------------------------------------
void BandistoProcessor::recalculate ()
{
driv1 = (float)pow (10.0,(6.0 * params[3] * params[3]) - 1.0);
driv2 = (float)pow (10.0,(6.0 * params[4] *params[4]) - 1.0);
driv3 = (float)pow (10.0,(6.0 * params[5] *params[5]) - 1.0);
valve = int (1.99 * params[9]);
if (valve)
{
trim1 = (float)(0.5);
trim2 = (float)(0.5);
trim3 = (float)(0.5);
}
else
{
trim1 = 0.3f*(float)pow (10.0,(4.0 * pow ((float)(params[3]),3.f)));//(0.5 + 500.0 * pow (params[4,6.0));
trim2 = 0.3f*(float)pow (10.0,(4.0 * pow ((float)(params[4]),3.f)));
trim3 = 0.3f*(float)pow (10.0,(4.0 * pow ((float)(params[5]),3.f)));
}
trim1 = (float)(trim1 * pow (10.0, 2.0 * params[6] - 1.0));
trim2 = (float)(trim2 * pow (10.0, 2.0 * params[7] - 1.0));
trim3 = (float)(trim3 * pow (10.0, 2.0 * params[8] - 1.0));
switch (int (params[0]*5.0))
{
case 0: trim2=0.0; trim3=0.0; slev=0.0; break;
case 1: trim1=0.0; trim3=0.0; slev=0.0; break;
case 2: trim1=0.0; trim2=0.0; slev=0.0; break;
default: slev=0.5; break;
}
fi1 = (float)pow (10.0,params[1] - 1.70); fo1= (float)(1.0 - fi1);
fi2 = (float)pow (10.0,params[2] - 1.05); fo2= (float)(1.0 - fi2);
}
}}} // namespaces
@@ -0,0 +1,65 @@
/*
* mdaBandistoProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class BandistoProcessor : BaseProcessor
{
public:
BandistoProcessor ();
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaD'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new BandistoProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461446D, 0x64612062, 0x616E6469);
#else
inline static DECLARE_UID (uid, 0x79F1CDBB, 0x1F004396, 0x947E35BA, 0x22B4FA6D);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float gain1, driv1, trim1;
float gain2, driv2, trim2;
float gain3, driv3, trim3;
float fi1, fb1, fo1, fi2, fb2, fo2, fb3, slev;
int valve;
};
}}} // namespaces
@@ -0,0 +1,226 @@
/*
* mdaBaseController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaBaseController.h"
#include "mdaParameter.h"
#include "helpers.h"
#include "pluginterfaces/base/ibstream.h"
#include "pluginterfaces/vst/ivstcomponent.h"
#include "public.sdk/source/vst/utility/vst2persistence.h"
#include "base/source/fstreamer.h"
namespace Steinberg {
namespace Vst {
namespace mda {
const TChar BaseController::kMicroSecondsString[] = {0x00b5, 0x0073, 0x0};
//-----------------------------------------------------------------------------
BaseController::BaseController () : sampleRate (44100), addBypassParameter (true)
{
for (int32 i = 0; i < kCountCtrlNumber; i++)
midiCCParamID[i] = -1;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BaseController::initialize (FUnknown* context)
{
tresult res = EditControllerEx1::initialize (context);
if (res == kResultOk)
{
UnitInfo uinfo;
uinfo.id = kRootUnitId;
uinfo.parentUnitId = kNoParentUnitId;
uinfo.programListId = kPresetParam;
UString name (uinfo.name, 128);
name.fromAscii ("Root");
addUnit (new Unit (uinfo));
if (addBypassParameter)
{
auto* bypassParam = new IndexedParameter (
USTRING ("Bypass"), nullptr, 1, 0,
ParameterInfo::kIsBypass | ParameterInfo::kCanAutomate, kBypassParam);
bypassParam->setIndexString (0, UString128 ("off"));
bypassParam->setIndexString (1, UString128 ("on"));
parameters.addParameter (bypassParam);
}
}
return res;
}
//-----------------------------------------------------------------------------
int32 PLUGIN_API BaseController::getProgramListCount ()
{
if (parameters.getParameter (kPresetParam))
return 1;
return 0;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BaseController::getProgramListInfo (int32 listIndex,
ProgramListInfo& info /*out*/)
{
Parameter* param = parameters.getParameter (kPresetParam);
if (param && listIndex == 0)
{
info.id = kPresetParam;
info.programCount = (int32)param->toPlain (1) + 1;
UString name (info.name, 128);
name.fromAscii ("Presets");
return kResultTrue;
}
return kResultFalse;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BaseController::getProgramName (ProgramListID listId, int32 programIndex,
String128 name /*out*/)
{
if (listId == kPresetParam)
{
Parameter* param = parameters.getParameter (kPresetParam);
if (param)
{
ParamValue normalized = param->toNormalized (programIndex);
param->toString (normalized, name);
return kResultTrue;
}
}
return kResultFalse;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BaseController::getUnitByBus (MediaType type, BusDirection dir, int32 busIndex,
int32 channel, UnitID& unitId)
{
if (type == MediaTypes::kEvent && dir == BusDirections::kInput && busIndex == 0 && channel == 0)
{
if (auto param = parameters.getParameter (kPresetParam))
{
unitId = param->getUnitID ();
return kResultTrue;
}
}
return kResultFalse;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BaseController::notify (IMessage* message)
{
if (strcmp (message->getMessageID (), "activated") == 0)
{
message->getAttributes ()->getFloat ("SampleRate", sampleRate);
return kResultTrue;
}
return EditControllerEx1::notify (message);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BaseController::setComponentState (IBStream* state)
{
if (!state)
return kResultFalse;
if (auto vst2State = VST3::tryVst2StateLoad (*state))
{
if (vst2State->programs.empty ())
return kResultFalse;
auto& currentProgram = vst2State->programs[vst2State->currentProgram];
if (auto bypassParam = parameters.getParameter (kBypassParam))
bypassParam->setNormalized (vst2State->isBypassed ? 1. : 0.);
if (auto param = parameters.getParameter (kPresetParam))
param->setNormalized (param->toNormalized (vst2State->currentProgram));
auto numStateParams = static_cast<int32> (currentProgram.values.size ());
auto numParams = parameters.getParameterCount ();
for (auto index = 0; index < numParams && index < numStateParams; ++index)
{
if (auto param = parameters.getParameter (index))
{
param->setNormalized (currentProgram.values[index]);
}
}
return kResultTrue;
}
IBStreamer streamer (state, kLittleEndian);
uint32 temp;
streamer.readInt32u (temp); // numParams or Header
if (temp == BaseController::kMagicNumber)
{
// read current Program
streamer.readInt32u (temp);
Parameter* param = parameters.getParameter (kPresetParam);
if (param)
param->setNormalized (param->toNormalized (temp));
// numParams
streamer.readInt32u (temp);
}
// read each parameter
for (uint32 i = 0; i < temp; i++)
{
ParamValue value;
if (streamer.readDouble (value) == false)
return kResultFalse;
setParamNormalized (i, value);
}
// bypass
uint32 bypassState;
if (streamer.readInt32u (bypassState) == false)
return kResultFalse;
Parameter* bypassParam = parameters.getParameter (kBypassParam);
if (bypassParam)
bypassParam->setNormalized (bypassState);
return kResultTrue;
}
//------------------------------------------------------------------------
tresult PLUGIN_API BaseController::getMidiControllerAssignment (int32 busIndex, int16 /*channel*/,
CtrlNumber midiControllerNumber,
ParamID& tag /*out*/)
{
if (busIndex == 0 && midiControllerNumber < kCountCtrlNumber && midiCCParamID[midiControllerNumber] != -1)
{
tag = midiCCParamID[midiControllerNumber];
return kResultTrue;
}
return kResultFalse;
}
//------------------------------------------------------------------------
tresult PLUGIN_API BaseController::queryInterface (const char* iid, void** obj)
{
QUERY_INTERFACE (iid, obj, IMidiMapping::iid, IMidiMapping)
return EditControllerEx1::queryInterface (iid, obj);
}
}
}
} // namespaces
@@ -0,0 +1,83 @@
/*
* mdaBaseController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "public.sdk/source/vst/vsteditcontroller.h"
#include "public.sdk/source/vst/vstparameters.h"
#include "pluginterfaces/vst/ivstmidicontrollers.h"
#include "pluginterfaces/base/ustring.h"
#include "mdaParameter.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class BaseController : public EditControllerEx1, public IMidiMapping
{
public:
BaseController ();
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
tresult PLUGIN_API notify (IMessage* message) SMTG_OVERRIDE;
int32 PLUGIN_API getProgramListCount () SMTG_OVERRIDE;
tresult PLUGIN_API getProgramListInfo (int32 listIndex, ProgramListInfo& info /*out*/) SMTG_OVERRIDE;
tresult PLUGIN_API getProgramName (ProgramListID listId, int32 programIndex, String128 name /*out*/) SMTG_OVERRIDE;
tresult PLUGIN_API getUnitByBus (MediaType type, BusDirection dir, int32 busIndex,
int32 channel, UnitID& unitId) SMTG_OVERRIDE;
tresult PLUGIN_API getMidiControllerAssignment (int32 busIndex, int16 channel, CtrlNumber midiControllerNumber, ParamID& tag/*out*/) SMTG_OVERRIDE;
ParameterContainer& getParameters () { return parameters; }
//-----------------------------
DELEGATE_REFCOUNT (EditControllerEx1)
tresult PLUGIN_API queryInterface (const char* iid, void** obj) SMTG_OVERRIDE;
//-----------------------------
enum {
kMagicNumber = 9999999,
kBypassParam = 'bpas',
kPresetParam = 'prst',
kModWheelParam = 'modw',
kBreathParam = 'brth',
kCtrler3Param = 'ct03',
kExpressionParam = 'expr',
kPitchBendParam = 'pitb',
kSustainParam = 'sust',
kAftertouchParam = 'aftt',
};
static const TChar kMicroSecondsString[];
protected:
double getSampleRate () const { return sampleRate; }
int32 midiCCParamID[kCountCtrlNumber];
double sampleRate;
bool addBypassParameter;
};
}}} // namespaces
@@ -0,0 +1,579 @@
/*
* mdaBaseProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaBaseProcessor.h"
#include "mdaBaseController.h"
#include "helpers.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"
#include "pluginterfaces/base/ibstream.h"
#include "public.sdk/source/vst/utility/vst2persistence.h"
#include "public.sdk/source/vst/utility/processdataslicer.h"
#include "base/source/fstreamer.h"
#include <cmath>
#include <cstdlib>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
Processor::Processor ()
: params (nullptr)
, numParams (0)
, bypassRamp (0)
, bypassBuffer0 (nullptr)
, bypassBuffer1 (nullptr)
, bypassState (false)
{
}
//-----------------------------------------------------------------------------
Processor::~Processor ()
{
if (bypassBuffer0)
std::free (bypassBuffer0);
if (bypassBuffer1)
std::free (bypassBuffer1);
if (params)
delete [] params;
}
//------------------------------------------------------------------------
bool Processor::checkStateTransfer ()
{
bool result = false;
stateTransfer.accessTransferObject_rt ([this, &result] (const std::vector<ParamValue>& p) {
for (auto index = 0u; index < p.size (); ++index)
{
params[index] = p[index];
}
result = true;
});
return result;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API Processor::process (ProcessData& data)
{
preProcess ();
bool doRecalculate = checkStateTransfer ();
doRecalculate |= processParameterChanges (data.inputParameterChanges);
if (doRecalculate)
recalculate ();
processEvents (data.inputEvents);
if (data.numSamples > 0 && !bypassProcessing (data))
{
doProcessing (data);
checkSilence (data);
}
return kResultTrue;
}
//-----------------------------------------------------------------------------
void Processor::processEvents (IEventList* events)
{
if (events)
{
Event e {};
int32 count = events->getEventCount ();
for (int32 i = 0; i < count; i++)
{
if (events->getEvent (i, e) == kResultTrue)
processEvent (e);
}
}
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API Processor::setupProcessing (ProcessSetup& setup)
{
if (bypassBuffer0)
std::free (bypassBuffer0);
bypassBuffer0 = (float*)std::malloc (setup.maxSamplesPerBlock * sizeof (float));
if (bypassBuffer1)
std::free (bypassBuffer1);
bypassBuffer1 = (float*)std::malloc (setup.maxSamplesPerBlock * sizeof (float));
return AudioEffect::setupProcessing (setup);
}
//-----------------------------------------------------------------------------
bool Processor::bypassProcessing (ProcessData& data)
{
if (data.numSamples == 0)
return true;
if (isBypassed () || bypassRamp != 0)
{
if (bypassRamp)
{
float* origOut0 = data.outputs[0].channelBuffers32[0];
float* origOut1 = data.outputs[0].channelBuffers32[1];
data.outputs[0].channelBuffers32[0] = bypassBuffer0;
data.outputs[0].channelBuffers32[1] = bypassBuffer1;
doProcessing (data);
data.outputs[0].channelBuffers32[0] = origOut0;
data.outputs[0].channelBuffers32[1] = origOut1;
float* bpb0 = bypassBuffer0;
float* bpb1 = bypassBuffer1;
float origMix = 0;
float plugMix = 0;
float factor = 1.f / (float)data.numSamples;
if (bypassRamp > 0)
{
for (int32 i = 0; i < data.numSamples; i++)
{
origMix = (float)i * factor;
plugMix = (float)(data.numSamples - i) * factor;
*origOut0 = *origOut0 * origMix + *bpb0 * plugMix;
*origOut1 = *origOut1 * origMix + *bpb1 * plugMix;
origOut0++;
origOut1++;
bpb0++;
bpb1++;
}
}
else
{
for (int32 i = 0; i < data.numSamples; i++)
{
plugMix = (float)i * factor;
origMix = (float)(data.numSamples - i) * factor;
*origOut0 = *origOut0 * origMix + *bpb0 * plugMix;
*origOut1 = *origOut1 * origMix + *bpb1 * plugMix;
origOut0++;
origOut1++;
bpb0++;
bpb1++;
}
}
data.outputs[0].silenceFlags = 0;
bypassRamp = 0;
}
else
{
for (int32 bus = 0; (bus < data.numInputs) && (bus < data.numOutputs); bus++)
{
Bus* output = getAudioOutput (bus);
if (!output || !output->isActive ())
continue;
for (int32 channel = 0; channel < data.outputs[bus].numChannels; channel++)
{
if (data.numInputs <= bus || data.inputs[bus].numChannels <= channel)
{
memset (data.outputs[bus].channelBuffers32[channel], 0, sizeof (float) * data.numSamples);
data.outputs[bus].silenceFlags |= (uint64)1 << channel;
}
else
{
if (data.outputs[bus].channelBuffers32[channel] != data.inputs[bus].channelBuffers32[channel])
memcpy (data.outputs[bus].channelBuffers32[channel], data.inputs[bus].channelBuffers32[channel], sizeof (float) * data.numSamples);
data.outputs[bus].silenceFlags |= data.inputs[bus].silenceFlags & ((uint64)1 << channel);
}
}
}
}
return true;
}
return false;
}
#define kSilenceThreshold 0.000132184039
//-----------------------------------------------------------------------------
void Processor::checkSilence (ProcessData& data)
{
for (int32 bus = 0; bus < data.numOutputs; bus ++)
{
data.outputs[bus].silenceFlags = 0;
if (!getAudioOutput (bus)->isActive ())
continue;
for (int32 channel = 0; channel < data.outputs[bus].numChannels; channel++)
{
bool channelIsSilent = true;
for (int32 sample = 0; sample < data.numSamples; sample += 10)
{
if (fabs (data.outputs[bus].channelBuffers32[channel][sample]) > kSilenceThreshold)
{
channelIsSilent = false;
break;
}
}
if (channelIsSilent)
data.outputs[bus].silenceFlags |= (uint64)1 << channel;
}
}
}
//-----------------------------------------------------------------------------
bool Processor::processParameterChanges (IParameterChanges* changes)
{
if (changes)
{
int32 count = changes->getParameterCount ();
if (count > 0)
{
for (int32 i = 0; i < count; i++)
{
IParamValueQueue* queue = changes->getParameterData (i);
if (!queue)
continue;
ParamID paramId = queue->getParameterId ();
int32 pointCount = queue->getPointCount ();
int32 sampleOffset;
ParamValue value;
queue->getPoint (pointCount - 1, sampleOffset, value);
if (paramId == BaseController::kBypassParam)
setBypass (value >= 0.5, sampleOffset);
else if (paramId == BaseController::kPresetParam)
setCurrentProgramNormalized (value);
else
setParameter (paramId, value, sampleOffset);
}
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
void Processor::setBypass (bool state, int32 /*sampleOffset*/)
{
if (state != bypassState)
{
bypassState = state;
if (bypassState)
bypassRamp = 1;
else
bypassRamp = -1;
}
}
//-----------------------------------------------------------------------------
void Processor::setParameter (ParamID index, ParamValue newValue, int32 /*sampleOffset*/)
{
if (numParams > index)
params[index] = newValue;
}
//-----------------------------------------------------------------------------
void Processor::allocParameters (int32 _numParams)
{
if (params)
return;
numParams = _numParams;
params = new ParamValue[numParams];
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API Processor::setBusArrangements (SpeakerArrangement* inputs, int32 numIns, SpeakerArrangement* outputs, int32 numOuts)
{
if (numIns)
{
if (SpeakerArr::getChannelCount (inputs[0]) != 2)
return kResultFalse;
}
if (numOuts)
{
if (SpeakerArr::getChannelCount (outputs[0]) != 2)
return kResultFalse;
}
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API Processor::setActive (TBool state)
{
if (state)
{
if (auto msg = owned (allocateMessage ()))
{
msg->setMessageID ("activated");
msg->getAttributes ()->setFloat ("SampleRate", processSetup.sampleRate);
sendMessage (msg);
}
}
return AudioEffect::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API Processor::setState (IBStream* state)
{
if (!state)
return kResultFalse;
if (auto vst2State = VST3::tryVst2StateLoad (*state))
{
if ((vst2State->programs.empty ()) ||
(static_cast<int32_t> (vst2State->programs.size ()) <= vst2State->currentProgram))
return kResultFalse;
auto& currentProgram = vst2State->programs[vst2State->currentProgram];
bypassState = vst2State->isBypassed;
auto numStateParams = static_cast<uint32> (currentProgram.values.size ());
auto state = std::make_unique<StateT> ();
state->reserve (numStateParams);
for (uint32 index = 0; index < numParams && index < numStateParams; ++index)
{
state->push_back (currentProgram.values[index]);
}
stateTransfer.transferObject_ui (std::move (state));
return kResultTrue;
}
IBStreamer streamer (state, kLittleEndian);
uint32 temp;
streamer.readInt32u (temp); // numParams or Header
if (temp == BaseController::kMagicNumber)
{
// read current Program
streamer.readInt32u (temp);
setCurrentProgram (temp);
streamer.readInt32u (temp);
}
// read each parameter
for (uint32 i = 0; i < temp, i < numParams; i++)
{
streamer.readDouble (params[i]);
}
// bypass
streamer.readInt32u (temp);
bypassState = temp > 0;
recalculate ();
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API Processor::getState (IBStream* state)
{
if (!state)
return kResultFalse;
VST3::Vst2xState fxb;
fxb.fxUniqueID = getVst2UniqueId ();
fxb.fxVersion = 1;
fxb.currentProgram = getCurrentProgram ();
fxb.isBypassed = isBypassed ();
fxb.programs.resize (getNumPrograms ());
for (auto& program : fxb.programs)
program.values.resize (numParams);
auto& currentProgram = fxb.programs[fxb.currentProgram];
currentProgram.fxUniqueID = getVst2UniqueId ();
currentProgram.fxVersion = 1;
currentProgram.name = "";
for (uint32 index = 0; index < numParams; ++index)
{
currentProgram.values[index] = static_cast<float> (params[index]);
}
VST3::writeVst2State (fxb, *state);
#if 0
IBStreamer streamer (state, kLittleEndian);
if (hasProgram ())
{
// save header key
uint32 temp = BaseController::kMagicNumber;
streamer.writeInt32u (temp);
// save program
temp = getCurrentProgram ();
streamer.writeInt32u (temp);
}
// save number of parameter
streamer.writeInt32u (numParams);
// save each parameter
for (uint32 i = 0; i < numParams; i++)
{
streamer.writeDouble (params[i]);
}
// save bypass
streamer.writeInt32u (bypassState ? 1 : 0);
#endif
return kResultTrue;
}
//------------------------------------------------------------------------
SampleAccurateBaseProcessor::SampleAccurateBaseProcessor ()
{
parameterValues.resize (1);
}
//------------------------------------------------------------------------
void SampleAccurateBaseProcessor::allocParameters (int32 numParams)
{
Processor::allocParameters (numParams);
parameterValues.resize (numParams+1);
}
//------------------------------------------------------------------------
template <SymbolicSampleSizes SampleSize>
void SampleAccurateBaseProcessor::process (ProcessData& data)
{
ProcessDataSlicer slicer (16);
Event event {};
event.sampleOffset = -1;
auto eventCount = data.inputEvents ? data.inputEvents->getEventCount () : 0;
auto eventIndex = 0;
auto sampleCounter = 0;
if (eventCount)
data.inputEvents->getEvent (eventIndex++, event);
auto doProcess = [&] (ProcessData & data) noexcept
{
preProcess ();
while (event.sampleOffset >= 0)
{
if (event.sampleOffset <= data.numSamples)
{
processEvent (event);
event.sampleOffset = -1;
if (eventCount > eventIndex)
{
if (data.inputEvents->getEvent (eventIndex++, event) == kResultTrue)
{
event.sampleOffset -= sampleCounter;
}
else
event.sampleOffset = -1;
}
}
else
{
event.sampleOffset -= data.numSamples;
break;
}
}
bool needRecalculate = false;
for (auto& param : parameterValues)
{
if (!param.first)
break;
param.second.advance (data.numSamples, [&] (ParamValue value) {
setParameter (param.second.getParamID (), value, 0);
needRecalculate = true;
});
}
if (needRecalculate)
recalculate ();
doProcessing (data);
sampleCounter += data.numSamples;
};
slicer.process<SampleSize> (data, doProcess);
}
//------------------------------------------------------------------------
tresult PLUGIN_API SampleAccurateBaseProcessor::process (ProcessData& data)
{
if (checkStateTransfer ())
recalculate ();
processParameterChanges (data.inputParameterChanges);
if (data.numSamples > 0 && !bypassProcessing (data))
{
if (processSetup.symbolicSampleSize == SymbolicSampleSizes::kSample32)
process<SymbolicSampleSizes::kSample32> (data);
else
process<SymbolicSampleSizes::kSample64> (data);
checkSilence (data);
}
for (auto& paramterValue : parameterValues)
{
if (!paramterValue.first)
break;
paramterValue.second.endChanges ([&] (ParamValue value) {
setParameter (paramterValue.second.getParamID (), value, 0);
});
}
return kResultTrue;
}
//------------------------------------------------------------------------
bool SampleAccurateBaseProcessor::processParameterChanges (IParameterChanges* changes)
{
parameterValues[0].first = false;
if (!changes)
return false;
int32 count = changes->getParameterCount ();
if (count > 0)
{
uint32 usedChangedParameters = 0;
for (int32 i = 0; i < count; i++)
{
IParamValueQueue* queue = changes->getParameterData (i);
if (!queue)
continue;
auto paramID = queue->getParameterId ();
if (paramID < parameterValues.size ())
{
parameterValues[usedChangedParameters].first = true;
parameterValues[usedChangedParameters].second.setParamID (paramID);
parameterValues[usedChangedParameters].second.setValue (params[paramID]);
parameterValues[usedChangedParameters].second.beginChanges (queue);
++usedChangedParameters;
}
else
{
int32 sampleOffset;
ParamValue value;
queue->getPoint (queue->getPointCount () - 1, sampleOffset, value);
if (paramID == BaseController::kBypassParam)
setBypass (value >= 0.5, sampleOffset);
else
setParameter (paramID, value, sampleOffset);
}
}
parameterValues[usedChangedParameters].first = false;
return true;
}
return false;
}
//------------------------------------------------------------------------
}}} // namespace
@@ -0,0 +1,176 @@
/*
* mdaBaseProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "public.sdk/source/vst/vstaudioeffect.h"
#include "public.sdk/source/vst/utility/sampleaccurate.h"
#include "public.sdk/source/vst/utility/rttransfer.h"
#include "pluginterfaces/vst/ivstevents.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"
#include <vector>
#include <array>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class Processor : public AudioEffect
{
protected:
Processor ();
~Processor () override;
virtual void doProcessing (ProcessData& data) = 0;
virtual void preProcess () {}
virtual bool bypassProcessing (ProcessData& data);
virtual void processEvent (const Event& /*event*/) {}
virtual void checkSilence (ProcessData& data);
virtual void setBypass (bool state, int32 sampleOffset);
virtual bool processParameterChanges (IParameterChanges* changes);
virtual void setParameter (ParamID index, ParamValue newValue, int32 sampleOffset);
virtual void allocParameters (int32 numParams);
virtual void recalculate () {}
virtual bool hasProgram () const { return false; }
virtual uint32 getCurrentProgram () const { return 0; }
virtual uint32 getNumPrograms () const { return 1; }
virtual void setCurrentProgram (uint32 /*val*/) {}
virtual void setCurrentProgramNormalized (ParamValue /*val*/) {}
virtual int32 getVst2UniqueId () const = 0;
void processEvents (IEventList* events);
bool isBypassed () const { return bypassState; }
double getSampleRate () const { return processSetup.sampleRate; }
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
tresult PLUGIN_API setupProcessing (ProcessSetup& setup) SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
SpeakerArrangement* outputs, int32 numOuts) SMTG_OVERRIDE;
tresult PLUGIN_API setState (IBStream* state) final;
tresult PLUGIN_API getState (IBStream* state) final;
bool checkStateTransfer ();
ParamValue* params;
uint32 numParams;
int32 bypassRamp;
float* bypassBuffer0;
float* bypassBuffer1;
bool bypassState;
using StateT = std::vector<ParamValue>;
RTTransferT<StateT> stateTransfer;
};
//------------------------------------------------------------------------
class SampleAccurateBaseProcessor : public Processor
{
public:
SampleAccurateBaseProcessor ();
void allocParameters (int32 numParams) final;
tresult PLUGIN_API process (ProcessData& data) final;
bool processParameterChanges (IParameterChanges* changes) final;
private:
template<SymbolicSampleSizes SampleSize>
void process (ProcessData& data);
std::vector<std::pair<bool, SampleAccurate::Parameter>> parameterValues;
};
//------------------------------------------------------------------------
using BaseProcessor = SampleAccurateBaseProcessor;
static constexpr int32 EndNoteID = NoteIDUserRange::kNoteIDUserRangeLowerBound;
static constexpr int32 SustainNoteID = NoteIDUserRange::kNoteIDUserRangeLowerBound + 1;
//------------------------------------------------------------------------
template <typename VoiceT, int32 kEventBufferSize, int32 kNumVoices>
struct SynthData
{
using VOICE = VoiceT;
static constexpr int32 eventBufferSize = kEventBufferSize;
static constexpr int32 numVoices = kNumVoices;
static constexpr int32 eventsDoneID = 99999999;
using EventArray = std::array<Event, kEventBufferSize>;
using EventPos = typename EventArray::size_type;
EventArray events;
EventPos eventPos {0};
using VoiceArray = std::array<VOICE, kNumVoices>;
VoiceArray voice;
int32 activevoices {0};
int32 sustain {0};
void init () noexcept { activevoices = 0; }
bool hasEvents () const noexcept
{
return events[eventPos].flags & Event::EventFlags::kUserReserved1;
}
void clearEvents () noexcept
{
eventPos = 0;
events[0].flags = 0;
events[0].sampleOffset = eventsDoneID;
}
void processEvent (const Event& e) noexcept
{
switch (e.type)
{
//--- -------------------
case Event::kNoteOnEvent:
case Event::kNoteOffEvent:
{
events[eventPos] = e;
events[eventPos].flags |= Event::EventFlags::kUserReserved1;
++eventPos;
if (eventPos >= events.size ())
--eventPos;
else
{
events[eventPos].flags = 0;
events[eventPos].sampleOffset = eventsDoneID;
}
break;
}
//--- -------------------
default: return;
}
}
};
//------------------------------------------------------------------------
}
}
} // namespaces
@@ -0,0 +1,145 @@
/*
* mdaBeatBoxController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaBeatBoxController.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
BeatBoxController::BeatBoxController ()
{
}
//-----------------------------------------------------------------------------
BeatBoxController::~BeatBoxController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BeatBoxController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
//--- Create Units-------------
UnitInfo unitInfo;
Unit* unit;
// create a unit for the HiHat
unitInfo.id = 1;
unitInfo.parentUnitId = kRootUnitId; // attached to the root unit
Steinberg::UString (unitInfo.name, USTRINGSIZE (unitInfo.name)).assign (USTRING ("HiHat"));
unitInfo.programListId = kNoProgramListId;
unit = new Unit (unitInfo);
addUnit (unit);
// create a unit for the Kick
unitInfo.id = 2;
unitInfo.parentUnitId = kRootUnitId; // attached to the root unit
Steinberg::UString (unitInfo.name, USTRINGSIZE (unitInfo.name)).assign (USTRING ("Kick"));
unitInfo.programListId = kNoProgramListId;
unit = new Unit (unitInfo);
addUnit (unit);
// create a unit for the Snare
unitInfo.id = 3;
unitInfo.parentUnitId = kRootUnitId; // attached to the root unit
Steinberg::UString (unitInfo.name, USTRINGSIZE (unitInfo.name)).assign (USTRING ("Snare"));
unitInfo.programListId = kNoProgramListId;
unit = new Unit (unitInfo);
addUnit (unit);
Parameter* param;
param = new ScaledParameter (USTRING("Hat Thr"), USTRING("dB"), 0, 0.3, ParameterInfo::kCanAutomate, kParam0, -20, 20);
parameters.addParameter (param);
param->setUnitID (1);
param = parameters.addParameter (USTRING("Hat Rate"), USTRING("ms"), 0, 0.45, ParameterInfo::kCanAutomate, kParam1);
param->setUnitID (1);
param = parameters.addParameter (USTRING("Hat Mix"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam2);
param->setUnitID (1);
param = new ScaledParameter (USTRING("Kik Thr"), USTRING("dB"), 0, 0.46, ParameterInfo::kCanAutomate, kParam3, -20, 20);
parameters.addParameter (param);
param->setUnitID (2);
param = parameters.addParameter (USTRING("Kik Trig"), USTRING("Hz"), 0, 0.15, ParameterInfo::kCanAutomate, kParam4);
param->setUnitID (2);
param = parameters.addParameter (USTRING("Kik Mix"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam5);
param->setUnitID (2);
param = new ScaledParameter (USTRING("Snr Thr"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam6, -20, 20);
parameters.addParameter (param);
param->setUnitID (3);
param = parameters.addParameter (USTRING("Snr Trig"), USTRING("Hz"), 0, 0.7, ParameterInfo::kCanAutomate, kParam7);
param->setUnitID (3);
param = parameters.addParameter (USTRING("Snr Mix"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam8);
param->setUnitID (3);
parameters.addParameter (new ScaledParameter (USTRING("Dynamics"), USTRING("%"), 0, 0., ParameterInfo::kCanAutomate, kParam9, 0, 100));
auto* recParam = new IndexedParameter (USTRING("Record"), nullptr, 4, 0., ParameterInfo::kCanAutomate | ParameterInfo::kIsList, kParam10);
recParam->setIndexString (0, UString128("-"));
recParam->setIndexString (1, UString128("MONITOR"));
recParam->setIndexString (2, UString128("-> HAT"));
recParam->setIndexString (3, UString128("-> KIK"));
recParam->setIndexString (4, UString128("-> SNR"));
parameters.addParameter (recParam);
parameters.addParameter (USTRING("Thru Mix"), USTRING("dB"), 0, 0., ParameterInfo::kCanAutomate, kParam11);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BeatBoxController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BeatBoxController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
return BaseController::getParamStringByValue (tag, valueNormalized, string);
/*
UString128 result;
switch (tag)
{
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;*/
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BeatBoxController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
}}} // namespaces
@@ -0,0 +1,74 @@
/*
* mdaBeatBoxController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaBeatBoxProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class BeatBoxController : public BaseController
{
public:
BeatBoxController ();
~BeatBoxController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kParam6,
kParam7,
kParam8,
kParam9,
kParam10,
kParam11,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new BeatBoxController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461476D, 0x64612062, 0x65617462);
#else
inline static DECLARE_UID (uid, 0x7A668F2F, 0x42834CCF, 0xA4856D36, 0x891466F7);
#endif
};
}}} // namespaces
@@ -0,0 +1,297 @@
/*
* mdaBeatBoxProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaBeatBoxProcessor.h"
#include "mdaBeatBoxController.h"
#include <cmath>
#include <cstdlib>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
BeatBoxProcessor::BeatBoxProcessor ()
{
hbuf = kbuf = sbuf = sbuf2 = nullptr;
hthr = hfil = sthr = kthr = kfil1 = kfil2 = mix = 0;
klev = hlev = slev = 0;
ww = wwx = sb1 = sb2 = sf1 = sf2 = sf3 = 0;
kww = kwwx = ksb1 = ksb2 = ksf1 = ksf2 = 0;
dyne = dyna = dynr = dynm = 0;
allocParameters(12);
setControllerClass (BeatBoxController::uid);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BeatBoxProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.30; //hat thresh
params[1] = 0.45; //hat rate
params[2] = 0.50; //hat mix
params[3] = 0.46; //kick thresh
params[4] = 0.15; //kick key
params[5] = 0.50; //kick mix
params[6] = 0.50; //snare thresh
params[7] = 0.70; //snare key
params[8] = 0.50; //snare mix
params[9] = 0.00; //dynamics
params[10] = 0.00; //record
params[11] = 0.00; //thru mix
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BeatBoxProcessor::setActive (TBool state)
{
if (state)
{
sdel = (int32)(0.12 * getSampleRate ());
kdel = (int32)(0.10 * getSampleRate ());
sf3 = 0.991f; //r
sfx = 0; ksfx = 0;
rec = 0;
hbuflen = 20000;
kbuflen = 20000;
sbuflen = 60000;
if (getSampleRate ()>49000) { hbuflen*=2; kbuflen*=2; sbuflen*=2; }
hbuf = new float[hbuflen];
sbuf = new float[sbuflen];
sbuf2 = new float[sbuflen];
kbuf = new float[kbuflen];
hbufpos = sbufpos = kbufpos = 0;
memset (sbuf, 0, sbuflen * sizeof (float));
memset (sbuf2, 0, sbuflen * sizeof (float));
int32 t;
float e=0.00012f, de, o, o1=0.f, o2=0.f, p=0.2f, dp;
memset (hbuf, 0, hbuflen * sizeof (float)); //generate hi-hat
de = (float)pow (10.0,-36.0/getSampleRate ());
for(t=0;t<5000;t++)
{
o = (float)((rand() % 2000) - 1000);
*(hbuf + t) = e * ( 2.f * o1 - o2 - o);
e *= de; o2=o1; o1=o;
}
memset (kbuf, 0, kbuflen * sizeof (float)); //generate kick
de = (float)pow (10.0,-3.8/getSampleRate ());
e=0.5f; dp = 1588.f / static_cast<float> (getSampleRate ());
for(t=0;t<14000;t++)
{
*(kbuf + t) = e * (float)sin(p);
e *= de; p = (float)fmod(p + dp * e ,6.2831853f);
}
memset (sbuf, 0, sbuflen * sizeof (float)); //generate snare
de = (float)pow (10.0,-15.0/getSampleRate ());
e=0.38f; dp = 1103.f / static_cast<float> (getSampleRate ());
for(t=0;t<7000;t++)
{
o = (0.3f * o) + (float)((rand() % 2000) - 1000);
*(sbuf + t) = (float)(e * (sin(p) + 0.0004 * o));
*(sbuf2 + t) = *(sbuf + t);
e *= de; p = (float)fmod(p + 0.025,6.2831853);
}
}
else
{
if (hbuf) delete [] hbuf;
if (kbuf) delete [] kbuf;
if (sbuf) delete [] sbuf;
if (sbuf2) delete [] sbuf2;
hbuf = kbuf = sbuf = sbuf2 = nullptr;
}
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API BeatBoxProcessor::setProcessing (TBool state)
{
if (state)
{
hbufpos = sbufpos = kbufpos = 0;
}
BaseProcessor::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void BeatBoxProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, e, o, hf=hfil, ht=hthr, mx3=0.f, mx1=mix;
int32 hp=hbufpos, hl=hbuflen-2, hd=hdel;
float kt=kthr;
int32 kp=kbufpos, kl=kbuflen-2, kd=kdel;
float st=sthr, s, f1=sb1, f2=sb2, b1=sf1, b2=sf2, b3=sf3;
float k, kf1=ksb1, kf2=ksb2, kb1=ksf1, kb2=ksf2;
float hlv=hlev, klv=klev, slv=slev;
int32 sp=sbufpos, sl=sbuflen-2, sd=sdel;
float ya=dyna, yr = dynr, ye=dyne, ym=dynm, mx4;
if (sfx>0) { mx3=0.08f; slv=0.f; klv=0.f; hlv=0.f; mx1=0.f; sfx-=sampleFrames;} //key listen (snare)
if (ksfx>0) { mx3=0.03f; slv=0.f; klv=0.f; hlv=0.f; mx1=0.f; ksfx-=sampleFrames;
b1=ksf1; b2=ksf2; } //key listen (kick)
--in1;
--in2;
--out1;
--out2;
if (rec==0)
{
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
e = a + b;
ye = (e<ye)? ye * yr : e - ya * (e - ye); //dynamics envelope
hf = e - hf; //high filter
if ((hp>hd) && (hf>ht)) hp=0; else { hp++; if (hp>hl)hp=hl; }
o = hlv * *(hbuf + hp); //hat
k = e + (kf1 * kb1) - (kf2 * kb2); //low filter
kf2 = b3 * ((kf1 * kb2) + (kf2 * kb1));
kf1 = b3 * k;
if ((kp>kd) && (k>kt)) kp=0; else { kp++; if (kp>kl)kp=kl; }
o += klv * *(kbuf + kp); //kick
s = hf + (0.3f * e) + (f1 * b1) - (f2 * b2); //mid filter
f2 = b3 * ((f1 * b2) + (f2 * b1));
f1 = b3 * s;
if ((sp>sd) && (s>st)) sp=0; else { sp++; if (sp>sl)sp=sl; }
mx4 = 1.f + ym * (ye + ye - 1.f); //dynamics
*++out1 = mx1*a + mx3*s + mx4*(o + slv * *(sbuf + sp));
*++out2 = mx1*a + mx3*s + mx4*(o + slv * *(sbuf2 + sp));
hf=e;
}
}
else //record
{
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
e = 0.5f * (a + b);
if ((recpos==0) && (fabs (e) < 0.004)) e=0.f;
else
{
switch (rec)
{
case 1: break; //echo
case 2: if (recpos<hl) *(hbuf + recpos++) = e; else e=0.f; break;
case 3: if (recpos<kl) *(kbuf + recpos++) = e; else e=0.f; break;
case 4: if (recpos<sl)
{ *(sbuf+recpos)=a; *(sbuf2+recpos)=b; recpos++; }
else e=0.f; break;
}
}
*++out1 = e;
*++out2 = e;
}
}
hfil=hf; hbufpos=hp;
sbufpos=sp; sb1 = f1; sb2 = f2;
kbufpos=kp; ksb1 = kf1; ksb2 = kf2;
dyne=ye;
}
//-----------------------------------------------------------------------------
void BeatBoxProcessor::recalculate ()
{
//calcs here
hthr = (float)pow (10.f, (float)(2.f * params[0] - 2.f));
hdel = (int32)((0.04 + 0.20 * params[1]) * getSampleRate ());
sthr = (float)(40.0 * pow (10.f, (float)(2.f * params[6] - 2.f)));
kthr = (float)(220.0 * pow (10.f, (float)(2.f * params[3] - 2.f)));
hlev = (float)(0.0001f + params[2] * params[2] * 4.f);
klev = (float)(0.0001f + params[5] * params[5] * 4.f);
slev = (float)(0.0001f + params[8] * params[8] * 4.f);
wwx=ww;
ww = (float)pow (10.0,-3.0 + 2.2 * params[7]);
sf1 = (float)cos(3.1415927 * ww); //p
sf2 = (float)sin(3.1415927 * ww); //q
//sfx = 0; ksfx = 0;
kwwx=kww;
kww = (float)pow (10.0,-3.0 + 2.2 * params[4]);
ksf1 = (float)cos(3.1415927 * kww); //p
ksf2 = (float)sin(3.1415927 * kww); //q
if (wwx != ww) sfx = (int32)(2 * getSampleRate ());
if (kwwx != kww) ksfx = (int32)(2 * getSampleRate ());
rec = (int32)(4.9 * params[10]);
if ((rec!=recx) && (recpos>0)) //finish sample
{
switch (rec)
{
case 2: while (recpos<hbuflen) *(hbuf + recpos++) = 0.f; break;
case 3: while (recpos<kbuflen) *(kbuf + recpos++) = 0.f; break;
case 4: while (recpos<sbuflen)
{
*(sbuf + recpos) = 0.f;
*(sbuf2 + recpos) = 0.f; recpos++;
} break;
}
}
recpos=0; recx=rec;
mix = static_cast<float> (params[11]);
dynm = static_cast<float> (params[9]);
}
}}} // namespaces
@@ -0,0 +1,74 @@
/*
* mdaBeatBoxProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
class BeatBoxProcessor : public BaseProcessor
{
public:
BeatBoxProcessor ();
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaG'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new BeatBoxProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461476D, 0x64612062, 0x65617462);
#else
inline static DECLARE_UID (uid, 0x9E6A6E95, 0x9B734440, 0x97D787BE, 0xBBDDD831);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float hthr, hfil, sthr, kthr, kfil1, kfil2, mix;
float klev, hlev, slev;
float ww, wwx, sb1, sb2, sf1, sf2, sf3;
float kww, kwwx, ksb1, ksb2, ksf1, ksf2;
float dyne, dyna, dynr, dynm;
float *hbuf;
float *kbuf;
float *sbuf, *sbuf2;
int32 hbuflen, hbufpos, hdel;
int32 sbuflen, sbufpos, sdel, sfx;
int32 kbuflen, kbufpos, kdel, ksfx;
int32 rec, recx, recpos;
};
}}} // namespaces
@@ -0,0 +1,77 @@
/*
* mdaComboController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaComboController.h"
#include "pluginterfaces/base/ibstream.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
ComboController::ComboController ()
{
}
//-----------------------------------------------------------------------------
ComboController::~ComboController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ComboController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
auto* modelParam = new IndexedParameter (USTRING("Model"), nullptr, 6, 0.7, ParameterInfo::kCanAutomate | ParameterInfo::kIsList, kParam0);
modelParam->setIndexString (0, UString128("D.I."));
modelParam->setIndexString (1, UString128("Spkr Sim"));
modelParam->setIndexString (2, UString128("Radio"));
modelParam->setIndexString (3, UString128("MB 1\""));
modelParam->setIndexString (4, UString128("MB 8\""));
modelParam->setIndexString (5, UString128("4x12 ^"));
modelParam->setIndexString (6, UString128("4x12 >"));
parameters.addParameter (modelParam);
parameters.addParameter (new ScaledParameter (USTRING("Drive"), USTRING("S <> H"), 0, 0.7, ParameterInfo::kCanAutomate, kParam1, -100, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Bias"), nullptr, 0, 0.9, ParameterInfo::kCanAutomate, kParam2, -100, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam3, -20, 20, true));
auto* modeParam = new IndexedParameter (USTRING("Process"), nullptr, 1, 0.5, ParameterInfo::kCanAutomate | ParameterInfo::kIsList, kParam4);
modeParam->setIndexString (0, UString128("Stereo"));
modeParam->setIndexString (1, UString128("Mono"));
parameters.addParameter (modeParam);
parameters.addParameter (new ScaledParameter (USTRING("HPF Freq"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, kParam5, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("HPF Reso"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, kParam6, 0, 100, true));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ComboController::terminate ()
{
return BaseController::terminate ();
}
}}} // namespaces
@@ -0,0 +1,65 @@
/*
* mdaComboController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaComboProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class ComboController : public BaseController
{
public:
ComboController ();
~ComboController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kParam6,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new ComboController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461586D, 0x64612063, 0x6F6D626F);
#else
inline static DECLARE_UID (uid, 0x2C9437A7, 0x1B4D4E35, 0x845E3159, 0xE72D7BC4);
#endif
};
}}} // namespaces
@@ -0,0 +1,329 @@
/*
* mdaComboProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaComboProcessor.h"
#include "mdaComboController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
ComboProcessor::ComboProcessor ()
: buffer (nullptr)
, buffe2 (nullptr)
{
setControllerClass (ComboController::uid);
allocParameters (7);
}
//-----------------------------------------------------------------------------
ComboProcessor::~ComboProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ComboProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 1.00f; //select
params[1] = 0.50f; //drive
params[2] = 0.50f; //bias
params[3] = 0.50f; //output
params[4] = 0.40f; //stereo
params[5] = 0.00f; //hpf freq
params[6] = 0.50f; //hpf reso
size = 1024;
bufpos = 0;
buffer = new float[size];
buffe2 = new float[size];
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ComboProcessor::terminate ()
{
if (buffer) delete [] buffer;
if (buffe2) delete [] buffe2;
buffer = buffe2 = nullptr;
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ComboProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ComboProcessor::setProcessing (TBool state)
{
if (state)
clearBuffers ();
BaseProcessor::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void ComboProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, trm, m1=mix1, m2=mix2, clp=clip;
float o=lpf, i = 1.f-lpf, o2=hpf, bi=bias, drv=drive;
float f1=ff1, f2=ff2, f3=ff3, f4=ff4, f5=ff5;
float a2, b2, f6=ff6, f7=ff7, f8=ff8, f9=ff9, f10=ff10;
float hf=hhf, hq=hhq, h0=hh0, h1=hh1;
int32 d1=del1, d2=del2, bp = bufpos;
trm = trim * i * i * i * i;
--in1;
--in2;
--out1;
--out2;
if (ster) //stereo
{
while (--sampleFrames >= 0)
{
a = drv * (*++in1 + bi); a2 = drv * (*++in2 + bi);
if (mode)
{
b = (a>0.f)? a : -a; b2 = (a2>0.f)? a2 : -a2;
b = a / (1.f + b); b2 = a2 / (1.f + b2);
}
else
{
b = (a> clp)? clp : a; b2 = (a2> clp)? clp : a2; //distort
b = (a<-clp)? -clp : b; b2 = (a2<-clp)? -clp : b2;
}
*(buffer + bp) = b; *(buffe2 + bp) = b2;
b += (m1* *(buffer+((bp+d1)%1000))) + (m2* *(buffer+((bp+d2)%1000)));
b2+= (m1* *(buffe2+((bp+d1)%1000))) + (m2* *(buffe2+((bp+d2)%1000)));
f1 = o * f1 + trm * b; f6 = o * f6 + trm * b2;
f2 = o * f2 + f1; f7 = o * f7 + f6;
f3 = o * f3 + f2; f8 = o * f8 + f7;
f4 = o * f4 + f3; f9 = o * f9 + f8; //-24dB/oct filter
f5 = o2 * (f5 - f4) + f4; f10 = o2 * (f10 - f9) + f9;//high pass
b = f4 - f5; b2 = f9 - f10;
if (bp == 0) bufpos=999; else bufpos=bp-1;
*++out1 = b;
*++out2 = b2;
}
}
else //mono
{
if (mode) //soft clip
{
while (--sampleFrames >= 0)
{
a = drv * (*++in1 + *++in2 + bi);
h0 += hf * (h1 + a); //resonant highpass (Chamberlin SVF)
h1 -= hf * (h0 + hq * h1);
a += h1;
b = (a>0.f)? a : -a;
b = a / (1.f + b);
*(buffer + bp) = b;
b += (m1* *(buffer+((bp+d1)%1000))) + (m2* *(buffer+((bp+d2)%1000)));
f1 = o * f1 + trm * b;
f2 = o * f2 + f1;
f3 = o * f3 + f2;
f4 = o * f4 + f3; //-24dB/oct filter
f5 = o2 * (f5 - f4) + f4; //high pass
b = f4 - f5;
bp = (bp == 0)? 999 : bp - 1; //buffer position
*++out1 = b;
*++out2 = b;
}
}
else //hard clip
{
while (--sampleFrames >= 0)
{
a = drv * (*++in1 + *++in2 + bi);
h0 += hf * (h1 + a); //resonant highpass (Chamberlin SVF)
h1 -= hf * (h0 + hq * h1);
a += h1;
b = (a>clp)? clp : a; //distort
b = (a<-clp)? -clp : b;
*(buffer + bp) = b;
b += (m1* *(buffer+((bp+d1)%1000))) + (m2* *(buffer+((bp+d2)%1000)));
f1 = o * f1 + trm * b;
f2 = o * f2 + f1;
f3 = o * f3 + f2;
f4 = o * f4 + f3; //-24dB/oct filter
f5 = o2 * (f5 - f4) + f4; //high pass //also want smile curve here...
b = f4 - f5;
bp = (bp == 0)? 999 : bp - 1; //buffer position
*++out1 = b;
*++out2 = b;
}
}
}
bufpos = bp;
if (fabs (f1) < 1.0e-10) { ff1=0.f; ff2=0.f; ff3=0.f; ff4=0.f; ff5=0.f; }
else { ff1=f1; ff2=f2; ff3=f3; ff4=f4; ff5=f5; }
if (fabs (f6) < 1.0e-10) { ff6=0.f; ff7=0.f; ff8=0.f; ff9=0.f; ff10=0.f; }
else { ff6=f6; ff7=f7; ff8=f8; ff9=f9; ff10=f10; }
if (fabs (h0) < 1.0e-10) { hh0 = hh1 = 0.0f; } else { hh0=h0; hh1=h1; }
}
//-----------------------------------------------------------------------------
void ComboProcessor::clearBuffers ()
{
memset (buffer, 0, size * sizeof (float));
memset (buffe2, 0, size * sizeof (float));
ff1=0.f; ff2=0.f; ff3=0.f; ff4=0.f; ff5=0.f;
ff6=0.f; ff7=0.f; ff8=0.f; ff9=0.f; ff10=0.f;
hh0 = hh1 = 0.0f;
}
//-----------------------------------------------------------------------------
float ComboProcessor::filterFreq(float hz)
{
float j, k, r=0.999f;
j = r * r - 1;
k = (float)(2.f - 2.f * r * r * cos(0.647f * hz / getSampleRate () ));
return (float)((sqrt (k*k - 4.f*j*j) - k) / (2.f*j));
}
//-----------------------------------------------------------------------------
void ComboProcessor::recalculate ()
{
ster=0; if (params[4]>0.5) ster=1;
hpf = filterFreq(25.f);
switch (int (params[0]*6.9))
{
case 0: trim = 0.5f; lpf = 0.f; //DI
mix1 = (float)0.0; mix2 = (float)0.0;
del1 = 0; del2 = 0;
break;
case 1: trim = 0.53f; lpf = filterFreq(2700.f); //speaker sim
mix1 = (float)0.0; mix2 = (float)0.0;
del1 = 0; del2 = 0;
hpf = filterFreq(382.f);
break;
case 2: trim = 1.10f; lpf = filterFreq(1685.f); //radio
mix1 = -1.70f; mix2 = 0.82f;
del1 = int (getSampleRate () / 6546.f);
del2 = int (getSampleRate () / 4315.f);
break;
case 3: trim = 0.98f; lpf = filterFreq(1385.f); //mesa boogie 1"
mix1 = -0.53f; mix2 = 0.21f;
del1 = int (getSampleRate () / 7345.f);
del2 = int (getSampleRate () / 1193.f);
break;
case 4: trim = 0.96f; lpf = filterFreq(1685.f); //mesa boogie 8"
mix1 = -0.85f; mix2 = 0.41f;
del1 = int (getSampleRate () / 6546.f);
del2 = int (getSampleRate () / 3315.f);
break;
case 5: trim = 0.59f; lpf = lpf = filterFreq(2795.f);
mix1 = -0.29f; mix2 = 0.38f; //Marshall 4x12" celestion
del1 = int (getSampleRate () / 982.f);
del2 = int (getSampleRate () / 2402.f);
hpf = filterFreq(459.f);
break;
case 6: trim = 0.30f; lpf = filterFreq(1744.f); //scooped-out metal
mix1 = -0.96f; mix2 = 1.6f;
del1 = int (getSampleRate () / 356.f);
del2 = int (getSampleRate () / 1263.f);
hpf = filterFreq(382.f);
break;
}
mode = (params[1]<0.5)? 1 : 0;
if (mode) //soft clipping
{
drive = (float)pow (10.f, (float)(2.f - 6.f * params[1]));
trim *= 0.55f + 150.f * (float)pow ((float)(params[1]),4.0f);
}
else //hard clipping
{
drive = 1.f;
clip = (float)(11.7f - 16.f*params[1]);
if (params[1]>0.7)
{
drive = (float)pow (10.0f, (float)(7.f*params[1] - 4.9f));
clip = 0.5f;
}
}
bias = (float)(1.2f * params[2] - 0.6f);
if (params[1]>0.5) bias /= (float)(1.f + 3.f * (params[1]-0.5f));
else bias /= (float)(1.f + 3.f * (0.5f-params[1]));
trim *= (float)pow (10.f, (float)(2.f*params[3] - 1.f));
if (ster) trim *=2.f;
hhf = (float)params[5];
hhq = 1.1f - (float)params[6];
if (params[5]>0.05f) drive = drive * (1 + 0.1f * drive);
}
}}} // namespaces
@@ -0,0 +1,73 @@
/*
* mdaComboProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class ComboProcessor : public BaseProcessor
{
public:
ComboProcessor ();
~ComboProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaX'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new ComboProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461586D, 0x64612063, 0x6F6D626F);
#else
inline static DECLARE_UID (uid, 0x11C1BD22, 0x888F4F17, 0xB2E2A77B, 0x51CEDCD6);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
void clearBuffers ();
float filterFreq(float hz);
float clip, drive, trim, lpf, hpf, mix1, mix2;
float ff1, ff2, ff3, ff4, ff5, bias;
float ff6, ff7, ff8, ff9, ff10;
float hhf, hhq, hh0, hh1; //hpf
float *buffer, *buffe2;
int32 size, bufpos, del1, del2;
int mode, ster;
};
}}} // namespaces
@@ -0,0 +1,132 @@
/*
* mdaDX10Controller.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDX10Controller.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DX10Controller::DX10Controller ()
{
addBypassParameter = false;
}
//-----------------------------------------------------------------------------
DX10Controller::~DX10Controller ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DX10Controller::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
auto presetList = {"Bright E.Piano", "Jazz E.Piano", "E.Piano Pad", "Fuzzy E.Piano",
"Soft Chimes", "Harpsichord", "Funk Clav", "Sitar",
"Chiff Organ", "Tinkle", "Space Pad", "Koto",
"Harp", "Jazz Guitar", "Steel Drum", "Log Drum",
"Trumpet", "Horn", "Reed 1", "Reed 2",
"Violin", "Chunky Bass", "E.Bass", "Clunk Bass",
"Thick Bass", "Sine Bass", "Square Bass", "Upright Bass 1",
"Upright Bass 2", "Harmonics", "Scratch", "Syn Tom"};
auto* presetParam = new IndexedParameter (
USTRING ("Factory Presets"), nullptr, static_cast<int32> (presetList.size () - 1), 0.0,
ParameterInfo::kIsProgramChange | ParameterInfo::kIsList, kPresetParam);
parameters.addParameter (presetParam);
int32 i = 0;
for (auto item : presetList)
presetParam->setIndexString (i++, UString128 (item));
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING("Attack"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Decay"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Release"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (USTRING("Coarse"), USTRING("ratio"), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (USTRING("Fine"), USTRING("ratio"), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("Mod Init"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Mod Dec"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Mod Sus"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Mod Rel"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Mod Vel"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Vibrato"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (USTRING("Octave"), USTRING(""), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (USTRING("FineTune"), USTRING("cents"), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("WaveForm"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Mod Thru"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (USTRING("LFO Rate"), USTRING("Hz"), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
midiCCParamID[kCtrlModWheel] = kModWheelParam;
parameters.addParameter (USTRING("Mod Wheel"), USTRING(""), 0, 0, 0, kModWheelParam);
midiCCParamID[kPitchBend] = kPitchBendParam;
parameters.addParameter (USTRING("Pitch Bend"), USTRING(""), 0, 0.5, 0, kPitchBendParam);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DX10Controller::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DX10Controller::setParamNormalized (ParamID tag, ParamValue value)
{
tresult res = BaseController::setParamNormalized (tag, value);
if (res == kResultOk && tag == kPresetParam) // preset change
{
int32 program = static_cast<int32> (parameters.getParameter (tag)->toPlain (value));
for (int32 i = 0; i < 16; i++)
{
BaseController::setParamNormalized (i, DX10Processor::programParams[program][i]);
}
if (componentHandler)
componentHandler->restartComponent (kParamValuesChanged);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DX10Controller::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
return BaseController::getParamStringByValue (tag, valueNormalized, string);
/*
UString128 result;
switch (tag)
{
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;*/
}
}}} // namespaces
@@ -0,0 +1,58 @@
/*
* mdaDX10Controller.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaDX10Processor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DX10Controller : public BaseController
{
public:
DX10Controller ();
~DX10Controller () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setParamNormalized (ParamID tag, ParamValue value) SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new DX10Controller; }
//-----------------------------------------------------------------------------
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653454D, 0x4441786D, 0x64612064, 0x78313000);
#else
inline static DECLARE_UID (uid, 0x7EC0F00D, 0x92E142C7, 0x97056433, 0x30FFF119);
#endif
};
}}} // namespaces
@@ -0,0 +1,391 @@
/*
* mdaDX10Processor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDX10Processor.h"
#include "mdaDX10Controller.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
#define NOUTS 2 //number of outputs
#define SILENCE 0.0003f //voice choking
float DX10Processor::programParams[][NPARAMS] = {
{0.000f, 0.650f, 0.441f, 0.842f, 0.329f, 0.230f, 0.800f, 0.050f, 0.800f, 0.900f, 0.000f, 0.500f, 0.500f, 0.447f, 0.000f, 0.414f },
{0.000f, 0.500f, 0.100f, 0.671f, 0.000f, 0.441f, 0.336f, 0.243f, 0.800f, 0.500f, 0.000f, 0.500f, 0.500f, 0.178f, 0.000f, 0.500f },
{0.000f, 0.700f, 0.400f, 0.230f, 0.184f, 0.270f, 0.474f, 0.224f, 0.800f, 0.974f, 0.250f, 0.500f, 0.500f, 0.428f, 0.836f, 0.500f },
{0.000f, 0.700f, 0.400f, 0.320f, 0.217f, 0.599f, 0.670f, 0.309f, 0.800f, 0.500f, 0.263f, 0.507f, 0.500f, 0.276f, 0.638f, 0.526f },
{0.400f, 0.600f, 0.650f, 0.760f, 0.000f, 0.390f, 0.250f, 0.160f, 0.900f, 0.500f, 0.362f, 0.500f, 0.500f, 0.401f, 0.296f, 0.493f },
{0.000f, 0.342f, 0.000f, 0.280f, 0.000f, 0.880f, 0.100f, 0.408f, 0.740f, 0.000f, 0.000f, 0.600f, 0.500f, 0.842f, 0.651f, 0.500f },
{0.000f, 0.400f, 0.100f, 0.360f, 0.000f, 0.875f, 0.160f, 0.592f, 0.800f, 0.500f, 0.000f, 0.500f, 0.500f, 0.303f, 0.868f, 0.500f },
{0.000f, 0.500f, 0.704f, 0.230f, 0.000f, 0.151f, 0.750f, 0.493f, 0.770f, 0.500f, 0.000f, 0.400f, 0.500f, 0.421f, 0.632f, 0.500f },
{0.600f, 0.990f, 0.400f, 0.320f, 0.283f, 0.570f, 0.300f, 0.050f, 0.240f, 0.500f, 0.138f, 0.500f, 0.500f, 0.283f, 0.822f, 0.500f },
{0.000f, 0.500f, 0.650f, 0.368f, 0.651f, 0.395f, 0.550f, 0.257f, 0.900f, 0.500f, 0.300f, 0.800f, 0.500f, 0.000f, 0.414f, 0.500f },
{0.000f, 0.700f, 0.520f, 0.230f, 0.197f, 0.520f, 0.720f, 0.280f, 0.730f, 0.500f, 0.250f, 0.500f, 0.500f, 0.336f, 0.428f, 0.500f },
{0.000f, 0.240f, 0.000f, 0.390f, 0.000f, 0.880f, 0.100f, 0.600f, 0.740f, 0.500f, 0.000f, 0.500f, 0.500f, 0.526f, 0.480f, 0.500f },
{0.000f, 0.500f, 0.700f, 0.160f, 0.000f, 0.158f, 0.349f, 0.000f, 0.280f, 0.900f, 0.000f, 0.618f, 0.500f, 0.401f, 0.000f, 0.500f },
{0.000f, 0.500f, 0.100f, 0.390f, 0.000f, 0.490f, 0.250f, 0.250f, 0.800f, 0.500f, 0.000f, 0.500f, 0.500f, 0.263f, 0.145f, 0.500f },
{0.000f, 0.300f, 0.507f, 0.480f, 0.730f, 0.000f, 0.100f, 0.303f, 0.730f, 1.000f, 0.000f, 0.600f, 0.500f, 0.579f, 0.000f, 0.500f },
{0.000f, 0.300f, 0.500f, 0.320f, 0.000f, 0.467f, 0.079f, 0.158f, 0.500f, 0.500f, 0.000f, 0.400f, 0.500f, 0.151f, 0.020f, 0.500f },
{0.000f, 0.990f, 0.100f, 0.230f, 0.000f, 0.000f, 0.200f, 0.450f, 0.800f, 0.000f, 0.112f, 0.600f, 0.500f, 0.711f, 0.000f, 0.401f },
{0.280f, 0.990f, 0.280f, 0.230f, 0.000f, 0.180f, 0.400f, 0.300f, 0.800f, 0.500f, 0.000f, 0.400f, 0.500f, 0.217f, 0.480f, 0.500f },
{0.220f, 0.990f, 0.250f, 0.170f, 0.000f, 0.240f, 0.310f, 0.257f, 0.900f, 0.757f, 0.000f, 0.500f, 0.500f, 0.697f, 0.803f, 0.500f },
{0.220f, 0.990f, 0.250f, 0.450f, 0.070f, 0.240f, 0.310f, 0.360f, 0.900f, 0.500f, 0.211f, 0.500f, 0.500f, 0.184f, 0.000f, 0.414f },
{0.697f, 0.990f, 0.421f, 0.230f, 0.138f, 0.750f, 0.390f, 0.513f, 0.800f, 0.316f, 0.467f, 0.678f, 0.500f, 0.743f, 0.757f, 0.487f },
{0.000f, 0.400f, 0.000f, 0.280f, 0.125f, 0.474f, 0.250f, 0.100f, 0.500f, 0.500f, 0.000f, 0.400f, 0.500f, 0.579f, 0.592f, 0.500f },
{0.230f, 0.500f, 0.100f, 0.395f, 0.000f, 0.388f, 0.092f, 0.250f, 0.150f, 0.500f, 0.200f, 0.200f, 0.500f, 0.178f, 0.822f, 0.500f },
{0.000f, 0.600f, 0.400f, 0.230f, 0.000f, 0.450f, 0.320f, 0.050f, 0.900f, 0.500f, 0.000f, 0.200f, 0.500f, 0.520f, 0.105f, 0.500f },
{0.000f, 0.600f, 0.400f, 0.170f, 0.145f, 0.290f, 0.350f, 0.100f, 0.900f, 0.500f, 0.000f, 0.400f, 0.500f, 0.441f, 0.309f, 0.500f },
{0.000f, 0.600f, 0.490f, 0.170f, 0.151f, 0.099f, 0.400f, 0.000f, 0.900f, 0.500f, 0.000f, 0.400f, 0.500f, 0.118f, 0.013f, 0.500f },
{0.000f, 0.600f, 0.100f, 0.320f, 0.000f, 0.350f, 0.670f, 0.100f, 0.150f, 0.500f, 0.000f, 0.200f, 0.500f, 0.303f, 0.730f, 0.500f },
{0.300f, 0.500f, 0.400f, 0.280f, 0.000f, 0.180f, 0.540f, 0.000f, 0.700f, 0.500f, 0.000f, 0.400f, 0.500f, 0.296f, 0.033f, 0.500f },
{0.300f, 0.500f, 0.400f, 0.360f, 0.000f, 0.461f, 0.070f, 0.070f, 0.700f, 0.500f, 0.000f, 0.400f, 0.500f, 0.546f, 0.467f, 0.500f },
{0.000f, 0.500f, 0.500f, 0.280f, 0.000f, 0.330f, 0.200f, 0.000f, 0.700f, 0.500f, 0.000f, 0.500f, 0.500f, 0.151f, 0.079f, 0.500f },
{0.000f, 0.500f, 0.000f, 0.000f, 0.240f, 0.580f, 0.630f, 0.000f, 0.000f, 0.500f, 0.000f, 0.600f, 0.500f, 0.816f, 0.243f, 0.500f },
{0.000f, 0.355f, 0.350f, 0.000f, 0.105f, 0.000f, 0.000f, 0.200f, 0.500f, 0.500f, 0.000f, 0.645f, 0.500f, 1.000f, 0.296f, 0.500f }
};
//-----------------------------------------------------------------------------
DX10Processor::DX10Processor ()
: currentProgram (0)
{
setControllerClass (DX10Controller::uid);
allocParameters (NPARAMS);
}
//-----------------------------------------------------------------------------
DX10Processor::~DX10Processor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DX10Processor::initialize (FUnknown* context)
{
tresult res = Base::initialize (context);
if (res == kResultTrue)
{
addEventInput (USTRING("MIDI in"), 1);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
const float initParams[] = { 0.000f, 0.650f, 0.441f, 0.842f, 0.329f, 0.230f, 0.800f, 0.050f, 0.800f, 0.900f, 0.000f, 0.500f, 0.500f, 0.447f, 0.000f, 0.414f};
for (int32 i = 0; i < NPARAMS; i++)
params[i] = initParams[i];
//initialise...
for(int32 i = 0; i<synthData.numVoices; i++)
{
memset (&synthData.voice[i], 0, sizeof (VOICE));
synthData.voice[i].env = 0.0f;
synthData.voice[i].car = synthData.voice[i].dcar = 0.0f;
synthData.voice[i].mod0 = synthData.voice[i].mod1 = synthData.voice[i].dmod = 0.0f;
synthData.voice[i].cdec = 0.99f; //all notes off
}
synthData.sustain = synthData.activevoices = 0;
lfo0 = dlfo = modwhl = 0.0f;
lfo1 = pbend = 1.0f;
volume = 0.0035f;
K = 0;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DX10Processor::terminate ()
{
return Base::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DX10Processor::setActive (TBool state)
{
return Base::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DX10Processor::setProcessing (TBool state)
{
if (state)
{
synthData.init ();
synthData.clearEvents ();
lfo0 = 0.0f;
lfo1 = 1.0f; //reset LFO phase
}
Base::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void DX10Processor::setParameter (ParamID index, ParamValue newValue, int32 sampleOffset)
{
if (index < NPARAMS)
Base::setParameter (index, newValue, sampleOffset);
else if (index == BaseController::kPresetParam) // program change
{
currentProgram = std::min<int32> (kNumPrograms - 1, (int32)(newValue * kNumPrograms));
const float* newParams = programParams[currentProgram];
if (newParams)
{
for (int32 i = 0; i < NPARAMS; i++)
params[i] = newParams[i];
recalculate ();
}
}
else if (index == BaseController::kModWheelParam) // mod wheel
{
newValue *= 127.;
modwhl = 0.00000005f * (float)(newValue * newValue);
}
else if (index == BaseController::kPitchBendParam) // pitch bend
{
if (newValue <= 1)
pbend = static_cast<float> ((newValue - 0.5) * 0x2000);
else
pbend = static_cast<float> (newValue);
if (pbend>0.0f) pbend = 1.0f + 0.000014951f * pbend;
else pbend = 1.0f + 0.000013318f * pbend;
}
}
//-----------------------------------------------------------------------------
void DX10Processor::setCurrentProgram (Steinberg::uint32 val)
{
if (val < kNumPrograms)
currentProgram = val;
}
//-----------------------------------------------------------------------------
void DX10Processor::setCurrentProgramNormalized (ParamValue val)
{
setCurrentProgram (std::min<int32> (kNumPrograms - 1, (int32)(val * kNumPrograms)));
}
//-----------------------------------------------------------------------------
void DX10Processor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
int32 frame=0, frames, v;
float o, x, e, mw=MW, w=rich, m = modmix;
int32 k=K;
synthData.eventPos = 0;
if (synthData.activevoices>0 || synthData.hasEvents ()) //detect & bypass completely empty blocks
{
while (frame<sampleFrames)
{
frames = synthData.events[synthData.eventPos].sampleOffset;
if (frames>sampleFrames) frames = sampleFrames;
frames -= frame;
frame += frames;
while (--frames>=0) //would be faster with voice loop outside frame loop!
{ //but then each voice would need it's own LFO...
VOICE *V = synthData.voice.data ();
o = 0.0f;
if (--k<0)
{
lfo0 += dlfo * lfo1; //sine LFO
lfo1 -= dlfo * lfo0;
mw = lfo1 * (modwhl + vibrato);
k=100;
}
for(v=0; v<synthData.numVoices; v++) //for each voice
{
e = V->env;
if (e > SILENCE) //**** this is the synth ****
{
V->env = e * V->cdec; //decay & release
V->cenv += V->catt * (e - V->cenv); //attack
x = V->dmod * V->mod0 - V->mod1; //could add more modulator blocks like
V->mod1 = V->mod0; //this for a wider range of FM sounds
V->mod0 = x;
V->menv += V->mdec * (V->mlev - V->menv);
x = V->car + V->dcar + x * V->menv + mw; //carrier phase
while (x > 1.0f) x -= 2.0f; //wrap phase
while (x < -1.0f) x += 2.0f;
V->car = x;
o += V->cenv * (m * V->mod1 + (x + x * x * x * (w * x * x - 1.0f - w)));
} //amp env //mod thru-mix //5th-order sine approximation
/// xx = x * x;
/// x + x + x * xx * (xx - 3.0f);
V++;
}
*out1++ = o;
*out2++ = o;
}
if (frame<sampleFrames) //next note on/off
{
noteEvent (synthData.events[synthData.eventPos]);
++synthData.eventPos;
}
}
synthData.activevoices = synthData.numVoices;
for(v=0; v<synthData.numVoices; v++)
{
if (synthData.voice[v].env < SILENCE) //choke voices that have finished
{
synthData.voice[v].env = synthData.voice[v].cenv = 0.0f;
synthData.activevoices--;
}
if (synthData.voice[v].menv < SILENCE) synthData.voice[v].menv = synthData.voice[v].mlev = 0.0f;
}
}
else //completely empty block
{
memset (out1, 0, sizeof (float) * data.numSamples);
memset (out2, 0, sizeof (float) * data.numSamples);
data.outputs[0].silenceFlags = 3;
}
K=k; MW=mw; //remember these so vibrato speed not buffer size dependent!
}
//-----------------------------------------------------------------------------
void DX10Processor::preProcess ()
{
synthData.clearEvents ();
}
//-----------------------------------------------------------------------------
void DX10Processor::processEvent (const Event& e)
{
synthData.processEvent (e);
}
//-----------------------------------------------------------------------------
void DX10Processor::noteEvent (const Event& event)
{
float l = 1.0f;
int32 v, vl=0;
if (event.type == Event::kNoteOnEvent)
{
auto& note = event.noteOn;
float velocity = note.velocity * 127;
for(v=0; v<synthData.numVoices; v++) //find quietest voice
{
if (synthData.voice[v].env<l) { l=synthData.voice[v].env; vl=v; }
}
l = (float)exp (0.05776226505f * ((float)note.pitch + params[12] + params[12] - 1.0f));
synthData.voice[vl].note = note.pitch; //fine tuning
synthData.voice[vl].car = 0.0f;
synthData.voice[vl].dcar = tune * pbend * l; //pitch bend not updated during note as a bit tricky...
if (l>50.0f) l = 50.0f; //key tracking
l *= (64.0f + velsens * (velocity - 64)); //vel sens
synthData.voice[vl].menv = depth * l;
synthData.voice[vl].mlev = dept2 * l;
synthData.voice[vl].mdec = mdec;
synthData.voice[vl].dmod = ratio * synthData.voice[vl].dcar; //sine oscillator
synthData.voice[vl].mod0 = 0.0f;
synthData.voice[vl].mod1 = (float)sin(synthData.voice[vl].dmod);
synthData.voice[vl].dmod = 2.0f * (float)cos(synthData.voice[vl].dmod);
//scale volume with richness
synthData.voice[vl].env = static_cast<float> ((1.5f - params[13]) * volume * (velocity + 10));
synthData.voice[vl].catt = catt;
synthData.voice[vl].cenv = 0.0f;
synthData.voice[vl].cdec = cdec;
}
else //note off
{
auto& note = event.noteOff;
for(v=0; v<synthData.numVoices; v++) if (synthData.voice[v].note==note.pitch) //any voices playing that note?
{
if (synthData.sustain==0)
{
synthData.voice[v].cdec = crel; //release phase
synthData.voice[v].env = synthData.voice[v].cenv;
synthData.voice[v].catt = 1.0f;
synthData.voice[v].mlev = 0.0f;
synthData.voice[v].mdec = mrel;
}
else synthData.voice[v].note = SustainNoteID;
}
}
}
//-----------------------------------------------------------------------------
void DX10Processor::recalculate ()
{
float ifs = 1.0f / (float)getSampleRate ();
tune = static_cast<float> (8.175798915644 * ifs * pow (2.0, floor(params[11] * 6.9) - 2.0));
rati = static_cast<float> (params[3]);
rati = (float)floor(40.1f * rati * rati);
if (params[4]<0.5f)
ratf = static_cast<float> (0.2f * params[4] * params[4]);
else
switch ((int32)(8.9f * params[4]))
{
case 4: ratf = 0.25f; break;
case 5: ratf = 0.33333333f; break;
case 6: ratf = 0.50f; break;
case 7: ratf = 0.66666667f; break;
default: ratf = 0.75f;
}
ratio = 1.570796326795f * (rati + ratf);
depth = static_cast<float> (0.0002f * params[5] * params[5]);
dept2 = static_cast<float> (0.0002f * params[7] * params[7]);
velsens = static_cast<float> (params[9]);
vibrato = static_cast<float> (0.001f * params[10] * params[10]);
catt = 1.0f - (float)exp (-ifs * exp (8.0 - 8.0 * params[0]));
if (params[1]>0.98f) cdec = 1.0f; else
cdec = (float)exp (-ifs * exp (5.0 - 8.0 * params[1]));
crel = (float)exp (-ifs * exp (5.0 - 5.0 * params[2]));
mdec = 1.0f - (float)exp (-ifs * exp (6.0 - 7.0 * params[6]));
mrel = 1.0f - (float)exp (-ifs * exp (5.0 - 8.0 * params[8]));
rich = static_cast<float> (0.50f - 3.0f * params[13] * params[13]);
//rich = -1.0f + 2 * params[13];
modmix = static_cast<float> (0.25f * params[14] * params[14]);
dlfo = static_cast<float> (628.3f * ifs * 25.0f * params[15] * params[15]); //these params not in original DX10
}
}}} // namespaces
@@ -0,0 +1,119 @@
/*
* mdaDX10Processor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DX10Processor : public BaseProcessor
{
public:
using Base = BaseProcessor;
enum
{
NPARAMS = 16
};
static const int32 kNumPrograms = 32;
DX10Processor ();
~DX10Processor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'MDAx'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
bool hasProgram () const SMTG_OVERRIDE { return true; }
Steinberg::uint32 getCurrentProgram () const SMTG_OVERRIDE { return currentProgram; }
Steinberg::uint32 getNumPrograms () const SMTG_OVERRIDE { return kNumPrograms; }
void setCurrentProgram (Steinberg::uint32 val) SMTG_OVERRIDE;
void setCurrentProgramNormalized (ParamValue val) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new DX10Processor; }
//-----------------------------------------------------------------------------
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653544D, 0x4441786D, 0x64612064, 0x78313000);
#else
inline static DECLARE_UID (uid, 0xF8713648, 0xE2444174, 0x8AAA3B62, 0xA77F9E2D);
#endif
//-----------------------------------------------------------------------------
static float programParams[][NPARAMS];
struct VOICE //voice state
{
float env; //carrier envelope
float dmod; //modulator oscillator
float mod0;
float mod1;
float menv; //modulator envelope
float mlev; //modulator target level
float mdec; //modulator envelope decay
float car; //carrier oscillator
float dcar;
float cenv; //smoothed env
float catt; //smoothing
float cdec; //carrier envelope decay
int32 note; //remember what note triggered this
};
protected:
void checkSilence (ProcessData& /*data*/) SMTG_OVERRIDE {}
void setParameter (ParamID index, ParamValue newValue, int32 sampleOffset) SMTG_OVERRIDE;
void preProcess () SMTG_OVERRIDE;
void processEvent (const Event& event) SMTG_OVERRIDE;
void recalculate () SMTG_OVERRIDE;
void noteEvent (const Event& event);
float Fs;
static constexpr int32 kNumVoices = 8;
static constexpr int32 kEventBufferSize = 64;
using SynthDataT = SynthData<VOICE, kEventBufferSize, kNumVoices>;
SynthDataT synthData;
///global internal variables
int32 K;
float tune, rati, ratf, ratio; //modulator ratio
float catt, cdec, crel; //carrier envelope
float depth, dept2, mdec, mrel; //modulator envelope
float lfo0, lfo1, dlfo, modwhl, MW, pbend, velsens, volume, vibrato; //LFO and CC
float rich, modmix;
Steinberg::uint32 currentProgram;
};
}}} // namespaces
@@ -0,0 +1,60 @@
/*
* mdaDeEsserController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDeEsserController.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DeEsserController::DeEsserController ()
{
}
//-----------------------------------------------------------------------------
DeEsserController::~DeEsserController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DeEsserController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
parameters.addParameter (new ScaledParameter (USTRING("Thresh"), USTRING("dB"), 0, 0.15, ParameterInfo::kCanAutomate, kParam0, -60, 60, true));
parameters.addParameter (new ScaledParameter (USTRING("Freq"), USTRING("Hz"), 0, 0.6, ParameterInfo::kCanAutomate, kParam1, 1000, 11100, true));
parameters.addParameter (new ScaledParameter (USTRING("HF Drive"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam2, -20, 20, true));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DeEsserController::terminate ()
{
return BaseController::terminate ();
}
}}} // namespaces
@@ -0,0 +1,61 @@
/*
* mdaDeEsserController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaDeEsserProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DeEsserController : public BaseController
{
public:
DeEsserController ();
~DeEsserController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new DeEsserController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461736D, 0x64612064, 0x652D6573);
#else
inline static DECLARE_UID (uid, 0x370BA963, 0xE2D54BF8, 0x8D6838FA, 0x1567C8DD);
#endif
};
}}} // namespaces
@@ -0,0 +1,139 @@
/*
* mdaDeEsserProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDeEsserProcessor.h"
#include "mdaDeEsserController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DeEsserProcessor::DeEsserProcessor ()
{
setControllerClass (DeEsserController::uid);
allocParameters (3);
}
//-----------------------------------------------------------------------------
DeEsserProcessor::~DeEsserProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DeEsserProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.15; //thresh
params[1] = 0.60; //f
params[2] = 0.50; //drive
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DeEsserProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DeEsserProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DeEsserProcessor::setProcessing (TBool state)
{
if (state)
{
env = 0.f;
fbuf1 = fbuf2 = 0;
}
BaseProcessor::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void DeEsserProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b;
float f1=fbuf1, f2=fbuf2, tmp, fi=fil, fo= (1.f-fil);
float at=att, re=rel, en=env, th=thr, g, gg=gai;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
tmp = 0.5f * (a + b); //2nd order crossover
f1 = fo * f1 + fi * tmp;
tmp -= f1;
f2 = fo * f2 + fi * tmp;
tmp = gg*(tmp - f2); //extra HF gain
en= (tmp>en)? en+at*(tmp-en) : en*re; //envelope
if (en>th) g=f1+f2+tmp*(th/en); else g=f1+f2+tmp; //limit
//brackets for full-band!!!
*++out1 = g;
*++out2 = g;
}
if (fabs (f1) < 1.0e-10) {fbuf1=0.f; fbuf2=0.f;} else {fbuf1=f1; fbuf2=f2;}
if (fabs (en) < 1.0e-10) env=0.f; else env=en;
}
//-----------------------------------------------------------------------------
void DeEsserProcessor::recalculate ()
{
thr= (float)pow (10.0f, (float)(3.f * params[0] - 3.f));
att=0.01f;
rel=0.992f;
fil= static_cast<float> (0.05f + 0.94f * params[1] * params[1]);
gai= (float)pow (10.0f, (float)(2.f * params[2] - 1.f));
}
}}} // namespaces
@@ -0,0 +1,65 @@
/*
* mdaDeEsserProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DeEsserProcessor : public BaseProcessor
{
public:
DeEsserProcessor ();
~DeEsserProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdas'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new DeEsserProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461736D, 0x64612064, 0x652D6573);
#else
inline static DECLARE_UID (uid, 0x174FD6D1, 0x856E4641, 0xBFB9851A, 0x1C544725);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float fbuf1, fbuf2, gai;
float thr, att, rel, env, fil;
};
}}} // namespaces
@@ -0,0 +1,128 @@
/*
* mdaDegradeController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDegradeController.h"
#include "mdaDegradeController.h"
#include "pluginterfaces/base/ibstream.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DegradeController::DegradeController ()
{
}
//-----------------------------------------------------------------------------
DegradeController::~DegradeController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DegradeController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
parameters.addParameter (USTRING("Headroom"), USTRING("dB"), 0, 0.8, ParameterInfo::kCanAutomate, kParam0);
parameters.addParameter (new ScaledParameter (USTRING("Quant"), USTRING("bits"), 0, 0.5, ParameterInfo::kCanAutomate, kParam1, 4, 16, true));
parameters.addParameter (USTRING("Rate"), USTRING("S<>S&&H"), 0, 0.65, ParameterInfo::kCanAutomate, kParam2);
parameters.addParameter (USTRING("PostFilt"), USTRING("Hz"), 0, 0.9, ParameterInfo::kCanAutomate, kParam3);
parameters.addParameter (USTRING("Non-Lin"), USTRING("Odd<>Eve"), 0, 0.58, ParameterInfo::kCanAutomate, kParam4);
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam5, -20, 20, true));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DegradeController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DegradeController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case kParam0:
{
result.printInt (static_cast<int64> (-30 * (1 - valueNormalized)));
break;
}
case kParam2:
{
float f;
int tn;
if (valueNormalized > 0.5)
{
f = static_cast<float> (valueNormalized - 0.5f);
}
else
{
f = static_cast<float> (0.5f - valueNormalized);
}
tn = (int)exp (18.0f * f);
result.printInt (static_cast<int64> (sampleRate / tn));
break;
}
case kParam3:
{
result.printInt (static_cast<int64> (pow (10.0f, (float)(2.30104f + 2.f * valueNormalized))));
break;
}
case kParam4:
{
result.printInt (static_cast<int64> (200.0 * fabs (valueNormalized - 0.5)));
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DegradeController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
// TODO
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,67 @@
/*
* mdaDegradeController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaDegradeProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DegradeController : public BaseController
{
public:
DegradeController ();
~DegradeController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new DegradeController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461436D, 0x64612064, 0x65677261);
#else
inline static DECLARE_UID (uid, 0x2C3AC40E, 0xA7754992, 0x87FE2BD7, 0x77829B03);
#endif
};
}}} // namespaces
@@ -0,0 +1,182 @@
/*
* mdaDegradeProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDegradeProcessor.h"
#include "mdaDegradeController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DegradeProcessor::DegradeProcessor ()
{
setControllerClass (DegradeController::uid);
allocParameters (6);
}
//-----------------------------------------------------------------------------
DegradeProcessor::~DegradeProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DegradeProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.8; //clip
params[1] = 0.50; //bits
params[2] = 0.65; //rate
params[3] = 0.9; //postfilt
params[4] = 0.58; //non-lin
params[5] = 0.5; //level
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DegradeProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DegradeProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DegradeProcessor::setProcessing (TBool state)
{
if (state)
{
buf0 = buf1 = buf2 = buf3 = buf4 = buf5 = buf6 = buf7 = buf8 = buf9 = 0.0f;
}
BaseProcessor::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void DegradeProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float b0=buf0, l=lin, l2=lin2;
float cl=clp, i2=fi2, o2=fo2;
float b1=buf1, b2=buf2, b3=buf3, b4=buf4, b5=buf5;
float b6=buf6, b7=buf7, b8=buf8, b9=buf9;
float gi=g1, go=g2, ga=g3, m = mode;
int n=tn, t=tcount;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
b0 = (*++in1 + *++in2) + m * b0;
if (t==n)
{
t=0;
b5 = (float)(go * int (b0 * gi));
if (b5>0)
{ b5= (float)pow (b5,l2); if (b5>cl) b5=cl;}
else
{ b5=-(float)pow (-b5,l); if (b5<-cl) b5=-cl; }
b0=0;
}
t=t+1;
b1 = i2 * (b5 * ga) + o2 * b1;
b2 = b1 + o2 * b2;
b3 = b2 + o2 * b3;
b4 = b3 + o2 * b4;
b6 = i2 * b4 + o2 * b6;
b7 = b6 + o2 * b7;
b8 = b7 + o2 * b8;
b9 = b8 + o2 * b9;
*++out1 = b9;
*++out2 = b9;
}
if (fabs (b1) < 1.0e-10)
{ buf1=0.f; buf2=0.f; buf3=0.f; buf4=0.f; buf6=0.f; buf7=0.f;
buf8=0.f; buf9=0.f; buf0=0.f; buf5=0.f; }
else
{ buf1=b1; buf2=b2; buf3=b3; buf4=b4; buf6=b6; buf7=b7;
buf8=b8, buf9=b9; buf0=b0; buf5=b5; tcount=t; }
}
//-----------------------------------------------------------------------------
float DegradeProcessor::filterFreq(float hz)
{
float j, k, r=0.999f;
j = r * r - 1;
k = (float)(2.f - 2.f * r * r * cos(0.647f * hz / getSampleRate () ));
return (float)((sqrt (k*k - 4.f*j*j) - k) / (2.f*j));
}
//-----------------------------------------------------------------------------
void DegradeProcessor::recalculate ()
{
float f;
if (params[2]>0.5) { f = (float)params[2] - 0.5f; mode = 1.0f; }
else { f = 0.5f - (float)params[2]; mode = 0.0f; }
tn = (int)exp (18.0f * f);
//tn = (int)(18.0 * params[3 - 8.0); mode=1.f; }
// else { tn = (int)(10.0 - 18.0 * params[3); mode=0.f; }
tcount = 1;
clp = (float)(pow (10.0,(-1.5 + 1.5 * params[0])) );
fo2 = filterFreq((float)pow (10.0f, (float)(2.30104f + 2.f*params[3])));
fi2 = (1.f-fo2); fi2=fi2*fi2; fi2=fi2*fi2;
float _g1 = (float)(pow (2.0,2.0 + int (params[1]*12.0)));
g2 = (float)(1.0/(2.0 * _g1));
if (params[2]>0.5) g1 = -_g1/(float)tn; else g1= -_g1;
g3 = (float)(pow (10.0,2.0*params[5] - 1.0));
if (params[4]>0.5) { lin = (float)(pow (10.0,0.3 * (0.5 - params[4]))); lin2=lin; }
else { lin = (float)pow (10.0,0.3 * (params[4] - 0.5)); lin2=1.0; }
}
}}} // namespaces
@@ -0,0 +1,67 @@
/*
* mdaDegradeProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DegradeProcessor : public BaseProcessor
{
public:
DegradeProcessor ();
~DegradeProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaC'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new DegradeProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461436D, 0x64612064, 0x65677261);
#else
inline static DECLARE_UID (uid, 0xD31333A7, 0xA34E4690, 0xA279A0B0, 0x6C91BB85);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float filterFreq(float hz);
float fi2, fo2, clp, lin, lin2, g1, g2, g3, mode;
float buf0, buf1, buf2, buf3, buf4, buf5, buf6, buf7, buf8, buf9;
int tn, tcount;
};
}}} // namespaces
@@ -0,0 +1,133 @@
/*
* mdaDelayController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDelayController.h"
#include "pluginterfaces/base/ibstream.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DelayController::DelayController ()
{
}
//-----------------------------------------------------------------------------
DelayController::~DelayController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DelayController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
parameters.addParameter (USTRING("L Delay"), USTRING("ms"), 0, 0.5, ParameterInfo::kCanAutomate, kParam0);
parameters.addParameter (USTRING("R Delay"), USTRING("%"), 0, 0.27, ParameterInfo::kCanAutomate, kParam1);
parameters.addParameter (new ScaledParameter (USTRING("Feedback"), USTRING("%"), 0, 0.7, ParameterInfo::kCanAutomate, kParam2, 0, 99, true));
parameters.addParameter (new ScaledParameter (USTRING("Fb Tone"), USTRING("Lo <> Hi"), 0, 0.5, ParameterInfo::kCanAutomate, kParam3, -100, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Fb Mix"), USTRING("%"), 0, 0.33, ParameterInfo::kCanAutomate, kParam4, 0, 100, true));
parameters.addParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam5);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DelayController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DelayController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case kParam0:
{
int ldel = (int32)(32766 * valueNormalized * valueNormalized);
if (ldel<4) ldel=4;
result.printInt (static_cast<int64> (ldel * 1000. / sampleRate));
break;
}
case kParam1:
{
int ldel = (int32)(32766 * valueNormalized * valueNormalized);
if (ldel<4) ldel=4;
float tmp;
switch (int (valueNormalized * 17.9f)) //fixed left/right ratios
{
case 17: tmp = 0.5000f; break;
case 16: tmp = 0.6667f; break;
case 15: tmp = 0.7500f; break;
case 14: tmp = 0.8333f; break;
case 13: tmp = 1.0000f; break;
case 12: tmp = 1.2000f; break;
case 11: tmp = 1.3333f; break;
case 10: tmp = 1.5000f; break;
case 9: tmp = 2.0000f; break;
default: tmp = static_cast<float> (4.0f * valueNormalized); break; //variable ratio
}
int rdel = (int32)(32766 * valueNormalized * valueNormalized * tmp);
if (rdel>32766) rdel=32766;
if (rdel<4) rdel=4;
result.printInt (100 * rdel / ldel);
break;
}
case kParam5:
{
if (valueNormalized == 0)
result.fromAscii ("oo");
else
result.printFloat (20 * log10(2.0 * valueNormalized), 2);
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DelayController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,67 @@
/*
* mdaDelayController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaDelayProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DelayController : public BaseController
{
public:
DelayController ();
~DelayController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new DelayController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461796D, 0x64612064, 0x656C6179);
#else
inline static DECLARE_UID (uid, 0xF9AB9778, 0xEF1943F2, 0x86F911A3, 0x50C7AACB);
#endif
};
}}} // namespaces
@@ -0,0 +1,189 @@
/*
* mdaDelayProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDelayProcessor.h"
#include "mdaDelayController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DelayProcessor::DelayProcessor ()
: buffer(nullptr)
{
setControllerClass (DelayController::uid);
allocParameters (7);
}
//-----------------------------------------------------------------------------
DelayProcessor::~DelayProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DelayProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.50f; //left delay
params[1] = 0.27f; //right ratio
params[2] = 0.70f; //feedback
params[3] = 0.50f; //tone
params[4] = 0.33f; //wet mix
params[5] = 0.50f; //output
size = 32766; //set max delay time at max sample rate
buffer = new float[size + 2]; //spare just in case!
ipos = 0;
fil0 = 0.0f;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DelayProcessor::terminate ()
{
if (buffer) delete [] buffer;
buffer = nullptr;
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DelayProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DelayProcessor::setProcessing (TBool state)
{
if (state)
{
memset (buffer, 0, size * sizeof (float));
ipos = 0;
}
return kResultOk;
}
//-----------------------------------------------------------------------------
void DelayProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, ol, or_, w=wet, y =dry, fb=fbk;
float lx=lmix, hx=hmix, f=fil, f0=fil0, tmp;
int32 i=ipos, l, r, s=size;
l = (i + ldel) % (s + 1);
r = (i + rdel) % (s + 1);
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
ol = *(buffer + l); //delay outputs
or_ = *(buffer + r);
tmp = w * (a + b) + fb * (ol + or_); //mix input & feedback
f0 = f * (f0 - tmp) + tmp; //low-pass filter
*(buffer + i) = lx * f0 + hx * tmp; //delay input
i--; if (i<0) i=s;
l--; if (l<0) l=s;
r--; if (r<0) r=s;
*++out1 = y * a + ol; //mix wet & dry
*++out2 = y * b + or_;
}
ipos = i;
if (fabs (f0) < 1.0e-10) fil0=0.0f; else fil0=f0; //trap denormals
}
//-----------------------------------------------------------------------------
void DelayProcessor::recalculate ()
{
float tmp;
ldel = (int32)(size * params[0] * params[0]);
if (ldel<4) ldel=4;
switch (int (params[1] * 17.9f)) //fixed left/right ratios
{
case 17: tmp = 0.5000f; break;
case 16: tmp = 0.6667f; break;
case 15: tmp = 0.7500f; break;
case 14: tmp = 0.8333f; break;
case 13: tmp = 1.0000f; break;
case 12: tmp = 1.2000f; break;
case 11: tmp = 1.3333f; break;
case 10: tmp = 1.5000f; break;
case 9: tmp = 2.0000f; break;
default: tmp = static_cast<float> (4.0f * params[1]); break; //variable ratio
}
rdel = (int32)(size * params[0] * params[0] * tmp);
if (rdel>size) rdel=size;
if (rdel<4) rdel=4;
fil = static_cast<float> (params[3]);
if (params[3]>0.5f) //simultaneously change crossover frequency & high/low mix
{
fil = 0.5f * fil - 0.25f;
lmix = -2.0f * fil;
hmix = 1.0f;
}
else
{
hmix = 2.0f * fil;
lmix = 1.0f - hmix;
}
fil = (float)exp (-6.2831853f * pow (10.0f, 2.2f + 4.5f * fil) / getSampleRate ());
fbk = static_cast<float> (0.495f * params[2]);
wet = static_cast<float> (1.0f - params[4]);
wet = static_cast<float> (params[5] * (1.0f - wet * wet)); //-3dB at 50% mix
dry = static_cast<float> (params[5] * 2.0f * (1.0f - params[4] * params[4]));
}
}}} // namespaces
@@ -0,0 +1,66 @@
/*
* mdaDelayProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DelayProcessor : public BaseProcessor
{
public:
DelayProcessor ();
~DelayProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mday'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new DelayProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461796D, 0x64612064, 0x656C6179);
#else
inline static DECLARE_UID (uid, 0xE5041336, 0xE9434B28, 0xB7B01267, 0x95F0C32F);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float *buffer; //delay
int32 size, ipos, ldel, rdel; //delay max time, pointer, left time, right time
float wet, dry, fbk; //wet & dry mix
float lmix, hmix, fil, fil0; //low & high mix, crossover filter coeff & buffer
};
}}} // namespaces
@@ -0,0 +1,106 @@
/*
* mdaDetuneController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDetuneController.h"
#include "mdaDetuneController.h"
#include "pluginterfaces/base/ibstream.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DetuneController::DetuneController ()
{
}
//-----------------------------------------------------------------------------
DetuneController::~DetuneController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DetuneController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
parameters.addParameter (USTRING("Detune"), USTRING("cents"), 0, 0.4, ParameterInfo::kCanAutomate, kParam0);
parameters.addParameter (new ScaledParameter (USTRING("Mix"), USTRING("%"), 0, 0.4, ParameterInfo::kCanAutomate, kParam1, 0, 99));
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam2, -20, 20));
parameters.addParameter (USTRING("Latency"), USTRING("ms"), 0, 0.5, ParameterInfo::kCanAutomate, kParam3);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DetuneController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DetuneController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
return BaseController::getParamStringByValue (tag, valueNormalized, string);
/*
UString128 result;
switch (tag)
{
#if 0
case kParam3:
{
result.printFloat (bufres);
break;
}
case kParam0:
{
result.printFloat (100*semi);
break;
}
#endif
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;*/
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DetuneController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,65 @@
/*
* mdaDetuneController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaDetuneProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DetuneController : public BaseController
{
public:
DetuneController ();
~DetuneController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new DetuneController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461746D, 0x64612064, 0x6574756E);
#else
inline static DECLARE_UID (uid, 0xCE5E213E, 0xE1B74D02, 0x92FF66C6, 0x3DCF27C8);
#endif
};
}}} // namespaces
@@ -0,0 +1,203 @@
/*
* mdaDetuneProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDetuneProcessor.h"
#include "mdaDetuneController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
#define BUFMAX 4096
//-----------------------------------------------------------------------------
DetuneProcessor::DetuneProcessor ()
{
setControllerClass (DetuneController::uid);
allocParameters (4);
buf=win=nullptr;
}
//-----------------------------------------------------------------------------
DetuneProcessor::~DetuneProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DetuneProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.40f; //fine
params[1] = 0.40f; //mix
params[2] = 0.50f; //output
params[3] = 0.50f; //chunksize
buf = new float[BUFMAX];
win = new float[BUFMAX];
buflen=0;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DetuneProcessor::terminate ()
{
if (buf) delete [] buf;
if (win) delete [] win;
buf=win=nullptr;
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DetuneProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DetuneProcessor::setProcessing (TBool state)
{
if (state)
{
memset (buf, 0, BUFMAX * sizeof (float));
pos0 = 0; pos1 = pos2 = 0.0f;
}
BaseProcessor::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void DetuneProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, c, d;
float x, w=wet, y =dry, p1=pos1, p1f, d1=dpos1;
float p2=pos2, d2=dpos2;
int32 p0=pos0, p1i, p2i;
int32 l=buflen-1, lh=buflen>>1;
float lf = (float)buflen;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0) //had to disable optimization /Og in MSVC++5!
{
a = *++in1;
b = *++in2;
c = y * a;
d = y * b;
--p0 &= l;
*(buf + p0) = w * (a + b); //input
p1 -= d1;
if (p1<0.0f) p1 += lf; //output
p1i = (int32)p1;
p1f = p1 - (float)p1i;
a = *(buf + p1i);
++p1i &= l;
a += p1f * (*(buf + p1i) - a); //linear interpolation
p2i = (p1i + lh) & l; //180-degree ouptut
b = *(buf + p2i);
++p2i &= l;
b += p1f * (*(buf + p2i) - b); //linear interpolation
p2i = (p1i - p0) & l; //crossfade
x = *(win + p2i);
//++p2i &= l;
//x += p1f * (*(win + p2i) - x); //linear interpolation (doesn't do much)
c += b + x * (a - b);
p2 -= d2; //repeat for downwards shift - can't see a more efficient way?
if (p2<0.0f) p2 += lf; //output
p1i = (int32)p2;
p1f = p2 - (float)p1i;
a = *(buf + p1i);
++p1i &= l;
a += p1f * (*(buf + p1i) - a); //linear interpolation
p2i = (p1i + lh) & l; //180-degree ouptut
b = *(buf + p2i);
++p2i &= l;
b += p1f * (*(buf + p2i) - b); //linear interpolation
p2i = (p1i - p0) & l; //crossfade
x = *(win + p2i);
//++p2i &= l;
//x += p1f * (*(win + p2i) - x); //linear interpolation (doesn't do much)
d += b + x * (a - b);
*++out1 = c;
*++out2 = d;
}
pos0=p0; pos1=p1; pos2=p2;
}
//-----------------------------------------------------------------------------
void DetuneProcessor::recalculate ()
{
int32 tmp;
semi = static_cast<float> (3.0f * params[0] * params[0] * params[0]);
dpos2 = powf (1.0594631f, semi);
dpos1 = 1.0f / dpos2;
wet = powf (10.0f, static_cast<float> (2.0f * params[2] - 1.0f));
dry = static_cast<float> (wet - wet * params[1] * params[1]);
wet = static_cast<float> ((wet + wet - wet * params[1]) * params[1]);
tmp = 1 << (8 + (int32)(4.9f * params[3]));
if (tmp!=buflen) //recalculate crossfade window
{
buflen = tmp;
bufres = static_cast<float> (1000.0f * buflen / getSampleRate ());
int32 i; //hanning half-overlap-and-add
double p=0.0, dp=6.28318530718/buflen;
for(i = 0;i<buflen;i++) { win[i] = (float)(0.5 - 0.5 * cos(p)); p+=dp; }
}
}
}}} // namespaces
@@ -0,0 +1,71 @@
/*
* mdaDetuneProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DetuneProcessor : public BaseProcessor
{
public:
DetuneProcessor ();
~DetuneProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdat'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new DetuneProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461746D, 0x64612064, 0x6574756E);
#else
inline static DECLARE_UID (uid, 0x4CCBED11, 0xE28346A6, 0xA91EC86C, 0x9E85EDF8);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float *buf, *win; //buffer, window
int32 buflen; //buffer length
float bufres; //buffer resolution display
float semi; //detune display
int32 pos0; //buffer input
float pos1, dpos1; //buffer output, rate
float pos2, dpos2; //downwards shift
float wet, dry; //ouput levels
};
}}} // namespaces
@@ -0,0 +1,102 @@
/*
* dmaDitherController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDitherController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DitherController::DitherController ()
{
}
//-----------------------------------------------------------------------------
DitherController::~DitherController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DitherController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
parameters.addParameter (USTRING("Word Len"), USTRING("Bits"), 0, 0.15, ParameterInfo::kCanAutomate, kParam0);
auto* ditherParam = new IndexedParameter (USTRING("Dither"), USTRING(""), 3, 0.3, ParameterInfo::kCanAutomate | ParameterInfo::kIsList, kParam1);
ditherParam->setIndexString (0, UString128("OFF"));
ditherParam->setIndexString (1, UString128("TRI"));
ditherParam->setIndexString (2, UString128("HP-TRI"));
ditherParam->setIndexString (3, UString128("N.SHAPE"));
parameters.addParameter (ditherParam);
parameters.addParameter (new ScaledParameter (USTRING("Dith Amp"), USTRING("lsb"), 0, 0.5, ParameterInfo::kCanAutomate, kParam2, 0, 4));
parameters.addParameter (new ScaledParameter (USTRING("DC Trim"), USTRING("lsb"), 0, 0.5, ParameterInfo::kCanAutomate, kParam3, -2, 2));
parameters.addParameter (new ScaledParameter (USTRING("Zoom"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam4, -2, 2));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DitherController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DitherController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case kParam0:
{
result.printInt (static_cast<int64> (8.0f + 2.0f * (float)floor(8.9f * valueNormalized)));
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DitherController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
// TODO
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,66 @@
/*
* dmaDitherController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaDitherProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DitherController : public BaseController
{
public:
DitherController ();
~DitherController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new DitherController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461646D, 0x64612064, 0x69746865);
#else
inline static DECLARE_UID (uid, 0xE54A7007, 0x068149B4, 0xAEAF955C, 0x54760DBF);
#endif
};
}}} // namespaces
@@ -0,0 +1,168 @@
/*
* dmaDitherProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDitherProcessor.h"
#include "mdaDitherController.h"
#include <cmath>
#include <cstdlib>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DitherProcessor::DitherProcessor ()
{
setControllerClass (DitherController::uid);
allocParameters (5);
}
//-----------------------------------------------------------------------------
DitherProcessor::~DitherProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DitherProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.50f; //bits
params[1] = 0.88f; //dither (off, rect, tri, hp-tri, hp-tri-2ndOrderShaped)
params[2] = 0.50f; //dither level
params[3] = 0.50f; //dc trim
params[4] = 0.00f; //zoom (8 bit dither and fade audio out)
sh1 = sh2 = sh3 = sh4 = 0.0f;
rnd1 = rnd3 = 0;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DitherProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DitherProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
void DitherProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, aa, bb;
float sl=shap, s1=sh1, s2=sh2, s3=sh3, s4=sh4; //shaping level, buffers
float dl=dith; //dither level
float o = offs, w=wlen, wi = 1.0f/wlen; //DC offset, word length & inverse
float g=gain; //gain for Zoom mode
int32 r1=rnd1, r2, r3=rnd3, r4; //random numbers for dither
int32 m=1; //dither mode
if ((int32)(params[1] * 3)==1) m=0; //what is the fastest if (?)
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
r2=r1; r4=r3; //HP-TRI dither (also used when noise shaping)
if (m==0) { r4=rand() & 0x7FFF; r2= (r4 & 0x7F)<<8; } //TRI dither
r1=rand() & 0x7FFF; r3= (r1 & 0x7F)<<8; //Assumes RAND_MAX=32767?
a = g * a + sl * (s1 + s1 - s2); //target level + error feedback
aa = a + o + dl * (float)(r1 - r2); // + offset + dither
if (aa<0.0f) aa-=wi; //(int32) truncates towards zero!
aa = wi * (float)(int32)(w * aa); //truncate
s2 = s1;
s1 = a - aa; //error feedback: 2nd order noise shaping
b = g * b + sl * (s3 + s3 - s4);
bb = b + o + dl * (float)(r3 - r4);
if (bb<0.0f) bb-=wi;
bb = wi * (float)(int32)(w * bb);
s4 = s3;
s3 = b - bb;
*++out1 = aa;
*++out2 = bb;
}
sh1=s1; sh2=s2; sh3=s3; sh4=s4; //doesn't actually matter if these are
rnd1=r1; rnd3=r3; //saved or not as effect is so small !
}
//-----------------------------------------------------------------------------
void DitherProcessor::recalculate ()
{
gain = 1.0f;
bits = 8.0f + 2.0f * (float)floor(8.9f * params[0]);
if (params[4]>0.1f) //zoom to 6 bit & fade out audio
{
wlen = 32.0f;
gain = static_cast<float> ((1.0f - params[4]));
gain*=gain;
}
else wlen = (float)pow (2.0f, bits - 1.0f); //word length in quanta
//Using WaveLab 2.01 (unity gain) as a reference:
// 16-bit output is (int)floor(floating_point_value*32768.0f)
offs = static_cast<float> ((4.0f * params[3] - 1.5f) / wlen); //DC offset (plus 0.5 to round dither not truncate)
dith = static_cast<float> (2.0f * params[2] / (wlen * (float)32767));
shap=0.0f;
switch ((int32)(params[1]*3)) //dither mode
{
case 0: dith = 0.0f; break; //off
case 3: shap = 0.5f; break; //noise shaping
default: break; //tri, hp-tri
}
}
}}} // namespaces
@@ -0,0 +1,66 @@
/*
* dmaDitherProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DitherProcessor : public BaseProcessor
{
public:
DitherProcessor ();
~DitherProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdad'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new DitherProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461646D, 0x64612064, 0x69746865);
#else
inline static DECLARE_UID (uid, 0xA155F267, 0xA6954095, 0xAFD8BFB1, 0x9E4F2293);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float dith;
int32 rnd1, rnd3;
float shap, sh1, sh2, sh3, sh4;
float offs, bits, wlen, gain;
};
}}} // namespaces
@@ -0,0 +1,108 @@
/*
* mdaDubDelayController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDubDelayController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DubDelayController::DubDelayController ()
{
}
//-----------------------------------------------------------------------------
DubDelayController::~DubDelayController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DubDelayController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
parameters.addParameter (USTRING("Delay"), USTRING("ms"), 0, 0.3, ParameterInfo::kCanAutomate, kParam0);
parameters.addParameter (new ScaledParameter (USTRING("Feedback"), USTRING("Sat<>Lim"), 0, 0.7, ParameterInfo::kCanAutomate, kParam1, -110, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Fb Tone"), USTRING("Lo <> Hi"), 0, 0.4, ParameterInfo::kCanAutomate, kParam2, -100, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("LFO Dep."), USTRING("%"), 0, 0.0, ParameterInfo::kCanAutomate, kParam3, 0, 100, true));
parameters.addParameter (USTRING("LFO Rate"), USTRING("sec."), 0, 0.5, ParameterInfo::kCanAutomate, kParam4);
parameters.addParameter (new ScaledParameter (USTRING("FX Mix"), USTRING("%"), 0, 0.33, ParameterInfo::kCanAutomate, kParam5, 0, 100, true));
parameters.addParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam6);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DubDelayController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DubDelayController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case kParam0:
{
result.printInt (static_cast<int64> ((valueNormalized*valueNormalized*323766) * 1000. / sampleRate));
break;
}
case kParam4:
{
result.printFloat (pow (10.0f, (float)(2.0f - 3.0f * valueNormalized)), 2);
break;
}
case kParam6:
{
result.printFloat (20 * log10(2.0 * valueNormalized), 2);
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DubDelayController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;
*/
}
}}} // namespaces
@@ -0,0 +1,70 @@
/*
* mdaDubDelayController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaDubDelayProcessor.h"
using namespace Steinberg::Vst;
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DubDelayController : public BaseController
{
public:
DubDelayController ();
~DubDelayController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kParam6,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new DubDelayController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461626D, 0x64612064, 0x75626465);
#else
inline static DECLARE_UID (uid, 0x812A9763, 0xA27F4D74, 0x8A272139, 0x6F1D35BB);
#endif
};
}}} // namespaces
@@ -0,0 +1,209 @@
/*
* mdaDubDelayProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDubDelayProcessor.h"
#include "mdaDubDelayController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DubDelayProcessor::DubDelayProcessor ()
{
setControllerClass (DubDelayController::uid);
allocParameters (7);
}
//-----------------------------------------------------------------------------
DubDelayProcessor::~DubDelayProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DubDelayProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.30f; //delay
params[1] = 0.70f; //feedback
params[2] = 0.40f; //tone
params[3] = 0.00f; //lfo depth
params[4] = 0.50f; //lfo speed
params[5] = 0.33f; //wet mix
params[6] = 0.50f; //output
///CHANGED///too long?
size = 323766; //705600; //95998; //32766; //set max delay time at max sample rate
buffer = new float[size + 2]; //spare just in case!
memset (buffer, 0, sizeof (float) * (size + 2));
ipos = 0;
fil0 = 0.0f;
env = 0.0f;
phi = 0.0f;
dlbuf= 0.0f;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DubDelayProcessor::terminate ()
{
if (buffer) delete [] buffer;
buffer = nullptr;
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DubDelayProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DubDelayProcessor::setProcessing (TBool state)
{
if (state)
{
memset (buffer, 0, size * sizeof (float));
ipos = 0;
fil0 = 0.0f;
env = 0.0f;
phi = 0.0f;
dlbuf = 0.0f;
}
BaseProcessor::setProcessing (state);
return kResultOk;
}
//-----------------------------------------------------------------------------
void DubDelayProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, ol, w=wet, y =dry, fb=fbk, dl=dlbuf, db=dlbuf, ddl=0.0f;
float lx=lmix, hx=hmix, f=fil, f0=fil0, tmp;
float e=env, g, r = rel; //limiter envelope, gain, release
float twopi=6.2831853f;
int32 i=ipos, l, s=size, k=0;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
if (k==0) //update delay length at slower rate (could be improved!)
{
db += 0.01f * (del - db - mod - mod * (float)sin(phi)); //smoothed delay+lfo
ddl = 0.01f * (db - dl); //linear step
phi+=dphi; if (phi>twopi) phi-=twopi;
k=100;
}
k--;
dl += ddl; //lin interp between points
i--; if (i<0) i=s; //delay positions
l = (int32)dl;
tmp = dl - (float)l; //remainder
l += i; if (l>s) l-= (s+1);
ol = *(buffer + l); //delay output
l++; if (l>s) l=0;
ol += tmp * (*(buffer + l) - ol); //lin interp
tmp = a + fb * ol; //mix input (left only!) & feedback
f0 = f * (f0 - tmp) + tmp; //low-pass filter
tmp = lx * f0 + hx * tmp;
g = (tmp<0.0f)? -tmp : tmp; //simple limiter
e *= r; if (g>e) e = g;
if (e>1.0f) tmp /= e;
*(buffer + i) = tmp; //delay input
ol *= w; //wet
*++out1 = y * a + ol; //dry
*++out2 = y * b + ol;
}
ipos = i;
dlbuf=dl;
if (fabs (f0) < 1.0e-10) { fil0=0.0f; env=0.0f; } else { fil0=f0; env=e; } //trap denormals
}
//-----------------------------------------------------------------------------
void DubDelayProcessor::recalculate ()
{
float fs=(float)getSampleRate ();
///CHANGED///del = fParam0 * fParam0 * fParam0 * (float)size;
del = static_cast<float> (params[0] * params[0] * (float)size);
mod = static_cast<float> (0.049f * params[3] * del);
fil = static_cast<float> (params[2]);
if (params[2]>0.5f) //simultaneously change crossover frequency & high/low mix
{
fil = 0.5f * fil - 0.25f;
lmix = -2.0f * fil;
hmix = 1.0f;
}
else
{
hmix = 2.0f * fil;
lmix = 1.0f - hmix;
}
fil = (float)exp (-6.2831853f * pow (10.0f, 2.2f + 4.5f * fil) / fs);
fbk = (float)fabs (2.2f * params[1] - 1.1f);
if (params[1]>0.5f) rel=0.9997f; else rel=0.8f; //limit or clip
wet = static_cast<float> (1.0f - params[5]);
wet = static_cast<float> (params[6] * (1.0f - wet * wet)); //-3dB at 50% mix
dry = static_cast<float> (params[6] * 2.0f * (1.0f - params[5] * params[5]));
dphi = 628.31853f * (float)pow (10.0f, (float)(3.0f * params[4] - 2.0f)) / fs; //100-sample steps
}
}}} // namespaces
@@ -0,0 +1,70 @@
/*
* mdaDubDelayProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DubDelayProcessor : public BaseProcessor
{
public:
DubDelayProcessor ();
~DubDelayProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdab'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new DubDelayProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461626D, 0x64612064, 0x75626465);
#else
inline static DECLARE_UID (uid, 0xA49D1232, 0x24794649, 0xA57337B4, 0xDDC5041C);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float *buffer; //delay
int32 size, ipos; //delay max time, pointer, left time, right time
float wet, dry, fbk; //wet & dry mix
float lmix, hmix, fil, fil0; //low & high mix, crossover filter coeff & buffer
float env, rel; //limiter (clipper when release is instant)
float del, mod, phi, dphi; //lfo
float dlbuf; //smoothed modulated delay
};
}}} // namespaces
@@ -0,0 +1,103 @@
/*
* mdaDynamicsController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDynamicsController.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DynamicsController::DynamicsController ()
{
}
//-----------------------------------------------------------------------------
DynamicsController::~DynamicsController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DynamicsController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
parameters.addParameter (new ScaledParameter (USTRING("Thresh"), USTRING("dB"), 0, 0.15, ParameterInfo::kCanAutomate, kParam0, -40, 0, true));
parameters.addParameter (USTRING("Ratio"), USTRING(":1"), 0, 0.6, ParameterInfo::kCanAutomate, kParam1);
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam2, 0, 40, true));
parameters.addParameter (USTRING("Attack"), UString128(kMicroSecondsString), 0, 0.5, ParameterInfo::kCanAutomate, kParam3);
parameters.addParameter (USTRING("Release"), USTRING("ms"), 0, 0.5, ParameterInfo::kCanAutomate, kParam4);
parameters.addParameter (USTRING("Limiter"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam5);
parameters.addParameter (USTRING("Gate Thr"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, kParam6);
parameters.addParameter (USTRING("Gate Att"), UString128(kMicroSecondsString), 0, 0.5, ParameterInfo::kCanAutomate, kParam7);
parameters.addParameter (USTRING("Gate Rel"), USTRING("ms"), 0, 0.5, ParameterInfo::kCanAutomate, kParam8);
parameters.addParameter (new ScaledParameter (USTRING("Mix"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, kParam9, 0, 100, true));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DynamicsController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DynamicsController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
return BaseController::getParamStringByValue (tag, valueNormalized, string);
/*
UString128 result;
switch (tag)
{
#if 0
case kParam1:
{
break;
}
#endif
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;*/
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DynamicsController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,71 @@
/*
* mdaDynamicsController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaDynamicsProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DynamicsController : public BaseController
{
public:
DynamicsController ();
~DynamicsController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kParam6,
kParam7,
kParam8,
kParam9,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new DynamicsController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x64614E6D, 0x64612064, 0x796E616D);
#else
inline static DECLARE_UID (uid, 0xDB1EC488, 0x88364B93, 0xB66C365C, 0x904C6D62);
#endif
};
}}} // namespaces
@@ -0,0 +1,195 @@
/*
* mdaDynamicsProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaDynamicsProcessor.h"
#include "mdaDynamicsController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
DynamicsProcessor::DynamicsProcessor ()
{
setControllerClass (DynamicsController::uid);
allocParameters (10);
}
//-----------------------------------------------------------------------------
DynamicsProcessor::~DynamicsProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DynamicsProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.60; //thresh ///Note : special version for ardislarge
params[1] = 0.40; //ratio
params[2] = 0.10; //level ///was 0.6
params[3] = 0.18; //attack
params[4] = 0.55; //release
params[5] = 1.00; //Limiter
params[6] = 0.00; //gate thresh
params[7] = 0.10; //gate attack
params[8] = 0.50; //gate decay
params[9] = 1.00; //fx mix
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DynamicsProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API DynamicsProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
void DynamicsProcessor::checkSilence (ProcessData& /*data*/)
{
}
//-----------------------------------------------------------------------------
void DynamicsProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
if (data.inputs[0].silenceFlags & 3) // don't process if input is silent
{
if (in1 != out1)
memset (out1, 0, sampleFrames * sizeof (float));
if (in2 != out2)
memset (out2, 0, sampleFrames * sizeof (float));
data.outputs[0].silenceFlags = 3;
return;
}
data.outputs[0].silenceFlags = 0;
float a, b, i, j, g, e=env, e2=env2, ra=rat, re= (1.f-rel), at=att, ga=gatt;
float tr=trim, th=thr, lth=lthr, xth=xthr, ge=genv, y =dry;
--in1;
--in2;
--out1;
--out2;
if (mode) //comp/gate/lim
{
if (lth==0.f) lth=1000.f;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
i = (a<0.f)? -a : a;
j = (b<0.f)? -b : b;
i = (j>i)? j : i;
e = (i>e)? e + at * (i - e) : e * re;
e2 = (i>e)? i : e2 * re; //ir;
g = (e>th)? tr / (1.f + ra * ((e / th) - 1.f)) : tr;
if (g<0.f) g=0.f;
if (g*e2>lth) g = lth/e2; //limit
ge = (e>xth)? ge + ga - ga * ge : ge * xrat; //gate
*++out1 = a * (g * ge + y);
*++out2 = b * (g * ge + y);
}
}
else //compressor only
{
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
i = (a<0.f)? -a : a;
j = (b<0.f)? -b : b;
i = (j>i)? j : i; //get peak level
e = (i>e)? e + at * (i - e) : e * re; //envelope
g = (e>th)? tr / (1.f + ra * ((e / th) - 1.f)) : tr; //gain
*++out1 = a * (g + y); //vca
*++out2 = b * (g + y);
}
}
if (e <1.0e-10) env =0.f; else env =e;
if (e2<1.0e-10) env2=0.f; else env2=e2;
if (ge<1.0e-10) genv=0.f; else genv=ge;
}
//-----------------------------------------------------------------------------
void DynamicsProcessor::recalculate ()
{
mode=0;
thr = powf (10.f, static_cast<float> (2.f * params[0] - 2.f));
rat = static_cast<float> (2.5f * params[1] - 0.5f);
if (rat>1.0) { rat = 1.f + 16.f*(rat-1.f) * (rat - 1.f); mode = 1; }
if (rat<0.0) { rat = 0.6f*rat; mode=1; }
trim = powf (10.f,static_cast<float> (2.f * params[2])); //was - 1.f);
att = powf (10.f, static_cast<float> (-0.002f - 2.f * params[3]));
rel = powf (10.f, static_cast<float> (-2.f - 3.f * params[4]));
if (params[5]>0.98) lthr=0.f; //limiter
else { lthr=0.99f*(float)pow (10.0f,int (30.0*params[5] - 20.0)/20.f);
mode=1; }
if (params[6]<0.02) { xthr=0.f; } //expander
else { xthr= (float)pow (10.f,(float)(3.f * params[6] - 3.f)); mode=1; }
xrat = 1.f - (float)pow (10.f, (float)(-2.0 - 3.3 * params[8]));
irel = (float)pow (10.0,-2.0/getSampleRate ());
gatt = (float)pow (10.f, (float)(-0.002 - 3.0 * params[7]));
if (rat<0.0f && thr<0.1f) rat *= thr*15.f;
dry = static_cast<float> (1.0f - params[9]);
trim *= static_cast<float> (params[9]); //fx mix
}
}}} // namespaces
@@ -0,0 +1,66 @@
/*
* mdaDynamicsProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class DynamicsProcessor : public BaseProcessor
{
public:
DynamicsProcessor ();
~DynamicsProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaN'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
void checkSilence (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new DynamicsProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x64614E6D, 0x64612064, 0x796E616D);
#else
inline static DECLARE_UID (uid, 0x9CCF20FE, 0x76CD489C, 0xA9D7EA13, 0xB489CA55);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float thr, rat, env, env2, att, rel, trim, lthr, xthr, xrat, dry;
float genv, gatt, irel;
int mode;
};
}}} // namespaces
@@ -0,0 +1,160 @@
/*
* mdaEPianoController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaEPianoController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
EPianoController::EPianoController ()
{
addBypassParameter = false;
}
//-----------------------------------------------------------------------------
EPianoController::~EPianoController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
auto presetList = {"Default", "Bright", "Mellow", "Autopan", "Tremolo"};
auto* presetParam = new IndexedParameter (
USTRING ("Factory Presets"), USTRING ("%"), static_cast<int32> (presetList.size () - 1),
0.0, ParameterInfo::kIsProgramChange | ParameterInfo::kIsList, kPresetParam);
int32 i = 0;
for (auto item : presetList)
presetParam->setIndexString (i++, UString128 (item));
parameters.addParameter (presetParam);
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING("Envelope Decay"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Envelope Release"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Hardness"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -50, 50));
parameters.addParameter (new ScaledParameter (USTRING("Treble Boost"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -50, 50));
parameters.addParameter (new ScaledParameter (USTRING("Modulation"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (USTRING("LFO Rate"), USTRING("Hz"), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("Velocity Sense"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Stereo Width"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 200));
parameters.addParameter (new ScaledParameter (USTRING("Polyphony"), USTRING("Voices"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 1, 32, true));
parameters.addParameter (new ScaledParameter (USTRING("Fine Tuning"), USTRING("cents"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -50, 50));
parameters.addParameter (USTRING("Random Tuning"), USTRING("cents"), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("Overdrive"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 100));
midiCCParamID[kCtrlModWheel] = kModWheelParam;
parameters.addParameter (USTRING("Mod Wheel"), USTRING(""), 0, 0, 0, kModWheelParam);
midiCCParamID[kCtrlSustainOnOff] = kSustainParam;
midiCCParamID[kCtrlSustenutoOnOff] = kSustainParam;
parameters.addParameter (new IndexedParameter (USTRING("Sustain"), USTRING(""), 1, 0, 0, kSustainParam));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoController::setParamNormalized (ParamID tag, ParamValue value)
{
tresult res = BaseController::setParamNormalized (tag, value);
if (res == kResultOk && tag == kPresetParam) // preset change
{
int32 program = (int32)parameters.getParameter (tag)->toPlain (value);
for (int32 i = 0; i < 12; i++)
{
BaseController::setParamNormalized (i, EPianoProcessor::programParams[program][i]);
}
if (componentHandler)
componentHandler->restartComponent (kParamValuesChanged);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case 4:
{
if (valueNormalized > 0.5)
{
result.printInt (static_cast<int64> (200.0f * valueNormalized - 100.0f));
result.append(USTRING(" Trem"));
}
else
{
result.printInt (static_cast<int64> (100.0f - 200.0f * valueNormalized));
result.append(USTRING(" Pan"));
}
break;
}
case 5:
{
result.printFloat (exp (6.22f * valueNormalized - 2.61f));
break;
}
case 10:
{
result.printFloat (50 * valueNormalized * valueNormalized);
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
switch (tag)
{
case 4:
case 5:
case 10:
break;
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;
}
}}} // namespaces
@@ -0,0 +1,58 @@
/*
* mdaEPianoController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaEPianoProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class EPianoController : public BaseController
{
public:
EPianoController ();
~EPianoController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setParamNormalized (ParamID tag, ParamValue value) SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new EPianoController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653454D, 0x4441656D, 0x64612065, 0x7069616E);
#else
inline static DECLARE_UID (uid, 0xDA4F8237, 0x290441D4, 0xAF96E580, 0xE22C01FF);
#endif
};
}}} // namespaces
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,452 @@
/*
* mdaEPianoProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaEPianoProcessor.h"
#include "mdaEPianoController.h"
#include "mdaEPianoData.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
#define NPARAMS 12 //number of parameters
#define SILENCE 0.0001f //voice choking
#define WAVELEN 422414 //wave data bytes
float EPianoProcessor::programParams[][NPARAMS] = {
{ 0.500f, 0.500f, 0.500f, 0.500f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.146f, 0.000f },
{ 0.500f, 0.500f, 1.000f, 0.800f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.146f, 0.500f },
{ 0.500f, 0.500f, 0.000f, 0.000f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.246f, 0.000f },
{ 0.500f, 0.500f, 0.500f, 0.500f, 0.250f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.246f, 0.000f },
{ 0.500f, 0.500f, 0.500f, 0.500f, 0.750f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.246f, 0.000f }
};
//-----------------------------------------------------------------------------
EPianoProcessor::EPianoProcessor ()
: currentProgram (0)
{
setControllerClass (EPianoController::uid);
allocParameters (NPARAMS);
}
//-----------------------------------------------------------------------------
EPianoProcessor::~EPianoProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoProcessor::initialize (FUnknown* context)
{
tresult res = Base::initialize (context);
if (res == kResultTrue)
{
addEventInput (USTRING("MIDI in"), 1);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
ParamValue defValues[] = {0.500f, 0.500f, 0.500f, 0.500f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.146f, 0.000f};
for (int32 i = 0; i < NPARAMS; i++)
params[i] = defValues[i];
muffvel = tune = sizevel = 0;
waves = epianoData;
//Waveform data and keymapping
kgrp[ 0].root = 36; kgrp[ 0].high = 39; //C1
kgrp[ 3].root = 43; kgrp[ 3].high = 45; //G1
kgrp[ 6].root = 48; kgrp[ 6].high = 51; //C2
kgrp[ 9].root = 55; kgrp[ 9].high = 57; //G2
kgrp[12].root = 60; kgrp[12].high = 63; //C3
kgrp[15].root = 67; kgrp[15].high = 69; //G3
kgrp[18].root = 72; kgrp[18].high = 75; //C4
kgrp[21].root = 79; kgrp[21].high = 81; //G4
kgrp[24].root = 84; kgrp[24].high = 87; //C5
kgrp[27].root = 91; kgrp[27].high = 93; //G5
kgrp[30].root = 96; kgrp[30].high =999; //C6
kgrp[0].pos = 0; kgrp[0].end = 8476; kgrp[0].loop = 4400;
kgrp[1].pos = 8477; kgrp[1].end = 16248; kgrp[1].loop = 4903;
kgrp[2].pos = 16249; kgrp[2].end = 34565; kgrp[2].loop = 6398;
kgrp[3].pos = 34566; kgrp[3].end = 41384; kgrp[3].loop = 3938;
kgrp[4].pos = 41385; kgrp[4].end = 45760; kgrp[4].loop = 1633; //was 1636;
kgrp[5].pos = 45761; kgrp[5].end = 65211; kgrp[5].loop = 5245;
kgrp[6].pos = 65212; kgrp[6].end = 72897; kgrp[6].loop = 2937;
kgrp[7].pos = 72898; kgrp[7].end = 78626; kgrp[7].loop = 2203; //was 2204;
kgrp[8].pos = 78627; kgrp[8].end = 100387; kgrp[8].loop = 6368;
kgrp[9].pos = 100388; kgrp[9].end = 116297; kgrp[9].loop = 10452;
kgrp[10].pos = 116298; kgrp[10].end = 127661; kgrp[10].loop = 5217; //was 5220;
kgrp[11].pos = 127662; kgrp[11].end = 144113; kgrp[11].loop = 3099;
kgrp[12].pos = 144114; kgrp[12].end = 152863; kgrp[12].loop = 4284;
kgrp[13].pos = 152864; kgrp[13].end = 173107; kgrp[13].loop = 3916;
kgrp[14].pos = 173108; kgrp[14].end = 192734; kgrp[14].loop = 2937;
kgrp[15].pos = 192735; kgrp[15].end = 204598; kgrp[15].loop = 4732;
kgrp[16].pos = 204599; kgrp[16].end = 218995; kgrp[16].loop = 4733;
kgrp[17].pos = 218996; kgrp[17].end = 233801; kgrp[17].loop = 2285;
kgrp[18].pos = 233802; kgrp[18].end = 248011; kgrp[18].loop = 4098;
kgrp[19].pos = 248012; kgrp[19].end = 265287; kgrp[19].loop = 4099;
kgrp[20].pos = 265288; kgrp[20].end = 282255; kgrp[20].loop = 3609;
kgrp[21].pos = 282256; kgrp[21].end = 293776; kgrp[21].loop = 2446;
kgrp[22].pos = 293777; kgrp[22].end = 312566; kgrp[22].loop = 6278;
kgrp[23].pos = 312567; kgrp[23].end = 330200; kgrp[23].loop = 2283;
kgrp[24].pos = 330201; kgrp[24].end = 348889; kgrp[24].loop = 2689;
kgrp[25].pos = 348890; kgrp[25].end = 365675; kgrp[25].loop = 4370;
kgrp[26].pos = 365676; kgrp[26].end = 383661; kgrp[26].loop = 5225;
kgrp[27].pos = 383662; kgrp[27].end = 393372; kgrp[27].loop = 2811;
kgrp[28].pos = 383662; kgrp[28].end = 393372; kgrp[28].loop = 2811; //ghost
kgrp[29].pos = 393373; kgrp[29].end = 406045; kgrp[29].loop = 4522;
kgrp[30].pos = 406046; kgrp[30].end = 414486; kgrp[30].loop = 2306;
kgrp[31].pos = 406046; kgrp[31].end = 414486; kgrp[31].loop = 2306; //ghost
kgrp[32].pos = 414487; kgrp[32].end = 422408; kgrp[32].loop = 2169;
//extra xfade looping...
for(int32 k=0; k<28; k++)
{
int32 p0 = kgrp[k].end;
int32 p1 = kgrp[k].end - kgrp[k].loop;
float xf = 1.0f;
float dxf = -0.02f;
while (xf > 0.0f)
{
waves[p0] = (short)((1.0f - xf) * (float)waves[p0] + xf * (float)waves[p1]);
p0--;
p1 --;
xf += dxf;
}
}
//initialise...
for(int32 v=0; v<kNumVoices; v++)
{
memset (&synthData.voice[v], 0, sizeof (VOICE));
synthData.voice[v].env = 0.0f;
synthData.voice[v].dec = 0.99f; //all notes off
}
volume = 0.2f;
muff = 160.0f;
synthData.sustain = synthData.activevoices = 0;
tl = tr = lfo0 = dlfo = 0.0f;
lfo1 = 1.0f;
modwhl = 0.;
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoProcessor::terminate ()
{
return Base::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoProcessor::setActive (TBool state)
{
if (state)
{
Fs = static_cast<float> (getSampleRate ());
iFs = 1.0f / Fs;
dlfo = 6.283f * iFs * (float)exp ((float)(6.22f * params[5] - 2.61f)); //lfo rate
recalculate ();
}
return Base::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API EPianoProcessor::setProcessing (TBool state)
{
if (state)
{
synthData.init ();
synthData.clearEvents ();
}
Base::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void EPianoProcessor::setParameter (ParamID index, ParamValue newValue, int32 sampleOffset)
{
if (index < NPARAMS)
Base::setParameter (index, newValue, sampleOffset);
else if (index == BaseController::kPresetParam) // program change
{
int32 program = (int32)(newValue * kNumPrograms);
const float* newParams = programParams[program];
if (newParams)
{
for (int32 i = 0; i < NPARAMS; i++)
params[i] = newParams[i];
recalculate ();
}
}
else if (index == BaseController::kModWheelParam) // mod wheel
{
newValue *= 127.;
modwhl = static_cast<float> (0.0078f * newValue);
}
else if (index == BaseController::kSustainParam)
{
synthData.sustain = newValue > 0.5;
if (synthData.sustain==0)
{
for (auto& v : synthData.voice)
{
if (v.noteID = SustainNoteID)
{
v.dec = (float)exp (-iFs * exp (6.0 + 0.01 * (double)v.note - 5.0 * params[1]));
}
}
}
}
}
//-----------------------------------------------------------------------------
void EPianoProcessor::setCurrentProgram (Steinberg::uint32 val)
{
if (val < kNumPrograms)
currentProgram = val;
}
//-----------------------------------------------------------------------------
void EPianoProcessor::setCurrentProgramNormalized (ParamValue val)
{
setCurrentProgram (std::min<int32> (kNumPrograms - 1, (int32)(val * kNumPrograms)));
}
//-----------------------------------------------------------------------------
void EPianoProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
int32 frame=0, frames, v;
float x, l, r, od=overdrive;
int32 i;
synthData.eventPos = 0;
if (synthData.activevoices > 0 || synthData.hasEvents ())
{
while (frame<sampleFrames)
{
frames = synthData.events[synthData.eventPos].sampleOffset;
if (frames>sampleFrames) frames = sampleFrames;
frames -= frame;
frame += frames;
while (--frames>=0)
{
VOICE *V = synthData.voice.data ();
l = r = 0.0f;
for(v=0; v<synthData.activevoices; v++)
{
V->frac += V->delta; //integer-based linear interpolation
V->pos += V->frac >> 16;
V->frac &= 0xFFFF;
if (V->pos > V->end) V->pos -= V->loop;
//i = waves[V->pos];
//i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; //not working on intel mac !?!
//x = V->env * (*(float *)&i - 3.0f); //fast int->float
//x = V->env * (float)i / 32768.0f;
i = waves[V->pos] + ((V->frac * (waves[V->pos + 1] - waves[V->pos])) >> 16);
x = V->env * (float)i / 32768.0f;
V->env = V->env * V->dec; //envelope
if (x>0.0f) { x -= od * x * x; if (x < -V->env) x = -V->env; } //+= 0.5f * x * x; } //overdrive
l += V->outl * x;
r += V->outr * x;
V++;
}
tl += tfrq * (l - tl); //treble boost
tr += tfrq * (r - tr);
r += treb * (r - tr);
l += treb * (l - tl);
lfo0 += dlfo * lfo1; //LFO for tremolo and autopan
lfo1 -= dlfo * lfo0;
l += l * lmod * lfo1;
r += r * rmod * lfo1; //worth making all these local variables?
*out1++ = l;
*out2++ = r;
}
if (frame<sampleFrames)
{
if (synthData.activevoices == 0 && params[4] > 0.5f)
{ lfo0 = -0.7071f; lfo1 = 0.7071f; } //reset LFO phase - good idea?
noteEvent (synthData.events[synthData.eventPos]);
++synthData.eventPos;
}
}
}
else //completely empty block
{
memset (out1, 0, sizeof (float) * data.numSamples);
memset (out2, 0, sizeof (float) * data.numSamples);
data.outputs[0].silenceFlags = 3;
}
if (fabs (tl) < 1.0e-10) tl = 0.0f; //anti-denormal
if (fabs (tr) < 1.0e-10) tr = 0.0f;
for(v=0; v<synthData.activevoices; v++)
if (synthData.voice[v].env < SILENCE)
synthData.voice[v] = synthData.voice[--synthData.activevoices];
}
//-----------------------------------------------------------------------------
void EPianoProcessor::noteEvent (const Event& event)
{
float l=99.0f;
int32 v, vl=0, k, s;
if (event.type == Event::kNoteOnEvent)
{
auto& noteOn = event.noteOn;
auto note = noteOn.pitch;
float velocity = noteOn.velocity * 127;
if (synthData.activevoices < poly) //add a note
{
vl = synthData.activevoices;
synthData.activevoices++;
synthData.voice[vl].f0 = synthData.voice[vl].f1 = 0.0f;
}
else //steal a note
{
for(v=0; v<poly; v++) //find quietest voice
{
if (synthData.voice[v].env < l) { l = synthData.voice[v].env; vl = v; }
}
}
k = (note - 60) * (note - 60);
l = fine + random * ((float)(k % 13) - 6.5f); //random & fine tune
if (note > 60) l += stretch * (float)k; //stretch
s = size;
if (velocity > 40) s += (int32)(sizevel * (float)(velocity - 40));
k = 0;
while (note > (kgrp[k].high + s)) k += 3; //find keygroup
l += (float)(note - kgrp[k].root); //pitch
l = 32000.0f * iFs * (float)exp (0.05776226505 * l);
synthData.voice[vl].delta = (int32)(65536.0f * l);
synthData.voice[vl].frac = 0;
if (velocity > 48) k++; //mid velocity sample
if (velocity > 80) k++; //high velocity sample
synthData.voice[vl].pos = kgrp[k].pos;
synthData.voice[vl].end = kgrp[k].end - 1;
synthData.voice[vl].loop = kgrp[k].loop;
synthData.voice[vl].env = (3.0f + 2.0f * velsens) * (float)pow (0.0078f * velocity, velsens); //velocity
if (note > 60) synthData.voice[vl].env *= (float)exp (0.01f * (float)(60 - note)); //new! high notes quieter
l = static_cast<float> (50.0f + params[4] * params[4] * muff + muffvel * (float)(velocity - 64)); //muffle
if (l < (55.0f + 0.4f * (float)note)) l = 55.0f + 0.4f * (float)note;
if (l > 210.0f) l = 210.0f;
synthData.voice[vl].ff = l * l * iFs;
synthData.voice[vl].note = note; //note->pan
if (note < 12) note = 12;
if (note > 108) note = 108;
l = volume;
synthData.voice[vl].outr = l + l * width * (float)(note - 60);
synthData.voice[vl].outl = l + l - synthData.voice[vl].outr;
if (note < 44) note = 44; //limit max decay length
synthData.voice[vl].dec = (float)exp (-iFs * exp (-1.0 + 0.03 * (double)note - 2.0f * params[0]));
synthData.voice[vl].noteID = noteOn.noteId;
}
else //note off
{
auto& noteOff = event.noteOff;
auto note = noteOff.pitch;
for(v=0; v<synthData.numVoices; v++) if (synthData.voice[v].noteID==noteOff.noteId) //any voices playing that note?
{
if (synthData.sustain==0)
{
synthData.voice[v].dec = (float)exp (-iFs * exp (6.0 + 0.01 * (double)note - 5.0 * params[1]));
}
else synthData.voice[v].noteID = SustainNoteID;
}
}
}
//-----------------------------------------------------------------------------
void EPianoProcessor::preProcess ()
{
synthData.clearEvents ();
}
//-----------------------------------------------------------------------------
void EPianoProcessor::processEvent (const Event& e)
{
synthData.processEvent (e);
}
//-----------------------------------------------------------------------------
void EPianoProcessor::recalculate ()
{
size = (int32)(12.0f * params[2] - 6.0f);
treb = static_cast<float> (4.0f * params[3] * params[3] - 1.0f); //treble gain
if (params[3] > 0.5f) tfrq = 14000.0f; else tfrq = 5000.0f; //treble freq
tfrq = 1.0f - (float)exp (-iFs * tfrq);
rmod = lmod = static_cast<float> (params[4] + params[4] - 1.0f); //lfo depth
if (params[4] < 0.5f) rmod = -rmod;
dlfo = 6.283f * iFs * (float)exp (6.22f * params[5] - 2.61f); //lfo rate
velsens = static_cast<float> (1.0f + params[6] + params[6]);
if (params[6] < 0.25f) velsens -= static_cast<float> (0.75f - 3.0f * params[6]);
width = static_cast<float> (0.03f * params[7]);
poly = 1 + (int32)(31.9f * params[8]);
fine = static_cast<float> (params[9] - 0.5f);
random = static_cast<float> (0.077f * params[10] * params[10]);
stretch = 0.0f; //0.000434f * (params[11] - 0.5f); parameter re-used for overdrive!
overdrive = static_cast<float> (1.8f * params[11]);
if (modwhl > 0.05f) //over-ride pan/trem depth
{
rmod = lmod = modwhl; //lfo depth
if (params[4] < 0.5f) rmod = -rmod;
}
}
}}} // namespaces
@@ -0,0 +1,131 @@
/*
* mdaEPianoProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class EPianoProcessor : public BaseProcessor
{
public:
using Base = BaseProcessor;
EPianoProcessor ();
~EPianoProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'MDAe'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
bool hasProgram () const SMTG_OVERRIDE { return true; }
Steinberg::uint32 getCurrentProgram () const SMTG_OVERRIDE { return currentProgram; }
Steinberg::uint32 getNumPrograms () const SMTG_OVERRIDE { return kNumPrograms; }
void setCurrentProgram (Steinberg::uint32 val) SMTG_OVERRIDE;
void setCurrentProgramNormalized (ParamValue val) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new EPianoProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653544D, 0x4441656D, 0x64612065, 0x7069616E);
#else
inline static DECLARE_UID (uid, 0xFED93DB8, 0x5E81448F, 0xA3B14028, 0x879FA824);
#endif
//-----------------------------------------------------------------------------
static float programParams[][12];
//-----------------------------------------------------------------------------
struct VOICE //voice state
{
int32 delta; //sample playback
int32 frac;
int32 pos;
int32 end;
int32 loop;
float env; //envelope
float dec;
float f0; //first-order LPF
float f1;
float ff;
float outl;
float outr;
int32 note; //remember what note triggered this
int32 noteID;
};
//-----------------------------------------------------------------------------
struct KGRP //keygroup
{
int32 root; //MIDI root note
int32 high; //highest note
int32 pos;
int32 end;
int32 loop;
};
static const int32 kNumPrograms = 4;
protected:
void setParameter (ParamID index, ParamValue newValue, int32 sampleOffset) SMTG_OVERRIDE;
void preProcess () SMTG_OVERRIDE;
void processEvent (const Event& event) SMTG_OVERRIDE;
void noteEvent (const Event& event);
void recalculate () SMTG_OVERRIDE;
float Fs, iFs;
static constexpr int32 kNumVoices = 32;
static constexpr int32 kEventBufferSize = 64;
using SynthDataT = SynthData<VOICE, kEventBufferSize, kNumVoices>;
SynthDataT synthData;
KGRP kgrp[34];
int32 poly;
short *waves;
float width;
int32 size;
float lfo0, lfo1, dlfo, lmod, rmod;
float treb, tfrq, tl, tr;
float tune, fine, random, stretch, overdrive;
float muff, muffvel, sizevel, velsens, volume, modwhl;
Steinberg::uint32 currentProgram;
};
}}} // namespaces
@@ -0,0 +1,68 @@
/*
* mdaImageController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaImageController.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
ImageController::ImageController ()
{
}
//-----------------------------------------------------------------------------
ImageController::~ImageController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ImageController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
auto* modeParam = new IndexedParameter (USTRING("Mode"), USTRING(""), 3, 0.15, ParameterInfo::kCanAutomate | ParameterInfo::kIsList, kParam0);
modeParam->setIndexString (0, UString128("SM->LR"));
modeParam->setIndexString (1, UString128("MS->LR"));
modeParam->setIndexString (2, UString128("LR->LR"));
modeParam->setIndexString (3, UString128("LR->MS"));
parameters.addParameter (modeParam);
parameters.addParameter (new ScaledParameter (USTRING("S Width"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, kParam1, -200, 200, true));
parameters.addParameter (new ScaledParameter (USTRING("S Pan"), USTRING("L<->R"), 0, 0.5, ParameterInfo::kCanAutomate, kParam2, -100, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("M Level"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, kParam3, -200, 200, true));
parameters.addParameter (new ScaledParameter (USTRING("M Pan"), USTRING("L<->R"), 0, 0.15, ParameterInfo::kCanAutomate, kParam4, -100, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.15, ParameterInfo::kCanAutomate, kParam5, -20, 20, true));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ImageController::terminate ()
{
return BaseController::terminate ();
}
}}} // namespaces
@@ -0,0 +1,64 @@
/*
* mdaImageController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaImageProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class ImageController : public BaseController
{
public:
ImageController ();
~ImageController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new ImageController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461496D, 0x64612069, 0x6D616765);
#else
inline static DECLARE_UID (uid, 0x18E85131, 0x09CE429D, 0x83E6621D, 0x74EF40FD);
#endif
};
}}} // namespaces
@@ -0,0 +1,155 @@
/*
* mdaImageProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaImageProcessor.h"
#include "mdaImageController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
ImageProcessor::ImageProcessor ()
{
setControllerClass (ImageController::uid);
allocParameters (6);
}
//-----------------------------------------------------------------------------
ImageProcessor::~ImageProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ImageProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.6f; //mode
params[1] = 0.75f; //width
params[2] = 0.5f; //skew
params[3] = 0.75f; //centre
params[4] = 0.5f; //balance
params[5] = 0.5f; //output
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ImageProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ImageProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
void ImageProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, c, d, ll=l2l, lr=l2r, rl=r2l, rr = r2r;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
d = rr*b + lr*a;
c = ll*a + rl*b;
*++out1 = c;
*++out2 = d;
}
}
//-----------------------------------------------------------------------------
void ImageProcessor::recalculate ()
{
float w, k, c, b, g;
w = static_cast<float> (4.f * params[1] - 2.f); //width
k = static_cast<float> (2.f * params[2]); //balance
c = static_cast<float> (4.f * params[3] - 2.f); //depth
b = static_cast<float> (2.f * params[4]); //pan
g = (float)pow (10.0, 2.0 * params[5] - 1.0);
switch (int (params[0]*3.9))
{
case 0: //SM->LR
r2l = g * c * (2.f - b);
l2l = g * w * (2.f - k);
r2r = g * c * b;
l2r = -g * w * k;
break;
case 1: //MS->LR
l2l = g * c * (2.f - b);
r2l = g * w * (2.f - k);
l2r = g * c * b;
r2r = -g * w * k;
break;
case 2: //LR->LR
g *= 0.5f;
l2l = g * (c * (2.f - b) + w * (2.f - k));
r2l = g * (c * (2.f - b) - w * (2.f - k));
l2r = g * (c * b - w * k);
r2r = g * (c * b + w * k);
break;
case 3: //LR->MS
g *= 0.5f;
l2l = g * (2.f - b) * (2.f - k);
r2l = g * (2.f - b) * k;
l2r = -g * b * (2.f - k);
r2r = g * b * k;
break;
}
}
}}} // namespaces
@@ -0,0 +1,63 @@
/*
* mdaImageProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class ImageProcessor : public BaseProcessor
{
public:
ImageProcessor ();
~ImageProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaI'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new ImageProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461496D, 0x64612069, 0x6D616765);
#else
inline static DECLARE_UID (uid, 0xE99952F1, 0x3CBD42DE, 0x98604990, 0xD4FB3212);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float l2l, l2r, r2l, r2r;
};
}}} // namespaces
@@ -0,0 +1,217 @@
/*
* mdaJX10Controller.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaJX10Controller.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
JX10Controller::JX10Controller ()
{
addBypassParameter = false;
}
//-----------------------------------------------------------------------------
JX10Controller::~JX10Controller ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Controller::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
auto presetList = { "5th Sweep Pad",
"Echo Pad [SA]",
"Space Chimes [SA]",
"Solid Backing",
"Velocity Backing [SA]",
"Rubber Backing [ZF]",
"808 State Lead",
"Mono Glide",
"Detuned Techno Lead",
"Hard Lead [SA]",
"Bubble",
"Monosynth",
"Moogcury Lite",
"Gangsta Whine",
"Higher Synth [ZF]",
"303 Saw Bass",
"303 Square Bass",
"Analog Bass",
"Analog Bass 2",
"Low Pulses",
"Sine Infra-Bass",
"Wobble Bass [SA]",
"Squelch Bass",
"Rubber Bass [ZF]",
"Soft Pick Bass",
"Fretless Bass",
"Whistler",
"Very Soft Pad",
"Pizzicato",
"Synth Strings",
"Synth Strings 2",
"Leslie Organ",
"Click Organ",
"Hard Organ",
"Bass Clarinet",
"Trumpet",
"Soft Horn",
"Brass Section",
"Synth Brass",
"Detuned Syn Brass [ZF]",
"Power PWM",
"Water Velocity [SA]",
"Ghost [SA]",
"Soft E.Piano",
"Thumb Piano",
"Steel Drums [ZF]",
"Car Horn",
"Helicopter",
"Arctic Wind",
"Thip",
"Synth Tom",
"Squelchy Frog" };
auto* presetParam = new IndexedParameter (
USTRING ("Factory Presets"), USTRING ("%"), static_cast<int32> (presetList.size () - 1),
0.0, ParameterInfo::kIsProgramChange | ParameterInfo::kIsList, kPresetParam);
parameters.addParameter (presetParam);
int32 i = 0;
for (auto item : presetList)
presetParam->setIndexString (i++, UString128 (item));
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING ("OSC Mix"), USTRING ("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("OSC Tune"), USTRING ("%"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("OSC Fine"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -100, 100));
auto glideModeList = {"Poly", "Poly-Legato", "Poly-Glide",
"Mono", "Mono-Legato", "Mono-Glide"};
auto* glideModeParam = new IndexedParameter (
USTRING ("Glide"), nullptr, static_cast<int32> (glideModeList.size () - 1), 0,
ParameterInfo::kCanAutomate | ParameterInfo::kIsList, pid++);
i = 0;
for (auto item : glideModeList)
glideModeParam->setIndexString (i++, UString128 (item));
parameters.addParameter (glideModeParam);
parameters.addParameter (new ScaledParameter (USTRING ("Gld Rate"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("Gld Bend"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF Freq"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF Reso"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF Env"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF LFO"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF Vel"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF Att"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF Dec"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF Sus"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("VCF Rel"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("ENV Att"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("ENV Dec"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("ENV Sus"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("ENV Rel"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("LFO Rate"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("Vibrato"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("Noise"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING ("Octave"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -100, 100));
parameters.addParameter (new ScaledParameter (USTRING ("Tuning"), USTRING ("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -100, 100));
midiCCParamID[kCtrlModWheel] = kModWheelParam;
parameters.addParameter (new ScaledParameter (USTRING("Mod Wheel"), USTRING("%"), 0, 0, 0, kModWheelParam, 0, 100));
midiCCParamID[kPitchBend] = kPitchBendParam;
parameters.addParameter (new ScaledParameter (USTRING("Pitch Bend"), USTRING("%"), 0, 0.5, 0, kPitchBendParam, -100, 100));
midiCCParamID[kCtrlBreath] = kBreathParam;
midiCCParamID[kCtrlFilterResonance] = kBreathParam;
parameters.addParameter (new ScaledParameter (USTRING("Filter Mod+"), USTRING("%"), 0, 0., 0, kBreathParam, 0, 100));
midiCCParamID[3] = kCtrler3Param;
parameters.addParameter (new ScaledParameter (USTRING("Filter Mod-"), USTRING("%"), 0, 0., 0, kCtrler3Param, 0, 100));
midiCCParamID[kCtrlExpression] = kCtrler3Param;
parameters.addParameter (new ScaledParameter (USTRING("Filter Resonance"), USTRING("%"), 0, 0.5, 0, kExpressionParam, 0, 100));
midiCCParamID[kAfterTouch] = kAftertouchParam;
parameters.addParameter (new ScaledParameter (USTRING("Aftertouch"), USTRING("%"), 0, 0.5, 0, kAftertouchParam, 0, 100));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Controller::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Controller::setParamNormalized (ParamID tag, ParamValue value)
{
tresult res = BaseController::setParamNormalized (tag, value);
if (res == kResultOk && tag == kPresetParam) // preset change
{
int32 program = static_cast<int32> (parameters.getParameter (tag)->toPlain (value));
for (int32 i = 0; i < 24; i++)
{
BaseController::setParamNormalized (i, JX10Processor::programParams[program][i]);
}
if (componentHandler)
componentHandler->restartComponent (kParamValuesChanged);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Controller::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
return BaseController::getParamStringByValue (tag, valueNormalized, string);
/*
UString128 result;
switch (tag)
{
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;*/
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Controller::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,57 @@
/*
* mdaJX10Controller.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaJX10Processor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class JX10Controller : public BaseController
{
public:
JX10Controller ();
~JX10Controller () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setParamNormalized (ParamID tag, ParamValue value) SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new JX10Controller; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653454D, 0x44416A6D, 0x6461206A, 0x78313000);
#else
inline static DECLARE_UID (uid, 0x91E8798D, 0xEDE644C9, 0xB9EB444B, 0x5F0A8AA7);
#endif
};
}}} // namespaces
@@ -0,0 +1,645 @@
/*
* mdaJX10Processor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaJX10Processor.h"
#include "mdaJX10Controller.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
#define NPARAMS 24 //number of parameters
#define SILENCE 0.001f //voice choking
#define PI 3.1415926535897932f
#define TWOPI 6.2831853071795864f
#define ANALOG 0.002f //oscillator drift
float JX10Processor::programParams[kNumPrograms][NPARAMS] = {
{1.0f, 0.37f, 0.25f, 0.3f, 0.32f, 0.5f, 0.9f, 0.6f, 0.12f, 0.0f, 0.5f, 0.9f, 0.89f, 0.9f, 0.73f, 0.0f, 0.5f, 1.0f, 0.71f, 0.81f, 0.65f, 0.0f, 0.5f, 0.5f},
{0.88f, 0.51f, 0.5f, 0.0f, 0.49f, 0.5f, 0.46f, 0.76f, 0.69f, 0.1f, 0.69f, 1.0f, 0.86f, 0.76f, 0.57f, 0.3f, 0.8f, 0.68f, 0.66f, 0.79f, 0.13f, 0.25f, 0.45f, 0.5f},
{0.88f, 0.51f, 0.5f, 0.16f, 0.49f, 0.5f, 0.49f, 0.82f, 0.66f, 0.08f, 0.89f, 0.85f, 0.69f, 0.76f, 0.47f, 0.12f, 0.22f, 0.55f, 0.66f, 0.89f, 0.34f, 0.0f, 1.0f, 0.5f},
{1.0f, 0.26f, 0.14f, 0.0f, 0.35f, 0.5f, 0.3f, 0.25f, 0.7f, 0.0f, 0.63f, 0.0f, 0.35f, 0.0f, 0.25f, 0.0f, 0.5f, 1.0f, 0.3f, 0.81f, 0.5f, 0.5f, 0.5f, 0.5f},
{0.41f, 0.5f, 0.79f, 0.0f, 0.08f, 0.32f, 0.49f, 0.01f, 0.34f, 0.0f, 0.93f, 0.61f, 0.87f, 1.0f, 0.93f, 0.11f, 0.48f, 0.98f, 0.32f, 0.81f, 0.5f, 0.0f, 0.5f, 0.5f},
{0.29f, 0.76f, 0.26f, 0.0f, 0.18f, 0.76f, 0.35f, 0.15f, 0.77f, 0.14f, 0.54f, 0.0f, 0.42f, 0.13f, 0.21f, 0.0f, 0.56f, 0.0f, 0.32f, 0.2f, 0.58f, 0.22f, 0.53f, 0.5f},
{1.0f, 0.65f, 0.24f, 0.4f, 0.34f, 0.85f, 0.65f, 0.63f, 0.75f, 0.16f, 0.5f, 0.0f, 0.3f, 0.0f, 0.25f, 0.17f, 0.5f, 1.0f, 0.03f, 0.81f, 0.5f, 0.0f, 0.68f, 0.5f},
{0.0f, 0.25f, 0.5f, 1.0f, 0.46f, 0.5f, 0.51f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.3f, 0.0f, 0.25f, 0.37f, 0.5f, 1.0f, 0.38f, 0.81f, 0.62f, 0.0f, 0.5f, 0.5f},
{0.84f, 0.51f, 0.15f, 0.45f, 0.41f, 0.42f, 0.54f, 0.01f, 0.58f, 0.21f, 0.67f, 0.0f, 0.09f, 1.0f, 0.25f, 0.2f, 0.85f, 1.0f, 0.3f, 0.83f, 0.09f, 0.4f, 0.49f, 0.5f},
{0.71f, 0.75f, 0.53f, 0.18f, 0.24f, 1.0f, 0.56f, 0.52f, 0.69f, 0.19f, 0.7f, 1.0f, 0.14f, 0.65f, 0.95f, 0.07f, 0.91f, 1.0f, 0.15f, 0.84f, 0.33f, 0.0f, 0.49f, 0.5f},
{0.0f, 0.25f, 0.43f, 0.0f, 0.71f, 0.48f, 0.23f, 0.77f, 0.8f, 0.32f, 0.63f, 0.4f, 0.18f, 0.66f, 0.14f, 0.0f, 0.38f, 0.65f, 0.16f, 0.48f, 0.5f, 0.0f, 0.67f, 0.5f},
{0.62f, 0.26f, 0.51f, 0.79f, 0.35f, 0.54f, 0.64f, 0.39f, 0.51f, 0.65f, 0.0f, 0.07f, 0.52f, 0.24f, 0.84f, 0.13f, 0.3f, 0.76f, 0.21f, 0.58f, 0.3f, 0.0f, 0.36f, 0.5f},
{0.81f, 1.0f, 0.21f, 0.78f, 0.15f, 0.35f, 0.39f, 0.17f, 0.69f, 0.4f, 0.62f, 0.0f, 0.47f, 0.19f, 0.37f, 0.0f, 0.5f, 0.2f, 0.33f, 0.38f, 0.53f, 0.0f, 0.12f, 0.5f},
{0.0f, 0.51f, 0.52f, 0.96f, 0.44f, 0.5f, 0.41f, 0.46f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.25f, 0.15f, 0.5f, 1.0f, 0.32f, 0.81f, 0.49f, 0.0f, 0.83f, 0.5f},
{0.48f, 0.51f, 0.22f, 0.0f, 0.0f, 0.5f, 0.5f, 0.47f, 0.73f, 0.3f, 0.8f, 0.0f, 0.1f, 0.0f, 0.07f, 0.0f, 0.42f, 0.0f, 0.22f, 0.21f, 0.59f, 0.16f, 0.98f, 0.5f},
{0.0f, 0.51f, 0.5f, 0.83f, 0.49f, 0.5f, 0.55f, 0.75f, 0.69f, 0.35f, 0.5f, 0.0f, 0.56f, 0.0f, 0.56f, 0.0f, 0.8f, 1.0f, 0.24f, 0.26f, 0.49f, 0.0f, 0.07f, 0.5f},
{0.75f, 0.51f, 0.5f, 0.83f, 0.49f, 0.5f, 0.55f, 0.75f, 0.69f, 0.35f, 0.5f, 0.14f, 0.49f, 0.0f, 0.39f, 0.0f, 0.8f, 1.0f, 0.24f, 0.26f, 0.49f, 0.0f, 0.07f, 0.5f},
{1.0f, 0.25f, 0.2f, 0.81f, 0.19f, 0.5f, 0.3f, 0.51f, 0.85f, 0.09f, 0.0f, 0.0f, 0.88f, 0.0f, 0.21f, 0.0f, 0.5f, 1.0f, 0.46f, 0.81f, 0.5f, 0.0f, 0.27f, 0.5f},
{1.0f, 0.25f, 0.2f, 0.72f, 0.19f, 0.86f, 0.48f, 0.43f, 0.94f, 0.0f, 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.61f, 1.0f, 0.32f, 0.81f, 0.5f, 0.0f, 0.27f, 0.5f},
{0.97f, 0.26f, 0.3f, 0.0f, 0.35f, 0.5f, 0.8f, 0.4f, 0.52f, 0.0f, 0.5f, 0.0f, 0.77f, 0.0f, 0.25f, 0.0f, 0.5f, 1.0f, 0.3f, 0.81f, 0.16f, 0.0f, 0.0f, 0.5f},
{0.0f, 0.25f, 0.5f, 0.65f, 0.35f, 0.5f, 0.33f, 0.76f, 0.53f, 0.0f, 0.5f, 0.0f, 0.3f, 0.0f, 0.25f, 0.0f, 0.55f, 0.25f, 0.3f, 0.81f, 0.52f, 0.0f, 0.14f, 0.5f},
{1.0f, 0.26f, 0.22f, 0.64f, 0.82f, 0.59f, 0.72f, 0.47f, 0.34f, 0.34f, 0.82f, 0.2f, 0.69f, 1.0f, 0.15f, 0.09f, 0.5f, 1.0f, 0.07f, 0.81f, 0.46f, 0.0f, 0.24f, 0.5f},
{1.0f, 0.26f, 0.22f, 0.71f, 0.35f, 0.5f, 0.67f, 0.7f, 0.26f, 0.0f, 0.5f, 0.48f, 0.69f, 1.0f, 0.15f, 0.0f, 0.5f, 1.0f, 0.07f, 0.81f, 0.46f, 0.0f, 0.24f, 0.5f},
{0.49f, 0.25f, 0.66f, 0.81f, 0.35f, 0.5f, 0.36f, 0.15f, 0.75f, 0.2f, 0.5f, 0.0f, 0.38f, 0.0f, 0.25f, 0.0f, 0.6f, 1.0f, 0.22f, 0.19f, 0.5f, 0.0f, 0.17f, 0.5f},
{0.37f, 0.51f, 0.77f, 0.71f, 0.22f, 0.5f, 0.33f, 0.47f, 0.71f, 0.16f, 0.59f, 0.0f, 0.0f, 0.0f, 0.25f, 0.04f, 0.58f, 0.0f, 0.22f, 0.15f, 0.44f, 0.33f, 0.15f, 0.5f},
{0.5f, 0.51f, 0.17f, 0.8f, 0.34f, 0.5f, 0.51f, 0.0f, 0.58f, 0.0f, 0.67f, 0.0f, 0.09f, 0.0f, 0.25f, 0.2f, 0.85f, 0.0f, 0.3f, 0.81f, 0.7f, 0.0f, 0.0f, 0.5f},
{0.23f, 0.51f, 0.38f, 0.0f, 0.35f, 0.5f, 0.33f, 1.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.29f, 0.0f, 0.25f, 0.68f, 0.39f, 0.58f, 0.36f, 0.81f, 0.64f, 0.38f, 0.92f, 0.5f},
{0.39f, 0.51f, 0.27f, 0.38f, 0.12f, 0.5f, 0.35f, 0.78f, 0.5f, 0.0f, 0.5f, 0.0f, 0.3f, 0.0f, 0.25f, 0.35f, 0.5f, 0.8f, 0.7f, 0.81f, 0.5f, 0.0f, 0.5f, 0.5f},
{0.0f, 0.25f, 0.5f, 0.0f, 0.35f, 0.5f, 0.23f, 0.2f, 0.75f, 0.0f, 0.5f, 0.0f, 0.22f, 0.0f, 0.25f, 0.0f, 0.47f, 0.0f, 0.3f, 0.81f, 0.5f, 0.8f, 0.5f, 0.5f},
{1.0f, 0.51f, 0.24f, 0.0f, 0.0f, 0.35f, 0.42f, 0.26f, 0.75f, 0.14f, 0.69f, 0.0f, 0.67f, 0.55f, 0.97f, 0.82f, 0.7f, 1.0f, 0.42f, 0.84f, 0.67f, 0.3f, 0.47f, 0.5f},
{0.75f, 0.51f, 0.29f, 0.0f, 0.49f, 0.5f, 0.55f, 0.16f, 0.69f, 0.08f, 0.2f, 0.76f, 0.29f, 0.76f, 1.0f, 0.46f, 0.8f, 1.0f, 0.39f, 0.79f, 0.27f, 0.0f, 0.68f, 0.5f},
{0.0f, 0.5f, 0.53f, 0.0f, 0.13f, 0.39f, 0.38f, 0.74f, 0.54f, 0.2f, 0.0f, 0.0f, 0.55f, 0.52f, 0.31f, 0.0f, 0.17f, 0.73f, 0.28f, 0.87f, 0.24f, 0.0f, 0.29f, 0.5f},
{0.5f, 0.77f, 0.52f, 0.0f, 0.35f, 0.5f, 0.44f, 0.5f, 0.65f, 0.16f, 0.0f, 0.0f, 0.0f, 0.18f, 0.0f, 0.0f, 0.75f, 0.8f, 0.0f, 0.81f, 0.49f, 0.0f, 0.44f, 0.5f},
{0.89f, 0.91f, 0.37f, 0.0f, 0.35f, 0.5f, 0.51f, 0.62f, 0.54f, 0.0f, 0.0f, 0.0f, 0.37f, 0.0f, 1.0f, 0.04f, 0.08f, 0.72f, 0.04f, 0.77f, 0.49f, 0.0f, 0.58f, 0.5f},
{1.0f, 0.51f, 0.51f, 0.37f, 0.0f, 0.5f, 0.51f, 0.1f, 0.5f, 0.11f, 0.5f, 0.0f, 0.0f, 0.0f, 0.25f, 0.35f, 0.65f, 0.65f, 0.32f, 0.79f, 0.49f, 0.2f, 0.35f, 0.5f},
{0.0f, 0.51f, 0.51f, 0.82f, 0.06f, 0.5f, 0.57f, 0.0f, 0.32f, 0.15f, 0.5f, 0.21f, 0.15f, 0.0f, 0.25f, 0.24f, 0.6f, 0.8f, 0.1f, 0.75f, 0.55f, 0.25f, 0.69f, 0.5f},
{0.12f, 0.9f, 0.67f, 0.0f, 0.35f, 0.5f, 0.5f, 0.21f, 0.29f, 0.12f, 0.6f, 0.0f, 0.35f, 0.36f, 0.25f, 0.08f, 0.5f, 1.0f, 0.27f, 0.83f, 0.51f, 0.1f, 0.25f, 0.5f},
{0.43f, 0.76f, 0.23f, 0.0f, 0.28f, 0.36f, 0.5f, 0.0f, 0.59f, 0.0f, 0.5f, 0.24f, 0.16f, 0.91f, 0.08f, 0.17f, 0.5f, 0.8f, 0.45f, 0.81f, 0.5f, 0.0f, 0.58f, 0.5f},
{0.4f, 0.51f, 0.25f, 0.0f, 0.3f, 0.28f, 0.39f, 0.15f, 0.75f, 0.0f, 0.5f, 0.39f, 0.3f, 0.82f, 0.25f, 0.33f, 0.74f, 0.76f, 0.41f, 0.81f, 0.47f, 0.23f, 0.5f, 0.5f},
{0.68f, 0.5f, 0.93f, 0.0f, 0.31f, 0.62f, 0.26f, 0.07f, 0.85f, 0.0f, 0.66f, 0.0f, 0.83f, 0.0f, 0.05f, 0.0f, 0.75f, 0.54f, 0.32f, 0.76f, 0.37f, 0.29f, 0.56f, 0.5f},
{1.0f, 0.27f, 0.22f, 0.0f, 0.35f, 0.5f, 0.82f, 0.13f, 0.75f, 0.0f, 0.0f, 0.24f, 0.3f, 0.88f, 0.34f, 0.0f, 0.5f, 1.0f, 0.48f, 0.71f, 0.37f, 0.0f, 0.35f, 0.5f},
{0.76f, 0.51f, 0.35f, 0.0f, 0.49f, 0.5f, 0.87f, 0.67f, 1.0f, 0.32f, 0.09f, 0.95f, 0.56f, 0.72f, 1.0f, 0.04f, 0.76f, 0.11f, 0.46f, 0.88f, 0.72f, 0.0f, 0.38f, 0.5f},
{0.75f, 0.51f, 0.24f, 0.45f, 0.16f, 0.48f, 0.38f, 0.58f, 0.75f, 0.16f, 0.81f, 0.0f, 0.3f, 0.4f, 0.31f, 0.37f, 0.5f, 1.0f, 0.54f, 0.85f, 0.83f, 0.43f, 0.46f, 0.5f},
{0.31f, 0.51f, 0.43f, 0.0f, 0.35f, 0.5f, 0.34f, 0.26f, 0.53f, 0.0f, 0.63f, 0.0f, 0.22f, 0.0f, 0.39f, 0.0f, 0.8f, 0.0f, 0.44f, 0.81f, 0.51f, 0.0f, 0.5f, 0.5f},
{0.72f, 0.82f, 1.0f, 0.0f, 0.35f, 0.5f, 0.37f, 0.47f, 0.54f, 0.0f, 0.5f, 0.0f, 0.45f, 0.0f, 0.39f, 0.0f, 0.39f, 0.0f, 0.48f, 0.81f, 0.6f, 0.0f, 0.71f, 0.5f},
{0.81f, 0.76f, 0.19f, 0.0f, 0.18f, 0.7f, 0.4f, 0.3f, 0.54f, 0.17f, 0.4f, 0.0f, 0.42f, 0.23f, 0.47f, 0.12f, 0.48f, 0.0f, 0.49f, 0.53f, 0.36f, 0.34f, 0.56f, 0.5f},
{0.57f, 0.49f, 0.31f, 0.0f, 0.35f, 0.5f, 0.46f, 0.0f, 0.68f, 0.0f, 0.5f, 0.46f, 0.3f, 1.0f, 0.23f, 0.3f, 0.5f, 1.0f, 0.31f, 1.0f, 0.38f, 0.0f, 0.5f, 0.5f},
{0.0f, 0.25f, 0.5f, 0.0f, 0.35f, 0.5f, 0.08f, 0.36f, 0.69f, 1.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.96f, 0.5f, 1.0f, 0.92f, 0.97f, 0.5f, 1.0f, 0.0f, 0.5f},
{0.0f, 0.25f, 0.5f, 0.0f, 0.35f, 0.5f, 0.16f, 0.85f, 0.5f, 0.28f, 0.5f, 0.37f, 0.3f, 0.0f, 0.25f, 0.89f, 0.5f, 1.0f, 0.89f, 0.24f, 0.5f, 1.0f, 1.0f, 0.5f},
{1.0f, 0.37f, 0.51f, 0.0f, 0.35f, 0.5f, 0.0f, 1.0f, 0.97f, 0.0f, 0.5f, 0.02f, 0.2f, 0.0f, 0.2f, 0.0f, 0.46f, 0.0f, 0.3f, 0.81f, 0.5f, 0.78f, 0.48f, 0.5f},
{0.0f, 0.25f, 0.5f, 0.0f, 0.76f, 0.94f, 0.3f, 0.33f, 0.76f, 0.0f, 0.68f, 0.0f, 0.59f, 0.0f, 0.59f, 0.1f, 0.5f, 0.0f, 0.5f, 0.81f, 0.5f, 0.7f, 0.0f, 0.5f},
{0.5f, 0.41f, 0.23f, 0.45f, 0.77f, 0.0f, 0.4f, 0.65f, 0.95f, 0.0f, 0.5f, 0.33f, 0.5f, 0.0f, 0.25f, 0.0f, 0.7f, 0.65f, 0.18f, 0.32f, 1.0f, 0.0f, 0.06f, 0.5f},
};
//-----------------------------------------------------------------------------
JX10Processor::JX10Processor ()
: currentProgram (0)
{
setControllerClass (JX10Controller::uid);
allocParameters (NPARAMS);
}
//-----------------------------------------------------------------------------
JX10Processor::~JX10Processor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Processor::initialize (FUnknown* context)
{
tresult res = Base::initialize (context);
if (res == kResultTrue)
{
addEventInput (USTRING("MIDI in"), 1);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
const float* newParams = programParams[0];
if (newParams)
{
for (int32 i = 0; i < NPARAMS; i++)
params[i] = newParams[i];
}
//initialise...
for(int32 v=0; v<synthData.numVoices; v++)
{
memset (&synthData.voice[v], 0, sizeof (VOICE));
synthData.voice[v].dp = synthData.voice[v].dp2 = 1.0f;
synthData.voice[v].saw = synthData.voice[v].p = synthData.voice[v].p2 = 0.0f;
synthData.voice[v].env = synthData.voice[v].envd = synthData.voice[v].envl = 0.0f;
synthData.voice[v].fenv = synthData.voice[v].fenvd = synthData.voice[v].fenvl = 0.0f;
synthData.voice[v].f0 = synthData.voice[v].f1 = synthData.voice[v].f2 = 0.0f;
synthData.voice[v].note = 0;
}
lfo = modwhl = filtwhl = press = fzip = 0.0f;
rezwhl = pbend = ipbend = 1.0f;
volume = 0.0005f;
K = mode = lastnote = synthData.sustain = synthData.activevoices = 0;
noise = 22222;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Processor::terminate ()
{
return Base::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Processor::setActive (TBool state)
{
if (state)
{
synthData.init ();
for (auto& v : synthData.voice)
clearVoice (v);
recalculate ();
}
return Base::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API JX10Processor::setProcessing (TBool state)
{
if (state)
{
synthData.init ();
synthData.clearEvents ();
}
Base::setProcessing (state);
return kResultTrue;
}
//-----------------------------------------------------------------------------
void JX10Processor::setParameter (ParamID index, ParamValue newValue, int32 sampleOffset)
{
if (index < NPARAMS)
Base::setParameter (index, newValue, sampleOffset);
else if (index == BaseController::kPresetParam) // program change
{
auto newProgramIndex = std::min<int32> (kNumPrograms - 1, (int32)(newValue * kNumPrograms));
if (currentProgram != newProgramIndex)
{
currentProgram = newProgramIndex;
const float* newParams = programParams[currentProgram];
if (newParams)
{
for (int32 i = 0; i < NPARAMS; i++)
params[i] = newParams[i];
recalculate ();
}
}
}
else if (index == BaseController::kModWheelParam) // mod wheel
{
newValue *= 127.;
modwhl = static_cast<float> (0.000005f * (newValue*newValue));
}
else if (index == BaseController::kPitchBendParam) // pitch bend
{
if (newValue <= 1)
newValue = (newValue - 0.5) * 0x2000;
ipbend = (float)exp (0.000014102 * (double)newValue);
pbend = 1.0f / ipbend;
}
else if (index == BaseController::kBreathParam)
{
newValue *= 127.;
filtwhl = static_cast<float> (0.02f * newValue);
}
else if (index == BaseController::kCtrler3Param)
{
newValue *= 127.;
filtwhl = static_cast<float> (-0.03f * newValue);
}
else if (index == BaseController::kExpressionParam)
{
newValue *= 127.;
rezwhl = static_cast<float> (0.0065f * (154 - newValue));
}
else if (index == BaseController::kAftertouchParam)
{
newValue *= 127.;
press = static_cast<float> (0.00001f * (newValue * newValue));
}
}
//-----------------------------------------------------------------------------
void JX10Processor::setCurrentProgram (Steinberg::uint32 val)
{
if (val < kNumPrograms)
currentProgram = val;
}
//-----------------------------------------------------------------------------
void JX10Processor::setCurrentProgramNormalized (ParamValue val)
{
setCurrentProgram (std::min<int32> (kNumPrograms - 1, (int32)(val * kNumPrograms)));
}
//-----------------------------------------------------------------------------
void JX10Processor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
int32 frame=0, frames, v;
float oL, oR, e, vib, pwm, pb=pbend, ipb=ipbend, gl=glide;
float x, y, hpf=0.997f, min=1.0f, w=0.0f, ww=noisemix;
float ff, fe=filtenv, fq=filtq * rezwhl, fx=1.97f-0.85f*fq, fz=fzip;
int32 k=K;
Steinberg::uint32 r;
vib = (float)sin(lfo);
ff = filtf + filtwhl + (filtlfo + press) * vib; //have to do again here as way that
pwm = 1.0f + vib * (modwhl + pwmdep); //below triggers on k was too cheap!
vib = 1.0f + vib * (modwhl + vibrato);
synthData.eventPos = 0;
if (synthData.activevoices > 0 || synthData.hasEvents ())
{
while (frame<sampleFrames)
{
frames = synthData.events[synthData.eventPos].sampleOffset;
if (frames>sampleFrames) frames = sampleFrames;
frames -= frame;
frame += frames;
while (--frames>=0)
{
VOICE *V = synthData.voice.data ();
oL = oR = 0.0f;
noise = (noise * 196314165) + 907633515;
r = (noise & 0x7FFFFF) + 0x40000000; //generate noise + fast convert to float
w = *(float *)&r;
w = ww * (w - 3.0f);
if (--k<0)
{
lfo += dlfo;
if (lfo>PI) lfo -= TWOPI;
vib = (float)sin(lfo);
ff = filtf + filtwhl + (filtlfo + press) * vib;
pwm = 1.0f + vib * (modwhl + pwmdep);
vib = 1.0f + vib * (modwhl + vibrato);
k = KMAX;
}
for(v=0; v<synthData.numVoices; v++) //for each voice
{
e = V->env;
if (e > SILENCE)
{ //Sinc-Loop Oscillator
x = V->p + V->dp;
if (x > min)
{
if (x > V->pmax)
{
x = V->pmax + V->pmax - x;
V->dp = -V->dp;
}
V->p = x;
x = V->sin0 * V->sinx - V->sin1; //sine osc
V->sin1 = V->sin0;
V->sin0 = x;
x = x / V->p;
}
else
{
V->p = x = - x;
V->dp = V->period * vib * pb * V->snaPitchbend; //set period for next cycle
V->pmax = (float)floor(0.5f + V->dp) - 0.5f;
V->dc = -0.5f * V->lev / V->pmax;
V->pmax *= PI;
V->dp = V->pmax / V->dp;
V->sin0 = V->lev * (float)sin(x);
V->sin1 = V->lev * (float)sin(x - V->dp);
V->sinx = 2.0f * (float)cos(V->dp);
if (x*x > .1f) x = V->sin0 / x; else x = V->lev; //was 0.01f;
}
y = V->p2 + V->dp2; //osc2
if (y > min)
{
if (y > V->pmax2)
{
y = V->pmax2 + V->pmax2 - y;
V->dp2 = -V->dp2;
}
V->p2 = y;
y = V->sin02 * V->sinx2 - V->sin12;
V->sin12 = V->sin02;
V->sin02 = y;
y = y / V->p2;
}
else
{
V->p2 = y = - y;
V->dp2 = V->period * V->detune * pwm * pb * V->snaPitchbend;
V->pmax2 = (float)floor(0.5f + V->dp2) - 0.5f;
V->dc2 = -0.5f * V->lev2 / V->pmax2;
V->pmax2 *= PI;
V->dp2 = V->pmax2 / V->dp2;
V->sin02 = V->lev2 * (float)sin(y);
V->sin12 = V->lev2 * (float)sin(y - V->dp2);
V->sinx2 = 2.0f * (float)cos(V->dp2);
if (y*y > .1f) y = V->sin02 / y; else y = V->lev2;
}
V->saw = V->saw * hpf + V->dc + x - V->dc2 - y; //integrated sinc = saw
x = V->saw + w;
V->env += V->envd * (V->envl - V->env);
if (k==KMAX) //filter freq update at LFO rate
{
if ((V->env+V->envl)>3.0f) { V->envd=dec; V->envl=sus; } //envelopes
V->fenv += V->fenvd * (V->fenvl - V->fenv);
if ((V->fenv+V->fenvl)>3.0f) { V->fenvd=fdec; V->fenvl=fsus; }
fz += 0.005f * (ff - fz); //filter zipper noise filter
y = V->fc * (float)exp (fz + fe * V->fenv) * ipb; //filter cutoff
if (y<0.005f) y =0.005f;
V->ff = y;
V->period += gl * (V->target - V->period); //glide
if (V->target < V->period) V->period += gl * (V->target - V->period);
}
if (V->ff > fx) V->ff = fx; //stability limit
V->f0 += V->ff * V->f1; //state-variable filter
V->f1 -= V->ff * (V->f0 + fq * V->f1 - x - V->f2);
V->f1 -= 0.2f * V->f1 * V->f1 * V->f1; //soft limit //was 0.08f
V->f2 = x;
float oneSample = V->env * V->f0 * V->snaVolume;
oL += oneSample * V->snaPanLeft;
oR += oneSample * V->snaPanRight;
}
V++;
}
*out1++ = oL;
*out2++ = oR;
}
if (frame<sampleFrames)
{
noteEvent (synthData.events[synthData.eventPos]);
++synthData.eventPos;
}
}
synthData.activevoices = synthData.numVoices;
for(v=0; v<synthData.numVoices; v++)
{
if (synthData.voice[v].env<SILENCE) //choke voices
{
synthData.voice[v].env = synthData.voice[v].envl = 0.0f;
synthData.voice[v].f0 = synthData.voice[v].f1 = synthData.voice[v].f2 = 0.0f;
synthData.activevoices--;
}
}
}
else
{
// complete empty block
memset (out1, 0, sampleFrames * sizeof (float));
memset (out2, 0, sampleFrames * sizeof (float));
}
fzip = fz;
K = k;
}
//-----------------------------------------------------------------------------
void JX10Processor::preProcess ()
{
synthData.clearEvents ();
}
//-----------------------------------------------------------------------------
void JX10Processor::processEvent (const Event& e)
{
synthData.processEvent (e);
}
//-----------------------------------------------------------------------------
void JX10Processor::noteEvent (const Event& event)
{
float p, l=100.0f; //louder than any envelope!
int32 v=0, tmp, held=0;
bool polyMode = (mode < 3);
bool _glide = !(mode == 0 || mode == 3);
bool legato = (mode == 1 || mode == 5);
if (event.type == Event::kNoteOnEvent)
{
auto& note = event.noteOn;
float velocity = note.velocity * 127;
if (veloff) velocity = 80;
if (!polyMode) //monophonic
{
if (synthData.voice[0].noteID != EndNoteID) //legato pitch change
{
for(tmp= (synthData.numVoices-1); tmp>0; tmp--) //queue any held notes
{
synthData.voice[tmp].note = synthData.voice[tmp - 1].note;
synthData.voice[tmp].noteID = synthData.voice[tmp - 1].noteID;
}
p = tune * (float)exp (-0.05776226505 * ((double)note.pitch + ANALOG * (double)v));
while (p<3.0f || (p * detune)<3.0f) p += p;
synthData.voice[0].target = p;
if ((_glide)==0) synthData.voice[v].period = p;
synthData.voice[0].fc = (float)exp (filtvel * (float)(velocity - 64)) / p;
synthData.voice[0].env += SILENCE + SILENCE; ///was missed out below if returned?
synthData.voice[0].note = note.pitch;
synthData.voice[0].noteID = note.noteId;
synthData.voice[0].snaVolume = 1.f;
synthData.voice[0].snaPanLeft = synthData.voice[v].snaPanRight = 1.f;
synthData.voice[0].snaPitchbend = 1.f;
return;
}
}
else //polyphonic
{
for(tmp=0; tmp<synthData.numVoices; tmp++) //replace quietest voice not in attack
{
if (synthData.voice[tmp].note > 0) held++;
if (synthData.voice[tmp].env<l && synthData.voice[tmp].envl<2.0f) { l=synthData.voice[tmp].env; v=tmp; }
}
}
p = tune * (float)exp (-0.05776226505 * ((double)note.pitch + ANALOG * (double)v));
while (p<3.0f || (p * detune)<3.0f) p += p;
synthData.voice[v].target = p;
synthData.voice[v].detune = detune;
tmp = 0;
if (_glide || legato)
{
if ((_glide) || held) tmp = note.pitch - lastnote; //glide
}
synthData.voice[v].period = p * (float)pow (1.059463094359, (double)tmp - glidedisp);
if (synthData.voice[v].period<3.0f) synthData.voice[v].period = 3.0f; //limit min period
synthData.voice[v].note = lastnote = note.pitch;
synthData.voice[v].noteID = note.noteId;
synthData.voice[v].fc = (float)exp (filtvel * (float)(velocity - 64)) / p; //filter tracking
synthData.voice[v].lev = voltrim * volume * (0.004f * (float)((velocity + 64) * (velocity + 64)) - 8.0f);
synthData.voice[v].lev2 = synthData.voice[v].lev * oscmix;
if (params[20]<0.5f) //force 180 deg phase difference for PWM
{
if (synthData.voice[v].dp>0.0f)
{
p = synthData.voice[v].pmax + synthData.voice[v].pmax - synthData.voice[v].p;
synthData.voice[v].dp2 = -synthData.voice[v].dp;
}
else
{
p = synthData.voice[v].p;
synthData.voice[v].dp2 = synthData.voice[v].dp;
}
synthData.voice[v].p2 = synthData.voice[v].pmax2 = p + PI * synthData.voice[v].period;
synthData.voice[v].dc2 = 0.0f;
synthData.voice[v].sin02 = synthData.voice[v].sin12 = synthData.voice[v].sinx2 = 0.0f;
}
if (!polyMode) //monophonic retriggering
{
synthData.voice[v].env += SILENCE + SILENCE;
}
else
{
//if (params[15] < 0.28f)
//{
// voice[v].f0 = voice[v].f1 = voice[v].f2 = 0.0f; //reset filter
// voice[v].env = SILENCE + SILENCE;
// voice[v].fenv = 0.0f;
//}
//else
synthData.voice[v].env += SILENCE + SILENCE; //anti-glitching trick
}
synthData.voice[v].envl = 2.0f;
synthData.voice[v].envd = att;
synthData.voice[v].fenvl = 2.0f;
synthData.voice[v].fenvd = fatt;
synthData.voice[v].snaVolume = 1.f;
synthData.voice[v].snaPanLeft = synthData.voice[v].snaPanRight = 1.f;
synthData.voice[v].snaPitchbend = 1.f;
}
else //note off
{
auto& note = event.noteOff;
if ((!polyMode) && (synthData.voice[0].noteID==note.noteId)) //monophonic (and current note)
{
for(v= (synthData.numVoices-1); v>0; v--)
{
if (synthData.voice[v].noteID!=EndNoteID) held = v; //any other notes queued?
}
if (held>0)
{
synthData.voice[v].note = synthData.voice[held].note;
synthData.voice[v].noteID = synthData.voice[held].noteID;
clearVoice (synthData.voice[held]);
p = tune * (float)exp (-0.05776226505 * ((double)synthData.voice[v].note + ANALOG * (double)v));
while (p<3.0f || (p * detune)<3.0f) p += p;
synthData.voice[v].target = p;
if ((_glide || legato)==0) synthData.voice[v].period = p;
synthData.voice[v].fc = 1.0f / p;
}
else
{
clearVoice (synthData.voice[v]);
}
}
else //polyphonic
{
for(v=0; v<synthData.numVoices; v++) if (synthData.voice[v].noteID==note.noteId) //any voices playing that note?
{
if (synthData.sustain==0)
{
clearVoice (synthData.voice[v]);
}
else synthData.voice[v].note = SustainNoteID;
}
}
}
}
//------------------------------------------------------------------------
void JX10Processor::clearVoice (VOICE& v)
{
v.envl = 0.0f;
v.envd = rel;
v.fenvl = 0.0f;
v.fenvd = frel;
v.note = 0;
v.noteID = EndNoteID;
}
//-----------------------------------------------------------------------------
void JX10Processor::recalculate ()
{
double ifs = 1.0 / getSampleRate ();
mode = std::min<int32>(5, static_cast<int32> (params[3] * 6));
noisemix = static_cast<float> (params[21] * params[21]);
voltrim = static_cast<float> ((3.2f - params[0] - 1.5f * noisemix) * (1.5f - 0.5f * params[7]));
noisemix *= 0.06f;
oscmix = static_cast<float> (params[0]);
semi = (float)floor(48.0f * params[1]) - 24.0f;
cent = static_cast<float> (15.876f * params[2] - 7.938f);
cent = 0.1f * (float)floor(cent * cent * cent);
detune = (float)pow (1.059463094359f, - semi - 0.01f * cent);
tune = static_cast<float> (-23.376f - 2.0f * params[23] - 12.0f * (float)floor(params[22] * 4.9));
tune = static_cast<float> (getSampleRate ()) * powf (1.059463094359f, tune);
vibrato = pwmdep = static_cast<float> (0.2f * (params[20] - 0.5f) * (params[20] - 0.5f));
if (params[20]<0.5f) vibrato = 0.0f;
lfoHz = (float)exp (7.0f * params[19] - 4.0f);
dlfo = lfoHz * (float)(ifs * TWOPI * KMAX);
filtf = static_cast<float> (8.0f * params[6] - 1.5f);
filtq = static_cast<float> ((1.0f - params[7]) * (1.0f - params[7])); ////// + 0.02f;
filtlfo = static_cast<float> (2.5f * params[9] * params[9]);
filtenv = static_cast<float> (12.0f * params[8] - 6.0f);
filtvel = static_cast<float> (0.1f * params[10] - 0.05f);
if (params[10]<0.05f) { veloff = 1; filtvel = 0; } else veloff = 0;
att = 1.0f - (float)exp (-ifs * exp (5.5 - 7.5 * params[15]));
dec = 1.0f - (float)exp (-ifs * exp (5.5 - 7.5 * params[16]));
sus = static_cast<float> (params[17]);
rel = 1.0f - (float)exp (-ifs * exp (5.5 - 7.5 * params[18]));
if (params[18]<0.01f) rel = 0.1f; //extra fast release
ifs *= KMAX; //lower update rate...
fatt = 1.0f - (float)exp (-ifs * exp (5.5 - 7.5 * params[11]));
fdec = 1.0f - (float)exp (-ifs * exp (5.5 - 7.5 * params[12]));
fsus = static_cast<float> (params[13] * params[13]);
frel = 1.0f - (float)exp (-ifs * exp (5.5 - 7.5 * params[14]));
if (params[4]<0.02f) glide = 1.0f; else
glide = 1.0f - (float)exp (-ifs * exp (6.0 - 7.0 * params[4]));
glidedisp = static_cast<float> (6.604f * params[5] - 3.302f);
glidedisp *= glidedisp * glidedisp;
}
}}} // namespaces
@@ -0,0 +1,149 @@
/*
* mdaJX10Processor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class JX10Processor : public BaseProcessor
{
public:
using Base = BaseProcessor;
JX10Processor ();
~JX10Processor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'MDAj'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
bool hasProgram () const SMTG_OVERRIDE { return true; }
Steinberg::uint32 getCurrentProgram () const SMTG_OVERRIDE { return currentProgram; }
Steinberg::uint32 getNumPrograms () const SMTG_OVERRIDE { return kNumPrograms; }
void setCurrentProgram (Steinberg::uint32 val) SMTG_OVERRIDE;
void setCurrentProgramNormalized (ParamValue val) SMTG_OVERRIDE;
static const int32 kNumPrograms = 52;
static float programParams[kNumPrograms][24];
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new JX10Processor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653544D, 0x44416A6D, 0x6461206A, 0x78313000);
#else
inline static DECLARE_UID (uid, 0x82CD49DE, 0x13D743BA, 0xABDAC299, 0x1CE06F7C);
#endif
//-----------------------------------------------------------------------------
protected:
struct VOICE //voice state
{
float period;
float p; //sinc position
float pmax; //loop length
float dp; //delta
float sin0; //sine osc
float sin1;
float sinx;
float dc; //dc offset
float detune;
float p2; //sinc position
float pmax2; //loop length
float dp2; //delta
float sin02; //sine osc
float sin12;
float sinx2;
float dc2; //dc offset
float fc; //filter cutoff root
float ff; //filter cutoff
float f0; //filter buffers
float f1;
float f2;
float saw;
//float vca; //current level ///eliminate osc1 level when separate amp & filter envs?
//float env; //envelope
//float att; //attack
//float dec; //decay
float env;
float envd;
float envl;
float fenv;
float fenvd;
float fenvl;
float lev; //osc levels
float lev2;
float target; //period target
int32 note; //remember what note triggered this
int32 noteID; // SNA addition
float snaPitchbend;// SNA addition
float snaVolume;// SNA addition
float snaPanLeft; // SNA addition
float snaPanRight; // SNA addition
};
static constexpr int32 kEventBufferSize = 64;
static constexpr int32 kNumVoices = 8;
using SynthDataT = SynthData<VOICE, kEventBufferSize, kNumVoices>;
void preProcess () SMTG_OVERRIDE;
void processEvent (const Event& event) SMTG_OVERRIDE;
void recalculate () SMTG_OVERRIDE;
void noteEvent (const Event& event);
void setParameter (ParamID index, ParamValue newValue, int32 sampleOffset) SMTG_OVERRIDE;
void clearVoice (VOICE& v);
SynthDataT synthData;
static const int32 KMAX = 32;
///global internal variables
float semi, cent;
float tune, detune;
float filtf, fzip, filtq, filtlfo, filtenv, filtvel, filtwhl;
float oscmix, noisemix;
float att, dec, sus, rel, fatt, fdec, fsus, frel;
float lfo, dlfo, modwhl, press, pbend, ipbend, rezwhl;
float velsens, volume, voltrim;
float vibrato, pwmdep, lfoHz, glide, glidedisp;
int32 K, lastnote, veloff, mode;
Steinberg::uint32 noise;
Steinberg::uint32 currentProgram;
};
}}} // namespaces
@@ -0,0 +1,104 @@
/*
* mdaLeslieController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaLeslieController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
LeslieController::LeslieController ()
{
}
//-----------------------------------------------------------------------------
LeslieController::~LeslieController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LeslieController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
auto* speedParam = new IndexedParameter (USTRING("Speed Mode"), USTRING(""), 2, 0.15, ParameterInfo::kCanAutomate | ParameterInfo::kIsList, kParam0);
speedParam->setIndexString (0, UString128("STOP"));
speedParam->setIndexString (1, UString128("SLOW"));
speedParam->setIndexString (2, UString128("FAST"));
parameters.addParameter (speedParam);
parameters.addParameter (new ScaledParameter (USTRING("Lo Width"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, kParam1, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Lo Throb"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, kParam2, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Hi Width"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, kParam3, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Hi Depth"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, kParam4, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Hi Throb"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, kParam5, 0, 100, true));
parameters.addParameter (USTRING("X-Over"), USTRING("Hz"), 0, 0.15, ParameterInfo::kCanAutomate, kParam6);
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.15, ParameterInfo::kCanAutomate, kParam7, -20, 20, true));
parameters.addParameter (new ScaledParameter (USTRING("Speed"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, kParam8, 0, 200, true));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LeslieController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LeslieController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case kParam6:
{
result.printInt (10*int ((float)pow (10.0f,(float)(1.179f + valueNormalized))));
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LeslieController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,70 @@
/*
* mdaLeslieController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaLeslieProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class LeslieController : public BaseController
{
public:
LeslieController ();
~LeslieController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
enum ParameterIDs {
kParam0,
kParam1,
kParam2,
kParam3,
kParam4,
kParam5,
kParam6,
kParam7,
kParam8,
kNumParams
};
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new LeslieController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461486D, 0x6461206C, 0x65736C69);
#else
inline static DECLARE_UID (uid, 0x3AC7BB1E, 0xE8C74788, 0x8D29C9BF, 0x9D9A51F8);
#endif
};
}}} // namespaces
@@ -0,0 +1,236 @@
/*
* mdaLeslieProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaLeslieProcessor.h"
#include "mdaLeslieController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
LeslieProcessor::LeslieProcessor ()
{
setControllerClass (LeslieController::uid);
allocParameters (9);
}
//-----------------------------------------------------------------------------
LeslieProcessor::~LeslieProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LeslieProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[LeslieController::kParam0] = 0.66f;
params[LeslieController::kParam7] = 0.50f;
params[LeslieController::kParam6] = 0.48f;
params[LeslieController::kParam3] = 0.70f;
params[LeslieController::kParam4] = 0.60f;
params[LeslieController::kParam5] = 0.70f;
params[LeslieController::kParam2] = 0.50f;
params[LeslieController::kParam1] = 0.50f;
params[LeslieController::kParam8] = 0.60f;
size = 256; hpos = 0;
hbuf = new float[size];
fbuf1 = fbuf2 = 0.0f;
twopi = 6.2831853f;
chp = dchp = clp = dclp = shp = dshp = slp = dslp = 0.0f;
lspd = 0.0f; hspd = 0.0f;
lphi = 0.0f; hphi = 1.6f;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LeslieProcessor::terminate ()
{
if (hbuf) delete [] hbuf;
hbuf = nullptr;
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LeslieProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LeslieProcessor::setProcessing (TBool state)
{
if (state)
memset (hbuf, 0, size * sizeof (float));
BaseProcessor::setProcessing (state);
return kResultOk;
}
//-----------------------------------------------------------------------------
void LeslieProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, c, d, g=gain, h, l;
float fo=filo, fb1=fbuf1, fb2=fbuf2;
float hl=hlev, hs=hspd, ht, hm=hmom, hp=hphi, hw=hwid, hd=hdep;
float ll=llev, ls=lspd, lt, lm=lmom, lp=lphi, lw=lwid;
float hint, k0=0.03125f, k1=32.f; //k0 = 1/k1
int32 hdd, hdd2, k=0, hps=hpos;
ht=hset*(1.f-hm); //target speeds
lt=lset*(1.f-lm);
chp = (float)cos(hp); chp *= chp * chp; //set LFO values
clp = (float)cos(lp);
shp = (float)sin(hp);
slp = (float)sin(lp);
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1 + *++in2; //mono input
if (k) k--; else //linear piecewise approx to LFO waveforms
{
ls = (lm * ls) + lt; //tend to required speed
hs = (hm * hs) + ht;
lp += k1 * ls;
hp += k1 * hs;
dchp = (float)cos(hp + k1*hs);
dchp = k0 * (dchp * dchp * dchp - chp); //sin^3 level mod
dclp = k0 * ((float)cos(lp + k1*ls) - clp);
dshp = k0 * ((float)sin(hp + k1*hs) - shp);
dslp = k0 * ((float)sin(lp + k1*ls) - slp);
k= (int32)k1;
}
fb1 = fo * (fb1 - a) + a; //crossover
fb2 = fo * (fb2 - fb1) + fb1;
h = (g - hl * chp) * (a - fb2); //volume
l = (g - ll * clp) * fb2;
if (hps>0) hps--; else hps=200; //delay input pos
hint = hps + hd * (1.0f + chp); //delay output pos
hdd = (int)hint;
hint = hint - hdd; //linear interpolation
hdd2 = hdd + 1;
if (hdd>199) { if (hdd>200) hdd -= 201; hdd2 -= 201; }
*(hbuf + hps) = h; //delay input
a = *(hbuf + hdd);
h += a + hint * ( *(hbuf + hdd2) - a); //delay output
c = l + h;
d = l + h;
h *= hw * shp;
l *= lw * slp;
d += l - h;
c += h - l;
*++out1 = c; //output
*++out2 = d;
chp += dchp;
clp += dclp;
shp += dshp;
slp += dslp;
}
lspd = ls;
hspd = hs;
hpos = hps;
lphi = (float)fmod(lp+(k1 -k)*ls,twopi);
hphi = (float)fmod(hp+(k1 -k)*hs,twopi);
if (fabs (fb1)>1.0e-10) fbuf1=fb1; else fbuf1=0.0f; //catch denormals
if (fabs (fb2)>1.0e-10) fbuf2=fb2; else fbuf2=0.0f;
}
//-----------------------------------------------------------------------------
void LeslieProcessor::recalculate ()
{
float ifs = 1.0f / (float)getSampleRate ();
float spd = static_cast<float> (twopi * ifs * 2.0f * params[LeslieController::kParam8]);
filo = 1.f - (float)pow (10.0f, (float)(params[LeslieController::kParam6] * (2.27f - 0.54f * params[LeslieController::kParam6]) - 1.92f));
switch ((int)(params[LeslieController::kParam0]*2.))
{
case 0:
{
lset = 0.00f; hset = 0.00f;
lmom = 0.12f; hmom = 0.10f;
break;
}
case 1:
{
lset = 0.49f; hset = 0.66f;
lmom = 0.27f; hmom = 0.18f;
break;
}
case 2:
{
lset = 5.31f; hset = 6.40f;
lmom = 0.14f; hmom = 0.09f;
break;
}
}
hmom = (float)pow (10.0f, -ifs / hmom);
lmom = (float)pow (10.0f, -ifs / lmom);
hset *= spd;
lset *= spd;
gain = 0.4f * (float)pow (10.0f, (float)(2.0f * params[LeslieController::kParam7] - 1.0f));
lwid = static_cast<float> (params[LeslieController::kParam1] * params[LeslieController::kParam1]);
llev = static_cast<float> (gain * 0.9f * params[LeslieController::kParam2] * params[LeslieController::kParam2]);
hwid = static_cast<float> (params[LeslieController::kParam3] * params[LeslieController::kParam3]);
hdep = static_cast<float> (params[LeslieController::kParam4] * params[LeslieController::kParam4] * getSampleRate () / 760.0f);
hlev = static_cast<float> (gain * 0.9f * params[LeslieController::kParam5] * params[LeslieController::kParam5]);
}
}}} // namespaces
@@ -0,0 +1,72 @@
/*
* mdaLeslieProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class LeslieProcessor : public BaseProcessor
{
public:
LeslieProcessor ();
~LeslieProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaH'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new LeslieProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461486D, 0x6461206C, 0x65736C69);
#else
inline static DECLARE_UID (uid, 0xFBD3AD80, 0x9E2847E0, 0xB87CDEC3, 0x5C0469B1);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float filo; //crossover filter coeff
float fbuf1, fbuf2; //filter buffers
float twopi; //speed, target, momentum, phase, width, ampmod, freqmod...
float hspd, hset, hmom, hphi, hwid, hlev, hdep;
float lspd, lset, lmom, lphi, lwid, llev, gain;
float *hbuf; //HF delay buffer
int32 size, hpos; //buffer length & pointer
float chp, dchp, clp, dclp, shp, dshp, slp, dslp;
};
}}} // namespaces
@@ -0,0 +1,107 @@
/*
* mdaLimiterController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaLimiterController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
LimiterController::LimiterController ()
{
}
//-----------------------------------------------------------------------------
LimiterController::~LimiterController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LimiterController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING("Thresh"), USTRING("dB"), 0, 0, ParameterInfo::kCanAutomate, pid++, -20, 20, true));
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0, ParameterInfo::kCanAutomate, pid++, -20, 20, true));
parameters.addParameter (USTRING("Release"), USTRING("ms"), 0, 0.6, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (USTRING("Attack"), UString128(kMicroSecondsString), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
auto* kneeParam = new IndexedParameter (USTRING("Knee"), nullptr, 1, 0, ParameterInfo::kCanAutomate | ParameterInfo::kIsList, pid++);
kneeParam->setIndexString (0, UString128("HARD"));
kneeParam->setIndexString (1, UString128("SOFT"));
parameters.addParameter (kneeParam);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LimiterController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LimiterController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case 2:
{
float att = static_cast<float> (pow (10.0, -2.0 * valueNormalized));
result.printInt (static_cast<int64> (-301030.1 / (getSampleRate () * log10(1.0 - att))));
break;
}
case 3:
{
float rel = static_cast<float> (pow (10.0, -2.0 - (3.0 * valueNormalized)));
result.printInt (static_cast<int64> (-301.0301 / (getSampleRate () * log10(1.0 - rel))));
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LimiterController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,58 @@
/*
* mdaLimiterController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaLimiterProcessor.h"
using namespace Steinberg::Vst;
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class LimiterController : public BaseController
{
public:
LimiterController ();
~LimiterController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new LimiterController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x64614C6D, 0x6461206C, 0x696D6974);
#else
inline static DECLARE_UID (uid, 0x886C856F, 0x7C164A28, 0x9AD212A9, 0x857386A0);
#endif
};
}}} // namespaces
@@ -0,0 +1,207 @@
/*
* mdaLimiterProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaLimiterProcessor.h"
#include "mdaLimiterController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
LimiterProcessor::LimiterProcessor ()
{
setControllerClass (LimiterController::uid);
allocParameters (5);
}
//-----------------------------------------------------------------------------
LimiterProcessor::~LimiterProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LimiterProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING ("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING ("Stereo Out"), SpeakerArr::kStereo);
params[0] = (float)0.60; // thresh
params[1] = (float)0.60; // trim
params[2] = (float)0.15; // attack
params[3] = (float)0.50; // release
params[4] = (float)0.40; // knee
gain = 1.0;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LimiterProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LimiterProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
void LimiterProcessor::checkSilence (ProcessData& /*data*/)
{
}
//-----------------------------------------------------------------------------
void LimiterProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float g, at, re, tr, th, lev, ol, or_;
th = thresh;
g = gain;
at = att;
re = rel;
tr = trim;
if (data.inputs[0].silenceFlags & 3) // don't process if input (stereo=3 (first 2 bits)) is silent
{
if (in1 != out1)
memset (out1, 0, sampleFrames * sizeof (float));
if (in2 != out2)
memset (out2, 0, sampleFrames * sizeof (float));
data.outputs[0].silenceFlags = 3;
// keep computing the gain value
if (params[4] > 0.5) // soft knee
{
while (--sampleFrames >= 0)
{
if (g > 1)
{
g = g - at * (g - 1);
}
else
{
g = g + re * (1 - g);
}
}
}
else
{
while (--sampleFrames >= 0)
{
// only below threshold
g = g + (float)(re * (1.0 - g));
}
}
gain = g;
return;
}
data.outputs[0].silenceFlags = 0;
--in1;
--in2;
--out1;
--out2;
if (params[4] > 0.5) // soft knee
{
while (--sampleFrames >= 0)
{
ol = *++in1;
or_ = *++in2;
lev = (float)(1.0 / (1.0 + th * fabs (ol + or_)));
if (g > lev)
{
g = g - at * (g - lev);
}
else
{
g = g + re * (lev - g);
}
*++out1 = (ol * tr * g);
*++out2 = (or_ * tr * g);
}
}
else
{
while (--sampleFrames >= 0)
{
ol = *++in1;
or_ = *++in2;
lev = (float)(0.5 * g * fabs (ol + or_));
if (lev > th)
{
g = g - (at * (lev - th));
}
else // below threshold
{
g = g + (float)(re * (1.0 - g));
}
*++out1 = (ol * tr * g);
*++out2 = (or_ * tr * g);
}
}
gain = g;
}
//-----------------------------------------------------------------------------
void LimiterProcessor::recalculate ()
{
if (params[4] > 0.5) // soft knee
{
thresh = static_cast<float> (pow (10.0, 1.0 - (2.0 * params[0])));
}
else // hard knee
{
thresh = static_cast<float> (pow (10.0, (2.0 * params[0]) - 2.0));
}
trim = static_cast<float> (pow (10.0, (2.0 * params[1]) - 1.0));
att = static_cast<float> (pow (10.0, -2.0 * params[2]));
rel = static_cast<float> (pow (10.0, -2.0 - (3.0 * params[3])));
}
} // mda
} // Vst
} // Steinberg
@@ -0,0 +1,64 @@
/*
* mdaLimiterProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class LimiterProcessor : public BaseProcessor
{
public:
LimiterProcessor ();
~LimiterProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaL'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
void checkSilence (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new LimiterProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x64614C6D, 0x6461206C, 0x696D6974);
#else
inline static DECLARE_UID (uid, 0xE13C8DA0, 0x72DE4A97, 0xA0890C28, 0x0BDA61F8);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float thresh, gain, att, rel, trim;
};
}}} // namespaces
@@ -0,0 +1,100 @@
/*
* mdaLoudnessController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaLoudnessController.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
LoudnessController::LoudnessController ()
{
}
//-----------------------------------------------------------------------------
LoudnessController::~LoudnessController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LoudnessController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
ParamID pid = 0;
parameters.addParameter (USTRING("Loudness"), USTRING("dB"), 0, 0.15, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (USTRING("Output"), USTRING("dB"), 0, 0.6, ParameterInfo::kCanAutomate, pid++);
auto* linkParam = new IndexedParameter (USTRING("Link"), USTRING(""), 1, 0.5, ParameterInfo::kCanAutomate | ParameterInfo::kIsList, pid++);
linkParam->setIndexString (0, UString128("Off"));
linkParam->setIndexString (1, UString128("On"));
parameters.addParameter (linkParam);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LoudnessController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LoudnessController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case 0:
case 1:
{
float tmp = static_cast<float> (valueNormalized + valueNormalized - 1.0f);
float igain = 60.0f * tmp * tmp;
if (tmp<0.0f) igain *= -1.0f;
result.printFloat (igain);
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LoudnessController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,56 @@
/*
* mdaLoudnessController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaLoudnessProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class LoudnessController : public BaseController
{
public:
LoudnessController ();
~LoudnessController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new LoudnessController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x64616C6D, 0x6461206C, 0x6F75646E);
#else
inline static DECLARE_UID (uid, 0x9184DDF5, 0x6A2B4C5B, 0xA51BF670, 0x2A8B1BB0);
#endif
};
}}} // namespaces
@@ -0,0 +1,215 @@
/*
* mdaLoudnessProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaLoudnessProcessor.h"
#include "mdaLoudnessController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
static
float loudness[14][3] = { {402.f, 0.0025f, 0.00f}, //-60dB
{334.f, 0.0121f, 0.00f},
{256.f, 0.0353f, 0.00f},
{192.f, 0.0900f, 0.00f},
{150.f, 0.2116f, 0.00f},
{150.f, 0.5185f, 0.00f},
{ 1.0f, 0.0f, 0.00f}, //0dB
{33.7f, 5.5f, 1.00f},
{92.0f, 8.7f, 0.62f},
{63.7f, 18.4f, 0.44f},
{42.9f, 48.2f, 0.30f},
{37.6f, 116.2f, 0.18f},
{22.9f, 428.7f, 0.09f}, //+60dB
{ 0.0f, 0.0f, 0.00f} };
//-----------------------------------------------------------------------------
LoudnessProcessor::LoudnessProcessor ()
{
setControllerClass (LoudnessController::uid);
allocParameters (3);
}
//-----------------------------------------------------------------------------
LoudnessProcessor::~LoudnessProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LoudnessProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.70f; //loudness
params[1] = 0.50f; //output
params[2] = 0.35f; //link
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LoudnessProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API LoudnessProcessor::setActive (TBool state)
{
if (state)
{
Z0 = Z1 = Z2 = Z3 = 0.0f;
}
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
void LoudnessProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
if ((data.inputs[0].silenceFlags & 3) && Z0 == 0 && Z1 == 0 && Z2 == 0 && Z3 == 0) // don't process if input is silent
{
if (in1 != out1)
memset (out1, 0, sampleFrames * sizeof (float));
if (in2 != out2)
memset (out2, 0, sampleFrames * sizeof (float));
data.outputs[0].silenceFlags = 3;
return;
}
data.outputs[0].silenceFlags = 0;
float a, b, c, d;
float z0=Z0, z1=Z1, z2=Z2, z3=Z3;
float a0=A0, a1=A1, a2=A2, g=gain;
--in1;
--in2;
--out1;
--out2;
if (mode==0) //cut
{
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
z0 += a0 * (a - z0 + 0.3f * z1); a -= z0;
z1 += a0 * (a - z1); a -= z1;
a -= z0 * a1;
z2 += a0 * (b - z2 + 0.3f * z1); b -= z2;
z3 += a0 * (b - z3); b -= z3;
b -= z2 * a1;
c = a * g;
d = b * g;
*++out1 = c;
*++out2 = d;
}
}
else //boost
{
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
z0 += a0 * (a - z0);
z1 += a0 * (z0 - z1); a += a1 * (z1 - a2 * z0);
z2 += a0 * (b - z2);
z3 += a0 * (z2 - z3); b += a1 * (z3 - a2 * z2);
c = g * a;
d = g * b;
*++out1 = c;
*++out2 = d;
}
}
if (fabs (z1) < 1.0e-10 || fabs (z1)>100.0f) { Z0 = Z1 = 0.0f; } else { Z0 = z0; Z1 = z1; } //catch denormals
if (fabs (z3) < 1.0e-10 || fabs (z3)>100.0f) { Z2 = Z3 = 0.0f; } else { Z2 = z2; Z3 = z3; }
}
//-----------------------------------------------------------------------------
void LoudnessProcessor::recalculate ()
{
float f, tmp;
int32 i;
tmp = static_cast<float> (params[0] + params[0] - 1.0f);
igain = 60.0f * tmp * tmp;
if (tmp<0.0f) igain *= -1.0f;
tmp = static_cast<float> (params[1] + params[1] - 1.0f);
ogain = 60.0f * tmp * tmp;
if (tmp<0.0f) ogain *= -1.0f;
f = 0.1f * igain + 6.0f; //coefficient index + fractional part
i = (int32)f;
f -= (float)i;
tmp = loudness[i][0]; A0 = tmp + f * (loudness[i + 1][0] - tmp);
tmp = loudness[i][1]; A1 = tmp + f * (loudness[i + 1][1] - tmp);
tmp = loudness[i][2]; A2 = tmp + f * (loudness[i + 1][2] - tmp);
A0 = 1.0f - (float)exp (-6.283153f * A0 / getSampleRate ());
if (igain>0)
{
//if (mode==0) suspend(); //don't click when switching mode
mode=1;
}
else
{
//if (mode==1) suspend();
mode=0;
}
tmp = ogain;
if (params[2]>0.5f) //linked gain
{
tmp -= igain; if (tmp>0.0f) tmp = 0.0f; //limit max gain
}
gain = (float)pow (10.0f, 0.05f * tmp);
}
}}} // namespaces
@@ -0,0 +1,66 @@
/*
* mdaLoudnessProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class LoudnessProcessor : public BaseProcessor
{
public:
LoudnessProcessor ();
~LoudnessProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdal'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
void checkSilence (ProcessData& /*data*/) SMTG_OVERRIDE {}
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new LoudnessProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x64616C6D, 0x6461206C, 0x6F75646E);
#else
inline static DECLARE_UID (uid, 0xF2351D3C, 0xA6E94D47, 0x9E17EB3B, 0x6F30BA7C);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float Z0, Z1, Z2, Z3, A0, A1, A2, gain;
float igain, ogain;
int32 mode;
};
}}} // namespaces
@@ -0,0 +1,129 @@
/*
* mdaMultiBandController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaMultiBandController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
MultiBandController::MultiBandController ()
{
}
//-----------------------------------------------------------------------------
MultiBandController::~MultiBandController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API MultiBandController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
ParamID pid = 0;
auto* listenParam = new IndexedParameter (USTRING("Listen"), USTRING(""), 3, 0., ParameterInfo::kCanAutomate | ParameterInfo::kIsList, pid++);
listenParam->setIndexString (0, UString128("Low"));
listenParam->setIndexString (1, UString128("Mid"));
listenParam->setIndexString (2, UString128("High"));
listenParam->setIndexString (3, UString128("Output"));
parameters.addParameter (listenParam);
parameters.addParameter (USTRING("L <> M"), USTRING("Hz"), 0, 0.15, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (USTRING("M <> H"), USTRING("Hz"), 0, 0.6, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("L Comp"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 30, true));
parameters.addParameter (new ScaledParameter (USTRING("M Comp"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 30, true));
parameters.addParameter (new ScaledParameter (USTRING("H Comp"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 30, true));
parameters.addParameter (new ScaledParameter (USTRING("L Out"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -20, 20, true));
parameters.addParameter (new ScaledParameter (USTRING("M Out"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -20, 20, true));
parameters.addParameter (new ScaledParameter (USTRING("H Out"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -20, 20, true));
parameters.addParameter (USTRING("Attack"), UString128(kMicroSecondsString), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (USTRING("Release"), USTRING("ms"), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("Stereo Width"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (USTRING("Stereo"), USTRING(""), 1, 0.5, ParameterInfo::kCanAutomate, pid++);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API MultiBandController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API MultiBandController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case 1:
{
float fi1 = static_cast<float> (pow (10.0,valueNormalized - 1.70));
result.printInt (static_cast<int64> (getSampleRate () * fi1 * (0.098 + 0.09*fi1 + 0.5*powf (fi1,8.2f))));
break;
}
case 2:
{
float fi2 = static_cast<float> (pow (10.0,valueNormalized - 1.05));
result.printInt (static_cast<int64> (getSampleRate () * fi2 * (0.015 + 0.15*fi2 + 0.9*powf (fi2,8.2f))));
break;
}
case 9:
{
float att2 = static_cast<float> (pow (10.0, -0.05 -(2.0 * valueNormalized)));
result.printInt (static_cast<int64> (-301030.1 / (getSampleRate () * log10(1.0 - att2))));
break;
}
case 10:
{
float rel2 = static_cast<float> (pow (10.0, -2.0 - (3.0 * valueNormalized)));
result.printInt (static_cast<int64> (-301.0301 / (getSampleRate () * log10(1.0 - rel2))));
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API MultiBandController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,56 @@
/*
* mdaMultiBandController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaMultiBandProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class MultiBandController : public BaseController
{
public:
MultiBandController ();
~MultiBandController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new MultiBandController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x64614D6D, 0x6461206D, 0x756C7469);
#else
inline static DECLARE_UID (uid, 0x9C79B3F9, 0xD9C949CB, 0xA961571A, 0xFE118C95);
#endif
};
}}} // namespaces
@@ -0,0 +1,187 @@
/*
* mdaMultiBandProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaMultiBandProcessor.h"
#include "mdaMultiBandController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
MultiBandProcessor::MultiBandProcessor ()
{
setControllerClass (MultiBandController::uid);
allocParameters (13);
}
//-----------------------------------------------------------------------------
MultiBandProcessor::~MultiBandProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API MultiBandProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 1.00; //Listen: L/M/H/out
params[1] = 0.103; //xover1
params[2] = 0.878; //xover2
params[3] = 0.54; //L drive (1)
params[4] = 0.00; //M drive
params[5] = 0.60; //H drive
params[6] = 0.45; //L trim (2)
params[7] = 0.50; //M trim
params[8] = 0.50; //H trim
params[9] = 0.22; //attack (3)
params[10] = 0.602; //release (4)
params[11] = 0.55; //width
params[12] = 0.; //MS swap
fb1 = fb2 = fb3 = 0.f;
gain1 = gain2 = gain3 = 0.f;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API MultiBandProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API MultiBandProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
void MultiBandProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, c, d, l=fb3, m, h, s, sl=slev, tmp1, tmp2, tmp3;
float f1i=fi1, f1o=fo1, f2i=fi2, f2o=fo2, b1=fb1, b2=fb2;
float g1=gain1, d1=driv1, t1=trim1, a1=att1, r1=1.f - rel1;
float g2=gain2, d2=driv2, t2=trim2, a2=att2, r2=1.f - rel2;
float g3=gain3, d3=driv3, t3=trim3, a3=att3, r3=1.f - rel3;
int32 ms=mswap;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2; //process from here...
b = (ms)? -b : b;
s = (a - b) * sl; //keep stereo component for later
a += b;
b2 = (f2i * a) + (f2o * b2); //crossovers
b1 = (f1i * b2) + (f1o * b1);
l = (f1i * b1) + (f1o * l);
m=b2-l; h=a-b2;
tmp1 = (l>0)? l : -l; //l
g1 = (tmp1>g1)? g1+a1*(tmp1 -g1) : g1*r1;
tmp1 = 1.f / (1.f + d1 * g1);
tmp2 = (m > 0)? m : -m;
g2 = (tmp2>g2)? g2+a2*(tmp2-g2) : g2*r2;
tmp2 = 1.f / (1.f + d2 * g2);
tmp3 = (h>0)? h : -h;
g3 = (tmp3>g3)? g3+a3*(tmp3-g3) : g3*r3;
tmp3 = 1.f / (1.f + d3 * g3);
a = (l*tmp3*t1) + (m*tmp2*t2) + (h*tmp3*t3);
c = a + s; // output
d = (ms)? s - a : a - s;
*++out1 = c;
*++out2 = d;
}
gain1= (g1<1.0e-10)? 0.f : g1;
gain2= (g2<1.0e-10)? 0.f : g2;
gain3= (g3<1.0e-10)? 0.f : g3; // gain1=g1; gain2=g2; gain3=g3;
if (fabs (b1) < 1.0e-10) { fb1=0.f; fb2=0.f; fb3=0.f; }
else { fb1=b1; fb2=b2; fb3=l; }
}
//-----------------------------------------------------------------------------
void MultiBandProcessor::recalculate ()
{
//calcs here
driv1 = (float)pow (10.0,(2.5 * params[3]) - 1.0);
trim1 = (float)(0.5 + (4.0 - 2.0 * params[9]) * (params[3] * params[3] * params[3]));
trim1 = (float)(trim1 * pow (10.0, 2.0 * params[6] - 1.0));
att1 = (float)pow (10.0, -0.05 -(2.5 * params[9]));
rel1 = (float)pow (10.0, -2.0 - (3.5 * params[10]));
driv2 = (float)pow (10.0,(2.5 * params[4]) - 1.0);
trim2 = (float)(0.5 + (4.0 - 2.0 * params[9]) * (params[4] * params[4] * params[4]));
trim2 = (float)(trim2 * pow (10.0, 2.0 * params[7] - 1.0));
att2 = (float)pow (10.0, -0.05 -(2.0 * params[9]));
rel2 = (float)pow (10.0, -2.0 - (3.0 * params[10]));
driv3 = (float)pow (10.0,(2.5 * params[5]) - 1.0);
trim3 = (float)(0.5 + (4.0 - 2.0 * params[9]) * (params[5] * params[5] * params[5]));
trim3 = (float)(trim3 * pow (10.0, 2.0 * params[8] - 1.0));
att3 = (float)pow (10.0, -0.05 -(1.5 * params[9]));
rel3 = (float)pow (10.0, -2.0 - (2.5 * params[10]));
int32 listen = std::min<int32> (3, static_cast<int32> (params[0] * (4)));
switch (listen)
{
case 0: trim2=0.0; trim3=0.0; slev=0.0; break;
case 1: trim1=0.0; trim3=0.0; slev=0.0; break;
case 2: trim1=0.0; trim2=0.0; slev=0.0; break;
default: slev= static_cast<float> (params[11]); break;
}
fi1 = (float)pow (10.0,params[1] - 1.70); fo1= (float)(1.0 - fi1);
fi2 = (float)pow (10.0,params[2] - 1.05); fo2= (float)(1.0 - fi2);
if (params[12]>0.5) mswap=1; else mswap=0;
}
}}} // namespaces
@@ -0,0 +1,67 @@
/*
* mdaMultiBandProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class MultiBandProcessor : public BaseProcessor
{
public:
MultiBandProcessor ();
~MultiBandProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaM'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new MultiBandProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x64614D6D, 0x6461206D, 0x756C7469);
#else
inline static DECLARE_UID (uid, 0x97C53059, 0x47FC442C, 0x8A858B04, 0x30C3AFE7);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float gain1, driv1, att1, rel1, trim1;
float gain2, driv2, att2, rel2, trim2;
float gain3, driv3, att3, rel3, trim3;
float fi1, fb1, fo1, fi2, fb2, fo2, fb3, slev;
int32 mswap;
};
}}} // namespaces
@@ -0,0 +1,91 @@
/*
* mdaOverdriveController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaOverdriveController.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
OverdriveController::OverdriveController ()
{
}
//-----------------------------------------------------------------------------
OverdriveController::~OverdriveController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API OverdriveController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING("Drive"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Muffle"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -20, 20, true));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API OverdriveController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API OverdriveController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
return BaseController::getParamStringByValue (tag, valueNormalized, string);
/*
UString128 result;
switch (tag)
{
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;*/
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API OverdriveController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,56 @@
/*
* mdaOverdriveController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaOverdriveProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class OverdriveController : public BaseController
{
public:
OverdriveController ();
~OverdriveController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new OverdriveController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x64614F6D, 0x6461206F, 0x76657264);
#else
inline static DECLARE_UID (uid, 0x6E19D9A6, 0x81594A9D, 0x8730820A, 0x2AF52AC4);
#endif
};
}}} // namespaces
@@ -0,0 +1,122 @@
/*
* mdaOverdriveProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaOverdriveProcessor.h"
#include "mdaOverdriveController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
OverdriveProcessor::OverdriveProcessor ()
{
setControllerClass (OverdriveController::uid);
allocParameters (3);
}
//-----------------------------------------------------------------------------
OverdriveProcessor::~OverdriveProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API OverdriveProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.0f;
params[1] = 0.0f;
params[2] = 0.5f;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API OverdriveProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API OverdriveProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
void OverdriveProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, c, d;
float i= static_cast<float> (params[0]), g=gain, aa, bb;
float f=filt, fa=filt1, fb=filt2;
--in1;
--in2;
--out1;
--out2;
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2;
aa = (a > 0.0f)? (float)sqrt (a) : (float)-sqrt (-a); //overdrive
bb = (b > 0.0f)? (float)sqrt (b) : (float)-sqrt (-b);
fa = fa + f * (i * (aa - a) + a - fa); //filter
fb = fb + f * (i * (bb - b) + b - fb);
c = fa * g;
d = fb * g;
*++out1 = c;
*++out2 = d;
}
if (fabs (fa) > 1.0e-10) filt1 = fa; else filt1 = 0.0f; //catch denormals
if (fabs (fb) > 1.0e-10) filt2 = fb; else filt2 = 0.0f;
}
//-----------------------------------------------------------------------------
void OverdriveProcessor::recalculate ()
{
filt = (float)pow (10.0, -1.6 * params[1]);
gain = (float)pow (10.0f, (float)(2.0f * params[2] - 1.0f));
}
}}} // namespaces
@@ -0,0 +1,65 @@
/*
* mdaOverdriveProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class OverdriveProcessor : public BaseProcessor
{
public:
OverdriveProcessor ();
~OverdriveProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaO'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new OverdriveProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x64614F6D, 0x6461206F, 0x76657264);
#else
inline static DECLARE_UID (uid, 0x203C7009, 0x042A4AC2, 0xA515CFF1, 0xDF647E92);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float filt1, filt2; //filter buffers
float filt; //filter coeff.
float gain; //output gain
};
}}} // namespaces
@@ -0,0 +1,206 @@
/*
* mdaParameter.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/15/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaParameter.h"
#include "pluginterfaces/base/futils.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
BaseParameter::BaseParameter (const TChar* title, const TChar* units, int32 stepCount, ParamValue defaultValueNormalized, int32 flags, int32 tag, UnitID unitID)
{
Steinberg::UString (info.title, USTRINGSIZE (info.title)).assign (title);
Steinberg::UString uUnits (info.units, USTRINGSIZE (info.units));
if (units)
{
uUnits.assign (units);
}
info.stepCount = stepCount;
info.defaultNormalizedValue = defaultValueNormalized;
info.flags = flags;
info.id = tag;
info.unitId = unitID;
}
//-----------------------------------------------------------------------------
bool BaseParameter::fromString (const TChar* string, ParamValue& _valueNormalized) const
{
UString wrapper ((TChar*)string, USTRINGSIZE (String128));
double value;
if (wrapper.scanFloat (value))
{
if (value < 0)
value = 0;
else if (value > 1)
value = 1;
_valueNormalized = toNormalized (value);
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool BaseParameter::setNormalized (ParamValue v)
{
return Parameter::setNormalized (v);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
IndexedParameter::IndexedParameter (const TChar* title, const TChar* units, int32 stepCount, ParamValue defaultValueNormalized, int32 flags, int32 tag, UnitID unitID)
: BaseParameter (title, units, stepCount, defaultValueNormalized, flags, tag, unitID)
, indexString (nullptr)
{
indexString = new String128[stepCount+1];
for (int32 i = 0; i <= stepCount; i++)
indexString[i][0] = 0;
}
//-----------------------------------------------------------------------------
IndexedParameter::~IndexedParameter ()
{
delete[] indexString;
}
//-----------------------------------------------------------------------------
ParamValue IndexedParameter::toPlain (ParamValue _valueNormalized) const
{
return (ParamValue) (FromNormalized<ParamValue> (_valueNormalized, info.stepCount));
}
//-----------------------------------------------------------------------------
ParamValue IndexedParameter::toNormalized (ParamValue plainValue) const
{
return ToNormalized<ParamValue> (plainValue, info.stepCount);
}
//-----------------------------------------------------------------------------
void IndexedParameter::toString (ParamValue _valueNormalized, String128 string) const
{
memcpy (string, indexString[(int32)toPlain (_valueNormalized)], 128 * sizeof (TChar));
}
//-----------------------------------------------------------------------------
bool IndexedParameter::fromString (const TChar* string, ParamValue& _valueNormalized) const
{
if (string[0] == 0)
return false;
for (int32 i = 0; i <= info.stepCount; i++)
{
int32 pos = 0;
do
{
if (string[pos] != indexString[i][pos])
break;
pos++;
if (string[pos] == 0 && indexString[i][pos] == 0)
{
_valueNormalized = toNormalized (i);
return true;
}
} while (string[pos] != 0 && indexString[i][pos] != 0);
}
UString128 str (string);
int64 value;
if (str.scanInt (value) && value <= info.stepCount)
{
_valueNormalized = toNormalized (static_cast<Vst::ParamValue> (value));
return true;
}
return false;
}
//-----------------------------------------------------------------------------
void IndexedParameter::setIndexString (int32 index, const String128 str)
{
if (index <= info.stepCount)
memcpy (indexString[index], str, sizeof (String128));
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
ScaledParameter::ScaledParameter ( const TChar* title,
const TChar* units,
int32 stepCount,
ParamValue defaultValueNormalized,
int32 flags,
int32 tag,
ParamValue minValue,
ParamValue maxValue,
bool printAsInteger,
UnitID unitID)
: BaseParameter (title, units, stepCount, defaultValueNormalized, flags, tag, unitID)
, minValue (minValue)
, maxValue (maxValue)
, printAsInteger (printAsInteger)
{
setPrecision (2);
}
//-----------------------------------------------------------------------------
ParamValue ScaledParameter::toPlain (ParamValue _valueNormalized) const
{
return _valueNormalized * (maxValue - minValue) + minValue;
}
//-----------------------------------------------------------------------------
ParamValue ScaledParameter::toNormalized (ParamValue plainValue) const
{
return (plainValue - minValue) / (maxValue - minValue);
}
//-----------------------------------------------------------------------------
void ScaledParameter::toString (ParamValue _valueNormalized, String128 string) const
{
UString wrapper (string, USTRINGSIZE (String128));
if (printAsInteger)
wrapper.printInt (static_cast<int64> (toPlain (_valueNormalized)));
else
wrapper.printFloat (toPlain (_valueNormalized), precision);
}
//-----------------------------------------------------------------------------
bool ScaledParameter::fromString (const TChar* string, ParamValue& _valueNormalized) const
{
UString wrapper ((TChar*)string, USTRINGSIZE (String128));
double value;
if (wrapper.scanFloat (value))
{
if (value < minValue)
value = minValue;
else if (value > maxValue)
value = maxValue;
_valueNormalized = toNormalized (value);
return true;
}
return false;
}
}}} // namespaces
@@ -0,0 +1,103 @@
/*
* mdaParameter.h
* mda-vst3
*
* Created by Arne Scheffler on 6/15/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "public.sdk/source/vst/vstparameters.h"
#include "pluginterfaces/base/ustring.h"
#include <list>
#include <algorithm>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class BaseParameter : public Parameter
{
public:
BaseParameter ( const TChar* title,
const TChar* units,
int32 stepCount,
ParamValue defaultValueNormalized,
int32 flags,
int32 tag,
UnitID unitID = kRootUnitId);
bool fromString (const TChar* string, ParamValue& _valueNormalized) const SMTG_OVERRIDE;
bool setNormalized (ParamValue v) SMTG_OVERRIDE;
};
//-----------------------------------------------------------------------------
class IndexedParameter : public BaseParameter
{
public:
IndexedParameter ( const TChar* title,
const TChar* units,
int32 stepCount,
ParamValue defaultValueNormalized,
int32 flags,
int32 tag,
UnitID unitID = kRootUnitId);
ParamValue toPlain (ParamValue _valueNormalized) const SMTG_OVERRIDE;
ParamValue toNormalized (ParamValue plainValue) const SMTG_OVERRIDE;
void toString (ParamValue _valueNormalized, String128 string) const SMTG_OVERRIDE;
bool fromString (const TChar* string, ParamValue& _valueNormalized) const SMTG_OVERRIDE;
void setIndexString (int32 index, const String128 str);
protected:
~IndexedParameter () override;
String128* indexString;
};
//-----------------------------------------------------------------------------
class ScaledParameter : public BaseParameter
{
public:
ScaledParameter ( const TChar* title,
const TChar* units,
int32 stepCount,
ParamValue defaultValueNormalized,
int32 flags,
int32 tag,
ParamValue minValue = 0.,
ParamValue maxValue = 1.,
bool printAsInteger = false,
UnitID unitID = kRootUnitId);
ParamValue toPlain (ParamValue _valueNormalized) const SMTG_OVERRIDE;
ParamValue toNormalized (ParamValue plainValue) const SMTG_OVERRIDE;
void toString (ParamValue _valueNormalized, String128 string) const SMTG_OVERRIDE;
bool fromString (const TChar* string, ParamValue& _valueNormalized) const SMTG_OVERRIDE;
protected:
ParamValue minValue;
ParamValue maxValue;
bool printAsInteger;
};
}}} // namespaces
@@ -0,0 +1,137 @@
/*
* mdaPianoController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaPianoController.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
PianoController::PianoController ()
{
addBypassParameter = false;
}
//-----------------------------------------------------------------------------
PianoController::~PianoController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
auto presetList = {"mda Piano", "Plain Piano", "Compressed Piano", "Dance Piano",
"Convert Piano", "Dark Piano", "School Piano", "Broken Piano"};
auto* presetParam = new IndexedParameter (
USTRING ("Factory Presets"), USTRING ("%"), static_cast<int32> (presetList.size () - 1), 0.0,
ParameterInfo::kIsProgramChange | ParameterInfo::kIsList, kPresetParam);
int32 i = 0;
for (auto item : presetList)
presetParam->setIndexString (i++, UString128 (item));
parameters.addParameter (presetParam);
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING("Envelope Decay"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Envelope Release"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Hardness Offset"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Velocity to Hardness"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Muffling Filter"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Velocity to Muffling"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Velocity Sensitivity"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Stereo Width"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 200));
parameters.addParameter (new ScaledParameter (USTRING("Polyphony"), USTRING(""), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 8, 32, true));
parameters.addParameter (new ScaledParameter (USTRING("Fine Tuning"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Random Detunging"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100));
parameters.addParameter (new ScaledParameter (USTRING("Stretch Tuning"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -50, 50));
midiCCParamID[kCtrlModWheel] = kModWheelParam;
midiCCParamID[kCtrlSoftPedalOnOff] = kModWheelParam;
parameters.addParameter (USTRING("Mod Wheel"), USTRING(""), 0, 0, 0, kModWheelParam);
midiCCParamID[kCtrlSustainOnOff] = kSustainParam;
midiCCParamID[kCtrlSustenutoOnOff] = kSustainParam;
parameters.addParameter (new IndexedParameter (USTRING("Sustain"), USTRING(""), 1, 0, 0, kSustainParam));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoController::setParamNormalized (ParamID tag, ParamValue value)
{
tresult res = BaseController::setParamNormalized (tag, value);
if (res == kResultOk && tag == kPresetParam) // preset change
{
int32 program = static_cast<int32> (parameters.getParameter (tag)->toPlain (value));
for (int32 i = 0; i < PianoProcessor::NPARAMS; i++)
{
BaseController::setParamNormalized (i, PianoProcessor::programParams[program][i]);
}
if (componentHandler)
componentHandler->restartComponent (kParamValuesChanged);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
return BaseController::getParamStringByValue (tag, valueNormalized, string);
/*
UString128 result;
switch (tag)
{
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;*/
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,58 @@
/*
* mdaPianoController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaPianoProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class PianoController : public BaseController
{
public:
PianoController ();
~PianoController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setParamNormalized (ParamID tag, ParamValue value) SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new PianoController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653454D, 0x4441706D, 0x64612070, 0x69616E6F);
#else
inline static DECLARE_UID (uid, 0xBAC8AA21, 0x216D4754, 0xA7639173, 0xE3BB5F7A);
#endif
};
}}} // namespaces
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,403 @@
/*
* mdaPianoProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaPianoProcessor.h"
#include "mdaPianoController.h"
#include "mdaPianoData.h"
#include <cstdio>
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
#define SILENCE 0.0001f //voice choking
//-----------------------------------------------------------------------------
float PianoProcessor::programParams[][NPARAMS] = {
{0.500f, 0.500f, 0.500f, 0.5f, 0.803f, 0.251f, 0.376f, 0.500f, 0.330f, 0.500f, 0.246f, 0.500f},
{0.500f, 0.500f, 0.500f, 0.5f, 0.751f, 0.000f, 0.452f, 0.000f, 0.000f, 0.500f, 0.000f, 0.500f},
{0.902f, 0.399f, 0.623f, 0.5f, 1.000f, 0.331f, 0.299f, 0.499f, 0.330f, 0.500f, 0.000f, 0.500f},
{0.399f, 0.251f, 1.000f, 0.5f, 0.672f, 0.124f, 0.127f, 0.249f, 0.330f, 0.500f, 0.283f, 0.667f},
{0.648f, 0.500f, 0.500f, 0.5f, 0.298f, 0.602f, 0.550f, 0.850f, 0.356f, 0.500f, 0.339f, 0.660f},
{0.500f, 0.602f, 0.000f, 0.5f, 0.304f, 0.200f, 0.336f, 0.651f, 0.330f, 0.500f, 0.317f, 0.500f},
{0.450f, 0.598f, 0.626f, 0.5f, 0.603f, 0.500f, 0.174f, 0.331f, 0.330f, 0.500f, 0.421f, 0.801f},
{0.050f, 0.957f, 0.500f, 0.5f, 0.299f, 1.000f, 0.000f, 0.500f, 0.330f, 0.450f, 0.718f, 0.000f},
};
//-----------------------------------------------------------------------------
PianoProcessor::PianoProcessor ()
: currentProgram (0)
{
setControllerClass (PianoController::uid);
allocParameters (NPARAMS);
}
//-----------------------------------------------------------------------------
PianoProcessor::~PianoProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoProcessor::initialize (FUnknown* context)
{
tresult res = Base::initialize (context);
if (res == kResultTrue)
{
addEventInput (USTRING("MIDI in"), 1);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
Fs = 44100.0f; iFs = 1.0f/Fs; cmax = 0x7F; //just in case...
waves = pianoData;
//Waveform data and keymapping is hard-wired in *this* version
kgrp[ 0].root = 36; kgrp[ 0].high = 37; kgrp[ 0].pos = 0; kgrp[ 0].end = 36275; kgrp[ 0].loop = 14774;
kgrp[ 1].root = 40; kgrp[ 1].high = 41; kgrp[ 1].pos = 36278; kgrp[ 1].end = 83135; kgrp[ 1].loop = 16268;
kgrp[ 2].root = 43; kgrp[ 2].high = 45; kgrp[ 2].pos = 83137; kgrp[ 2].end = 146756; kgrp[ 2].loop = 33541;
kgrp[ 3].root = 48; kgrp[ 3].high = 49; kgrp[ 3].pos = 146758; kgrp[ 3].end = 204997; kgrp[ 3].loop = 21156;
kgrp[ 4].root = 52; kgrp[ 4].high = 53; kgrp[ 4].pos = 204999; kgrp[ 4].end = 244908; kgrp[ 4].loop = 17191;
kgrp[ 5].root = 55; kgrp[ 5].high = 57; kgrp[ 5].pos = 244910; kgrp[ 5].end = 290978; kgrp[ 5].loop = 23286;
kgrp[ 6].root = 60; kgrp[ 6].high = 61; kgrp[ 6].pos = 290980; kgrp[ 6].end = 342948; kgrp[ 6].loop = 18002;
kgrp[ 7].root = 64; kgrp[ 7].high = 65; kgrp[ 7].pos = 342950; kgrp[ 7].end = 391750; kgrp[ 7].loop = 19746;
kgrp[ 8].root = 67; kgrp[ 8].high = 69; kgrp[ 8].pos = 391752; kgrp[ 8].end = 436915; kgrp[ 8].loop = 22253;
kgrp[ 9].root = 72; kgrp[ 9].high = 73; kgrp[ 9].pos = 436917; kgrp[ 9].end = 468807; kgrp[ 9].loop = 8852;
kgrp[10].root = 76; kgrp[10].high = 77; kgrp[10].pos = 468809; kgrp[10].end = 492772; kgrp[10].loop = 9693;
kgrp[11].root = 79; kgrp[11].high = 81; kgrp[11].pos = 492774; kgrp[11].end = 532293; kgrp[11].loop = 10596;
kgrp[12].root = 84; kgrp[12].high = 85; kgrp[12].pos = 532295; kgrp[12].end = 560192; kgrp[12].loop = 6011;
kgrp[13].root = 88; kgrp[13].high = 89; kgrp[13].pos = 560194; kgrp[13].end = 574121; kgrp[13].loop = 3414;
kgrp[14].root = 93; kgrp[14].high = 999; kgrp[14].pos = 574123; kgrp[14].end = 586343; kgrp[14].loop = 2399;
//initialise...
for(int32 v=0; v<synthData.numVoices; v++)
{
memset (&synthData.voice[v], 0, sizeof (VOICE));
synthData.voice[v].env = 0.0f;
synthData.voice[v].dec = 0.99f; //all notes off
}
volume = 0.2f;
muff = 160.0f;
cpos = synthData.sustain = synthData.activevoices = 0;
comb = new float[256];
for (int32 i = 0; i < NPARAMS; i++)
params[i] = programParams[0][i];
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoProcessor::terminate ()
{
if (comb) delete[] comb;
comb = nullptr;
return Base::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoProcessor::setActive (TBool state)
{
if (state)
{
synthData.init ();
Fs = static_cast<float> (getSampleRate ());
iFs = 1.0f / Fs;
if (Fs > 64000.0f) cmax = 0xFF; else cmax = 0x7F;
memset (comb, 0, sizeof (float) * 256);
}
else
allNotesOff ();
return Base::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PianoProcessor::setProcessing (TBool state)
{
if (state)
allNotesOff ();
BaseProcessor::setProcessing (state);
return kResultOk;
}
//-----------------------------------------------------------------------------
void PianoProcessor::setParameter (ParamID index, ParamValue newValue, int32 sampleOffset)
{
if (index < NPARAMS)
Base::setParameter (index, newValue, sampleOffset);
else if (index == BaseController::kPresetParam) // program change
{
currentProgram = std::min<int32> (kNumPrograms - 1, (int32)(newValue * kNumPrograms));
const float* newParams = programParams[currentProgram];
if (newParams)
{
for (int32 i = 0; i < NPARAMS; i++)
params[i] = newParams[i];
recalculate ();
}
}
else if (index == BaseController::kModWheelParam) // mod wheel
{
newValue *= 127.;
muff = 0.01f * (float)((127 - newValue) * (127 - newValue));
}
else if (index == BaseController::kSustainParam)
{
synthData.sustain = newValue > 0.5;
if (synthData.sustain==0)
{
for (auto& v : synthData.voice)
{
if (v.noteID = SustainNoteID)
{
v.dec = (float)exp (-iFs * exp (6.0 + 0.01 * (double)v.note - 5.0 * params[1]));
}
}
}
}
}
//-----------------------------------------------------------------------------
void PianoProcessor::setCurrentProgram (Steinberg::uint32 val)
{
if (val < kNumPrograms)
currentProgram = val;
}
//-----------------------------------------------------------------------------
void PianoProcessor::setCurrentProgramNormalized (ParamValue val)
{
setCurrentProgram (std::min<int32> (kNumPrograms - 1, (int32)(val * kNumPrograms)));
}
//-----------------------------------------------------------------------------
void PianoProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
int32 frame=0, frames, v;
float x, l, r;
int32 i;
synthData.eventPos = 0;
if (synthData.activevoices > 0 || synthData.hasEvents ())
{
while (frame<sampleFrames)
{
frames = synthData.events[synthData.eventPos].sampleOffset;
if (frames>sampleFrames) frames = sampleFrames;
frames -= frame;
frame += frames;
while (--frames>=0)
{
VOICE *V = synthData.voice.data ();
l = r = 0.0f;
for(v=0; v<synthData.activevoices; v++)
{
V->frac += V->delta; //integer-based linear interpolation
V->pos += V->frac >> 16;
V->frac &= 0xFFFF;
if (V->pos > V->end) V->pos -= V->loop;
//i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; //not working on intel mac !?!
i = waves[V->pos] + ((V->frac * (waves[V->pos + 1] - waves[V->pos])) >> 16);
x = V->env * (float)i / 32768.0f;
//x = V->env * (*(float *)&i - 3.0f); //fast int->float
V->env = V->env * V->dec; //envelope
V->f0 += V->ff * (x + V->f1 - V->f0); //muffle filter
V->f1 = x;
l += V->outl * V->f0;
r += V->outr * V->f0;
if (!(l > -2.0f) || !(l < 2.0f))
{
printf ("what is this? %d, %f, %f\n", i, x, V->f0);
l = 0.0f;
}
if (!(r > -2.0f) || !(r < 2.0f))
{
r = 0.0f;
}
V++;
}
comb[cpos] = l + r;
++cpos &= cmax;
x = cdep * comb[cpos]; //stereo simulator
*out1++ = l + x;
*out2++ = r - x;
}
if (frame<sampleFrames)
{
noteEvent (synthData.events[synthData.eventPos]);
++synthData.eventPos;
}
}
}
else //completely empty block
{
memset (out1, 0, sizeof (float) * data.numSamples);
memset (out2, 0, sizeof (float) * data.numSamples);
data.outputs[0].silenceFlags = 3;
}
for (v = 0; v < synthData.activevoices; v++)
if (synthData.voice[v].env < SILENCE)
synthData.voice[v] = synthData.voice[--synthData.activevoices];
}
//-----------------------------------------------------------------------------
void PianoProcessor::noteEvent (const Event& event)
{
float l=99.0f;
int32 v, vl=0, k, s;
if (event.type == Event::kNoteOnEvent)
{
auto& noteOn = event.noteOn;
auto note = noteOn.pitch;
float velocity = noteOn.velocity * 127;
if (synthData.activevoices < poly) //add a note
{
vl = synthData.activevoices;
synthData.activevoices++;
}
else //steal a note
{
for(v=0; v<poly; v++) //find quietest voice
{
if (synthData.voice[v].env < l) { l = synthData.voice[v].env; vl = v; }
}
}
k = (note - 60) * (note - 60);
l = fine + random * ((float)(k % 13) - 6.5f); //random & fine tune
if (note > 60) l += stretch * (float)k; //stretch
s = size;
if (velocity > 40) s += (int32)(sizevel * (float)(velocity - 40));
k = 0;
while (note > (kgrp[k].high + s)) k++; //find keygroup
l += (float)(note - kgrp[k].root); //pitch
l = 22050.0f * iFs * (float)exp (0.05776226505 * l);
synthData.voice[vl].delta = (int32)(65536.0f * l);
synthData.voice[vl].frac = 0;
synthData.voice[vl].pos = kgrp[k].pos;
synthData.voice[vl].end = kgrp[k].end;
synthData.voice[vl].loop = kgrp[k].loop;
synthData.voice[vl].env = (0.5f + velsens) * (float)pow (0.0078f * velocity, velsens); //velocity
l = static_cast<float> (50.0f + params[4] * params[4] * muff + muffvel * (float)(velocity - 64)); //muffle
if (l < (55.0f + 0.25f * (float)note)) l = 55.0f + 0.25f * (float)note;
if (l > 210.0f) l = 210.0f;
synthData.voice[vl].ff = l * l * iFs;
synthData.voice[vl].f0 = synthData.voice[vl].f1 = 0.0f;
synthData.voice[vl].note = note; //note->pan
if (note < 12) note = 12;
if (note > 108) note = 108;
l = volume * trim;
synthData.voice[vl].outr = l + l * width * (float)(note - 60);
synthData.voice[vl].outl = l + l - synthData.voice[vl].outr;
if (note < 44) note = 44; //limit max decay length
l = static_cast<float> (2.0f * params[0]);
if (l < 1.0f) l += static_cast<float> (0.25f - 0.5f * params[0]);
synthData.voice[vl].dec = (float)exp (-iFs * exp (-0.6 + 0.033 * (double)note - l));
synthData.voice[vl].noteID = noteOn.noteId;
}
else //note off
{
auto& noteOff = event.noteOff;
auto note = noteOff.pitch;
for(v=0; v<synthData.numVoices; v++) if (synthData.voice[v].noteID==noteOff.noteId) //any voices playing that note?
{
if (synthData.sustain==0)
{
if (note < 94) //no release on highest notes
synthData.voice[v].dec = (float)exp (-iFs * exp (2.0 + 0.017 * (double)note - 2.0 * params[1]));
}
else synthData.voice[v].noteID = SustainNoteID;
}
}
}
//-----------------------------------------------------------------------------
void PianoProcessor::preProcess ()
{
synthData.clearEvents ();
}
//-----------------------------------------------------------------------------
void PianoProcessor::processEvent (const Event& e)
{
synthData.processEvent (e);
}
//-----------------------------------------------------------------------------
void PianoProcessor::allNotesOff ()
{
for (int32 v=0; v<synthData.numVoices; v++) synthData.voice[v].dec=0.99f;
synthData.sustain = 0;
muff = 160.0f;
}
//-----------------------------------------------------------------------------
void PianoProcessor::recalculate ()
{
size = (int32)(12.0f * params[2] - 6.0f);
sizevel = static_cast<float> (0.12f * params[3]);
muffvel = static_cast<float> (params[5] * params[5] * 5.0f);
velsens = static_cast<float> (1.0f + params[6] + params[6]);
if (params[6] < 0.25f) velsens -= static_cast<float> (0.75f - 3.0f * params[6]);
fine = static_cast<float> (params[9] - 0.5f);
random = static_cast<float> (0.077f * params[10] * params[10]);
stretch = static_cast<float> (0.000434f * (params[11] - 0.5f));
cdep = static_cast<float> (params[7] * params[7]);
trim = 1.50f - 0.79f * cdep;
width = static_cast<float> (0.04f * params[7]);
if (width > 0.03f) width = 0.03f;
poly = 8 + (int32)(24.9f * params[8]);
}
}}} // namespaces
@@ -0,0 +1,134 @@
/*
* mdaPianoProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class PianoProcessor : public BaseProcessor
{
public:
using Base = BaseProcessor;
PianoProcessor ();
~PianoProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'MDAp'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
bool hasProgram () const SMTG_OVERRIDE { return true; }
Steinberg::uint32 getCurrentProgram () const SMTG_OVERRIDE { return currentProgram; }
Steinberg::uint32 getNumPrograms () const SMTG_OVERRIDE { return kNumPrograms; }
void setCurrentProgram (Steinberg::uint32 val) SMTG_OVERRIDE;
void setCurrentProgramNormalized (ParamValue val) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new PianoProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653544D, 0x4441706D, 0x64612070, 0x69616E6F);
#else
inline static DECLARE_UID (uid, 0xA77EA27C, 0x1F184322, 0xBBD2AD93, 0x73A2B7A0);
#endif
//-----------------------------------------------------------------------------
enum {
NPARAMS=12,
WAVELEN=586348
};
static const int32 kNumPrograms = 8;
static float programParams[][NPARAMS];
protected:
void setParameter (ParamID index, ParamValue newValue, int32 sampleOffset) SMTG_OVERRIDE;
void preProcess () SMTG_OVERRIDE;
void processEvent (const Event& event) SMTG_OVERRIDE;
void noteEvent (const Event& event);
void recalculate () SMTG_OVERRIDE;
void allNotesOff ();
struct VOICE //voice state
{
int32 delta; //sample playback
int32 frac;
int32 pos;
int32 end;
int32 loop;
float env; //envelope
float dec;
float f0; //first-order LPF
float f1;
float ff;
float outl;
float outr;
int32 note; //remember what note triggered this
int32 noteID;
};
struct KGRP //keygroup
{
int32 root; //MIDI root note
int32 high; //highest note
int32 pos;
int32 end;
int32 loop;
};
float Fs, iFs;
static constexpr int32 kNumVoices = 32;
static constexpr int32 kEventBufferSize = 64;
using SynthDataT = SynthData<VOICE, kEventBufferSize, kNumVoices>;
SynthDataT synthData;
///global internal variables
KGRP kgrp[16];
int32 poly, cpos;
short *waves;
int32 cmax;
float *comb, cdep, width, trim;
int32 size;
float tune, fine, random, stretch;
float muff, muffvel, sizevel, velsens, volume;
Steinberg::uint32 currentProgram;
};
}}} // namespaces
@@ -0,0 +1,98 @@
/*
* mdaRePsychoController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaRePsychoController.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
RePsychoController::RePsychoController ()
{
}
//-----------------------------------------------------------------------------
RePsychoController::~RePsychoController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RePsychoController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING("Tune"), USTRING("semi"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, -24, 0, true));
parameters.addParameter (new ScaledParameter (USTRING("Fine"), USTRING("cent"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, -99, 0, true));
parameters.addParameter (new ScaledParameter (USTRING("Decay"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -50, 50, true));
parameters.addParameter (new ScaledParameter (USTRING("Thresh"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -30, 0, true));
parameters.addParameter (USTRING("Hold"), USTRING("ms"), 0, 0.5, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("Mix"), USTRING("%"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, 0, 100, true));
parameters.addParameter (USTRING("High Quality"), USTRING(""), 1, 0.5, ParameterInfo::kCanAutomate, pid++);
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RePsychoController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RePsychoController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case 4:
{
float dtim = 441.f + static_cast<int32> (0.5 * 22050 * valueNormalized);
result.printInt (static_cast <int64> (1000.0 * dtim / getSampleRate ()));
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RePsychoController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
return BaseController::getParamValueByString (tag, string, valueNormalized);
/*
switch (tag)
{
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;*/
}
}}} // namespaces
@@ -0,0 +1,56 @@
/*
* mdaRePsychoController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaRePsychoProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class RePsychoController : public BaseController
{
public:
RePsychoController ();
~RePsychoController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new RePsychoController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461596D, 0x64612072, 0x65707379);
#else
inline static DECLARE_UID (uid, 0x4C14E332, 0xE185463B, 0x98732E82, 0x944786C5);
#endif
};
}}} // namespaces
@@ -0,0 +1,258 @@
/*
* mdaRePsychoProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaRePsychoProcessor.h"
#include "mdaRePsychoController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
RePsychoProcessor::RePsychoProcessor ()
{
setControllerClass (RePsychoController::uid);
allocParameters (7);
}
//-----------------------------------------------------------------------------
RePsychoProcessor::~RePsychoProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RePsychoProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[3/**/] = (float)0.6; //thresh
params[2/**/] = (float)0.5; //env
params[0/**/] = (float)1.0; //tune
params[5/**/] = (float)1.0; //mix
params[4/**/] = (float)0.45; //minimum chunk length
params[1/**/] = (float)1.0; //fine tune
params[6/**/] = (float)1.; //quality
size = 22050;
buffer = new float[size];
buffer2 = new float[size];
buf = 0.0; buf2 = 0.0;
tim = size + 1;
fil = 0.0;
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RePsychoProcessor::terminate ()
{
if (buffer) delete [] buffer;
if (buffer2) delete [] buffer2;
buffer = buffer2 = nullptr;
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RePsychoProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RePsychoProcessor::setProcessing (TBool state)
{
if (state)
{
memset (buffer, 0, size * sizeof (float));
memset (buffer2, 0, size * sizeof (float));
gai = 0.f;
buf = 0.0; buf2 = 0.0;
tim = size + 1;
fil = 0.0;
}
BaseProcessor::setProcessing (state);
return kResultOk;
}
//-----------------------------------------------------------------------------
void RePsychoProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a, b, c, d;
float we=wet, dr = dry, tu=tun, en=env;
float ga=gai, x = 0.0f, x2=0.0f, xx=buf, xx2=buf2;
float it1, it2;
int32 ti=tim, dti=dtim, of1, of2;
--in1;
--in2;
--out1;
--out2;
if (params[6/**/]>0.5) //high quality
{
we= (float)(we*2.0);
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2; //process from here...
if ((a+b > thr) && (ti > dti)) //trigger
{
ga = 1.0;
ti = 0;
}
if (ti<22050) //play out
{
if (ti<80) //fade in
{
if (ti==0) { xx=x; xx2=x2; }
*(buffer + ti) = a;
*(buffer2 + ti) = b;
x = *(buffer + int (ti * tu));
x2 = *(buffer2 + int (ti * tu));
x = (float)(xx * (1.0 - (0.0125 * ti)) + (x * 0.0125 * ti));
x2 = (float)(xx2 * (1.0 - (0.0125 * ti)) + (x2 * 0.0125 * ti));
}
else
{
//update to/from buffer
*(buffer + ti) = a;
*(buffer2 + ti) = b;
it1 = (float)(ti * tu); //interpolation
of1 = (int)it1; of2 = of1 + 1; it1 = it1 - of1; it2 = (float)(1.0 - it1);
x = (it2* *(buffer + of1)) + (it1* *(buffer + of2));
x2 = (it2* *(buffer2 + of1)) + (it1* *(buffer2 + of2));
}
ti++;
ga*= en;
}
else //mute
{
ga = 0;
}
c = (a * dr) + (x * ga * we); // output
d = (b * dr) + (x2 * ga * we);
*++out1 = c;
*++out2 = d;
}
}
else
{
while (--sampleFrames >= 0)
{
a = *++in1;
b = *++in2; //process from here...
if ((a+b > thr) && (ti > dti)) //trigger
{
ga = 1.0;
ti = 0;
}
if (ti<22050) //play out
{
if (ti<80) //fade in
{
if (ti==0) xx = x;
*(buffer + ti) = (a + b);
x = *(buffer + int (ti * tu));
x = (float)(xx * (1.0 - (0.0125 * ti)) + (x * 0.0125 * ti));
}
else
{
//update to/from buffer
*(buffer + ti) = (a + b);
x = *(buffer + int (ti * tu));
}
ti++;
ga*= en;
}
else //mute
{
ga = 0;
}
c = (a * dr) + (x * ga * we); // output
d = (b * dr) + (x * ga * we);
*++out1 = c;
*++out2 = d;
}
}
tim = ti;
gai = ga;
buf = xx;
buf2 = xx2;
}
//-----------------------------------------------------------------------------
void RePsychoProcessor::recalculate ()
{
dtim = 441 + int (0.5 * size * params[4/**/]);
thr = (float)pow (10.0,(1.5 * params[3/**/]) - 1.5);
if (params[2/**/]>0.5)
{ env = (float)(1.0 + 0.003 * pow (params[2/**/] - 0.5,5.0)); }
else
{ env = (float)(1.0 + 0.025 * pow (params[2/**/] - 0.5,5.0)); }
//if (params[2/**/]>0.5)
//{ env = (float)(1.0 + 0.01 * (params[2/**/] - 0.5)); }
//else
//{ env = (float)(1.0 + 0.01 * (params[2/**/] - 0.5)); }
tun = (float)(((int (params[0/**/] * 24.0) - 24.0) + (params[1/**/] - 1.0)) / 24.0);
tun = (float)pow (10.0, 0.60206 * tun);
wet = (float)(0.5 * sqrt (params[5/**/]));
dry = (float)sqrt (1.0 - params[5/**/]);
}
}}} // namespaces
@@ -0,0 +1,68 @@
/*
* mdaRePsychoProcessor.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class RePsychoProcessor : public BaseProcessor
{
public:
RePsychoProcessor ();
~RePsychoProcessor () override;
int32 getVst2UniqueId () const SMTG_OVERRIDE { return 'mdaY'; }
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
void doProcessing (ProcessData& data) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new RePsychoProcessor; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653546D, 0x6461596D, 0x64612072, 0x65707379);
#else
inline static DECLARE_UID (uid, 0xC20CCF82, 0x90574B71, 0x98AE3FE1, 0x240C2704);
#endif
//-----------------------------------------------------------------------------
protected:
void recalculate () SMTG_OVERRIDE;
float thr, env, gai, tun, wet, dry, fil, buf, buf2;
int32 tim, dtim;
float *buffer, *buffer2;
int32 size;
};
}}} // namespaces
@@ -0,0 +1,126 @@
/*
* mdaRezFilterController.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaRezFilterController.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
RezFilterController::RezFilterController ()
{
}
//-----------------------------------------------------------------------------
RezFilterController::~RezFilterController ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RezFilterController::initialize (FUnknown* context)
{
tresult res = BaseController::initialize (context);
if (res == kResultTrue)
{
ParamID pid = 0;
parameters.addParameter (new ScaledParameter (USTRING("Freq"), USTRING("%"), 0, 0.15, ParameterInfo::kCanAutomate, pid++, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Res"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, 0, 100, true));
parameters.addParameter (new ScaledParameter (USTRING("Output"), USTRING("dB"), 0, 0.5, ParameterInfo::kCanAutomate, pid++, -20, 20, true));
parameters.addParameter (new ScaledParameter (USTRING("Env->VCF"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, -100, 100, true));
parameters.addParameter (USTRING("Attack"), USTRING("ms"), 0, 0.6, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (USTRING("Release"), USTRING("ms"), 0, 0.6, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("LFO->VCF"), USTRING("S+H<>Sin"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, -100, 100, true));
parameters.addParameter (USTRING("LFO Rate"), USTRING("Hz"), 0, 0.6, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (USTRING("Trigger"), USTRING("dB"), 0, 0.6, ParameterInfo::kCanAutomate, pid++);
parameters.addParameter (new ScaledParameter (USTRING("Max Freq"), USTRING("%"), 0, 0.6, ParameterInfo::kCanAutomate, pid++, 0, 100, true));
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RezFilterController::terminate ()
{
return BaseController::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RezFilterController::getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string)
{
UString128 result;
switch (tag)
{
case 4:
{
float att = (float)pow (10.0, -0.01 - 4.0 * valueNormalized);
result.printFloat (-301.0301 / (getSampleRate () * log10(1.0 - att)), 2);
break;
}
case 5:
{
float rel = 1.f - (float)pow (10.0, -2.00 - 4.0 * valueNormalized);
result.printFloat (-301.0301 / (getSampleRate () * log10(rel)), 2);
break;
}
case 7:
{
result.printFloat (pow (10.0f, (float)(4.f*valueNormalized - 2.f)), 2);
break;
}
case 8:
{
float tthr = 0.f;
if (valueNormalized<0.1f) tthr=0.f; else tthr = static_cast <float>(3.f * valueNormalized * valueNormalized);
if (tthr == 0)
result.fromAscii("FREE RUN");
else
result.printFloat (20*log10 (0.5*tthr), 2);
break;
}
default:
return BaseController::getParamStringByValue (tag, valueNormalized, string);
}
result.copyTo (string, 128);
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RezFilterController::getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized)
{
switch (tag)
{
case 4:
case 5:
case 7:
case 8:
break;
default:
return BaseController::getParamValueByString (tag, string, valueNormalized);
}
return kResultFalse;
}
}}} // namespaces
@@ -0,0 +1,56 @@
/*
* mdaRezFilterController.h
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#pragma once
#include "mdaBaseController.h"
#include "mdaRezFilterProcessor.h"
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
class RezFilterController : public BaseController
{
public:
RezFilterController ();
~RezFilterController () override;
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized, String128 string) SMTG_OVERRIDE;
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string, ParamValue& valueNormalized) SMTG_OVERRIDE;
//-----------------------------------------------------------------------------
static FUnknown* createInstance (void*) { return (IEditController*)new RezFilterController; }
#ifdef SMTG_MDA_VST2_COMPATIBILITY
inline static DECLARE_UID (uid, 0x5653456D, 0x6461466D, 0x64612072, 0x657A6669);
#else
inline static DECLARE_UID (uid, 0xEB05C9E8, 0xD99E4797, 0x83E6F33E, 0x90D9378B);
#endif
};
}}} // namespaces
@@ -0,0 +1,221 @@
/*
* mdaRezFilterProcessor.cpp
* mda-vst3
*
* Created by Arne Scheffler on 6/14/08.
*
* mda VST Plug-ins
*
* Copyright (c) 2008 Paul Kellett
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above copyright notice and this
* permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "mdaRezFilterProcessor.h"
#include "mdaRezFilterController.h"
#include <cmath>
#include <cstdlib>
namespace Steinberg {
namespace Vst {
namespace mda {
//-----------------------------------------------------------------------------
RezFilterProcessor::RezFilterProcessor ()
{
setControllerClass (RezFilterController::uid);
allocParameters (10);
}
//-----------------------------------------------------------------------------
RezFilterProcessor::~RezFilterProcessor ()
{
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RezFilterProcessor::initialize (FUnknown* context)
{
tresult res = BaseProcessor::initialize (context);
if (res == kResultTrue)
{
addAudioInput (USTRING("Stereo In"), SpeakerArr::kStereo);
addAudioOutput (USTRING("Stereo Out"), SpeakerArr::kStereo);
params[0] = 0.33f; //f
params[1] = 0.70f; //q
params[2] = 0.50f; //a
params[3] = 0.85f; //fenv
params[4] = 0.00f; //att
params[5] = 0.50f; //rel
params[6] = 0.70f; //lfo
params[7] = 0.40f; //rate
params[8] = 0.00f; //trigger
params[9] = 0.75f; //max freq
recalculate ();
}
return res;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RezFilterProcessor::terminate ()
{
return BaseProcessor::terminate ();
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RezFilterProcessor::setActive (TBool state)
{
return BaseProcessor::setActive (state);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API RezFilterProcessor::setProcessing (TBool state)
{
if (state)
{
buf0 = 0.f;
buf1 = 0.f;
buf2 = 0.f;
}
BaseProcessor::setProcessing (state);
return kResultOk;
}
//-----------------------------------------------------------------------------
void RezFilterProcessor::doProcessing (ProcessData& data)
{
int32 sampleFrames = data.numSamples;
float* in1 = data.inputs[0].channelBuffers32[0];
float* in2 = data.inputs[0].channelBuffers32[1];
float* out1 = data.outputs[0].channelBuffers32[0];
float* out2 = data.outputs[0].channelBuffers32[1];
float a;
float f, i, ff=fff, fe=fenv, q=fq, g=fg, e=env, tmp;
float b0=buf0, b1=buf1, b2=buf2, at=att, re=rel, fm=fmax;
float fl=flfo, dph=dphi, ph=phi, bl=bufl, th=tthr, e2=env2;
int32 lm=lfomode, ta=tatt, tt=ttrig;
--in1;
--in2;
--out1;
--out2;
if (th==0.f)
{
while (--sampleFrames >= 0)
{
a = *++in1 + *++in2;
i = (a>0)? a : -a; //envelope
e = (i>e)? e + at * (i - e) : e * re;
if (lm==0) bl = fl * (float)sin(ph); //lfo
else if (ph>1.f) { bl = fl*(rand() % 2000 - 1000); ph=0.f; }
ph += dph;
f = ff + fe * e + bl; //freq
if (f<0.f) i = 0.f; else i= (f>fm)? fm : f;
// o = 1.f - i;
// tmp = g*a + q*(1.f + (1.f/o)) * (b0-b1);
// b0 = o * (b0 - tmp) + tmp;
// b1 = o * (b1 - b0) + b0;
tmp = q + q * (1.0f + i * (1.0f + 1.1f * i));
//tmp = q + q/(1.0008 - i);
b0 += i * (g * a - b0 + tmp * (b0 - b1));
b1 += i * (b0 - b1);
// b2 = o * (b2 - b1) + b1;
*++out1 = b1;
*++out2 = b1;
}
}
else
{
while (--sampleFrames >= 0)
{
a = *++in1 + *++in2;
i = (a>0)? a : -a; //envelope
e = (i>e)? i : e * re;
if (e>th) { if (tt==0) {ta=1; if (lm==1)ph=2.f; } tt=1; } else tt=0;
if (ta==1) { e2 += at*(1.f-e2); if (e2>0.999f)ta=0; } else e2*=re;
if (lm==0) bl = fl * (float)sin(ph); //lfo
else if (ph>1.f) { bl = fl*(rand() % 2000 - 1000); ph=0.f; }
ph += dph;
f = ff + fe * e + bl; //freq
if (f<0.f) i = 0.f; else i= (f>fm)? fm : f;
// o = 1.f - i;
tmp = q + q * (1.0f + i * (1.0f + 1.1f * i));
//tmp = q + q/(1.0008 - i);
b0 += i * (g * a - b0 + tmp * (b0 - b1));
b1 += i * (b0 - b1);
// tmp = g*a + q*(1.f + (1.f/o)) * (b0-b1); //what about (q + q/f)*
// b0 = o * (b0 - tmp) + tmp; // ^ what about div0 ?
// b1 = o * (b1 - b0) + b0;
// b2 = o * (b2 - b1) + b1;
*++out1 = b1;
*++out2 = b1;
}
}
if (fabs (b0) < 1.0e-10) { buf0=0.f; buf1=0.f; buf2=0.f; }
else { buf0=b0; buf1=b1; buf2=b2; }
env=e; env2=e2; bufl=bl; tatt=ta; ttrig=tt;
phi= (float)fmod(ph,6.2831853f);
}
//-----------------------------------------------------------------------------
void RezFilterProcessor::recalculate ()
{
fff = static_cast<float> (1.5f * params[0] * params[0] - 0.15f);
fq = 0.99f * powf (static_cast<float> (params[1]),0.3f); //was 0.99f *
fg = 0.5f * powf (10.0f, static_cast<float> (2.f * params[2] - 1.f));
fmax = static_cast<float> (0.99f + 0.3f * params[1]);
if (fmax>(1.3f * params[9])) fmax= static_cast<float> (1.3f*params[9]);
//fmax = 1.0f;
//fq *= 1.0f + 0.2f * params[9];
fenv = static_cast<float> (2.f*(0.5f - params[3])*(0.5f - params[3]));
fenv = (params[3]>0.5)? fenv : -fenv;
att = static_cast<float> (pow (10.0, -0.01 - 4.0 * params[4]));
rel = 1.f - static_cast<float> (pow (10.0, -2.00 - 4.0 * params[5]));
lfomode=0;
flfo = static_cast<float> (2.f * (params[6] - 0.5f)*(params[6] - 0.5f));
dphi = static_cast<float> (6.2832f * powf (10.0f, static_cast<float> (3.f * params[7] - 1.5f)) / getSampleRate ());
if (params[6]<0.5) { lfomode=1; dphi *= 0.15915f; flfo *= 0.001f; } //S&H
if (params[8]<0.1) tthr=0.f; else tthr = static_cast<float> (3.f * params[8] * params[8]);
}
}}} // namespaces

Some files were not shown because too many files have changed in this diff Show More