Add more fx

This commit is contained in:
Roland Rabien 2023-10-08 22:44:56 -07:00
commit b20f153c84
15 changed files with 5211 additions and 22 deletions

View file

@ -106,9 +106,9 @@
},
{ "id": "fx", "x": 0, "y": "prevB()+1", "w": "parW() - 169", "h": 137, "children":
[
{ "id": "gate", "x": "0", "y": 0, "w": 290, "h": 137, "children":
{ "id": "gate", "x": "0", "y": 0, "w": 306, "h": 137, "children":
[
{ "id": "Beat", "x": 61, "y": 30, "w": 42, "h": 57 },
{ "id": "Beat", "x": 69, "y": 30, "w": 42, "h": 57 },
{ "id": "Length", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "A", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "R", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
@ -124,9 +124,42 @@
{ "id": "Width", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
]
},
{ "id": "distort", "x": "prevR()+1", "y": "prevY()", "w": 100, "h": 137, "children":
{ "id": "distort", "x": "prevR()+1", "y": "prevY()", "w": 84, "h": 137, "children":
[
{ "id": "Amount", "x": 22, "y": "23 + 22", "w": 56, "h": 70 }
{ "id": "Distort", "children":
[
{ "id": "mode", "r": "parW() - 4", "y": 4, "w": 16, "h": 16 }
]
},
{ "id": "page1", "bounds": "parent", "children":
[
{ "id": "Amount", "x": 14, "y": "23 + 22", "w": 56, "h": 70 }
]
},
{ "id": "page2", "bounds": "parent", "children":
[
{ "id": "Rate", "x": 0, "y": 23, "w": 42, "h": 57 },
{ "id": "Rez", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Hard", "x": 0, "y": "prevB()", "w": 42, "h": 57 },
{ "id": "Mix", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
]
},
{ "id": "page3", "bounds": "parent", "children":
[
{ "id": "Gain", "x": 0, "y": 23, "w": 42, "h": 57 },
{ "id": "Tone", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Output", "x": 0, "y": "prevB()", "w": 42, "h": 57 },
{ "id": "Mix", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
]
},
{ "id": "page4", "bounds": "parent", "children":
[
{ "id": "Gain", "x": 0, "y": 23, "w": 42, "h": 57 },
{ "id": "Tone", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Output", "x": 0, "y": "prevB()", "w": 42, "h": 57 },
{ "id": "Mix", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
]
}
]
},
{ "id": "delay", "x": "prevR()+1", "y": "prevY()", "w": 126, "h": 137, "children":

156
plugin/Source/FX/DeRez2.cpp Executable file
View file

@ -0,0 +1,156 @@
/* ========================================
* DeRez2 - DeRez2.h
* Copyright (c) 2016 airwindows, Airwindows uses the MIT license
* ======================================== */
#ifndef __DeRez2_H
#include "DeRez2.h"
#endif
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wfloat-conversion", "-Wimplicit-float-conversion", "-Wunused-parameter")
DeRez2::DeRez2(audioMasterCallback audioMaster) :
AudioEffectX(audioMaster, kNumPrograms, kNumParameters)
{
A = 1.0;
B = 1.0;
C = 1.0;
D = 1.0;
lastSampleL = 0.0;
heldSampleL = 0.0;
lastDrySampleL = 0.0;
lastOutputSampleL = 0.0;
lastSampleR = 0.0;
heldSampleR = 0.0;
lastDrySampleR = 0.0;
lastOutputSampleR = 0.0;
position = 0.0;
incrementA = 0.0;
incrementB = 0.0;
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
//this is reset: values being initialized only once. Startup values, whatever they are.
_canDo.insert("plugAsChannelInsert"); // plug-in can be used as a channel insert effect.
_canDo.insert("plugAsSend"); // plug-in can be used as a send effect.
_canDo.insert("x2in2out");
setNumInputs(kNumInputs);
setNumOutputs(kNumOutputs);
setUniqueID(kUniqueId);
canProcessReplacing(); // supports output replacing
canDoubleReplacing(); // supports double precision processing
programsAreChunks(true);
vst_strncpy (_programName, "Default", kVstMaxProgNameLen); // default program name
}
DeRez2::~DeRez2() {}
VstInt32 DeRez2::getVendorVersion () {return 1000;}
void DeRez2::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);}
void DeRez2::getProgramName(char *name) {vst_strncpy (name, _programName, kVstMaxProgNameLen);}
//airwindows likes to ignore this stuff. Make your own programs, and make a different plugin rather than
//trying to do versioning and preventing people from using older versions. Maybe they like the old one!
static float pinParameter(float data)
{
if (data < 0.0f) return 0.0f;
if (data > 1.0f) return 1.0f;
return data;
}
VstInt32 DeRez2::getChunk (void** data, bool isPreset)
{
float *chunkData = (float *)calloc(kNumParameters, sizeof(float));
chunkData[0] = A;
chunkData[1] = B;
chunkData[2] = C;
chunkData[3] = D;
/* Note: The way this is set up, it will break if you manage to save settings on an Intel
machine and load them on a PPC Mac. However, it's fine if you stick to the machine you
started with. */
*data = chunkData;
return kNumParameters * sizeof(float);
}
VstInt32 DeRez2::setChunk (void* data, VstInt32 byteSize, bool isPreset)
{
float *chunkData = (float *)data;
A = pinParameter(chunkData[0]);
B = pinParameter(chunkData[1]);
C = pinParameter(chunkData[2]);
D = pinParameter(chunkData[3]);
/* We're ignoring byteSize as we found it to be a filthy liar */
/* calculate any other fields you need here - you could copy in
code from setParameter() here. */
return 0;
}
void DeRez2::setParameter(VstInt32 index, float value) {
switch (index) {
case kParamA: A = value; break;
case kParamB: B = value; break;
case kParamC: C = value; break;
case kParamD: D = value; break;
default: throw; // unknown parameter, shouldn't happen!
}
}
float DeRez2::getParameter(VstInt32 index) {
switch (index) {
case kParamA: return A; break;
case kParamB: return B; break;
case kParamC: return C; break;
case kParamD: return D; break;
default: break; // unknown parameter, shouldn't happen!
} return 0.0; //we only need to update the relevant name, this is simple to manage
}
void DeRez2::getParameterName(VstInt32 index, char *text) {
switch (index) {
case kParamA: vst_strncpy (text, "Rate", kVstMaxParamStrLen); break;
case kParamB: vst_strncpy (text, "Rez", kVstMaxParamStrLen); break;
case kParamC: vst_strncpy (text, "Hard", kVstMaxParamStrLen); break;
case kParamD: vst_strncpy (text, "Dry/Wet", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} //this is our labels for displaying in the VST host
}
void DeRez2::getParameterDisplay(VstInt32 index, char *text) {
switch (index) {
case kParamA: float2string (A, text, kVstMaxParamStrLen); break;
case kParamB: float2string (B, text, kVstMaxParamStrLen); break;
case kParamC: float2string (C, text, kVstMaxParamStrLen); break;
case kParamD: float2string (D, text, kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} //this displays the values and handles 'popups' where it's discrete choices
}
void DeRez2::getParameterLabel(VstInt32 index, char *text) {
switch (index) {
case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamB: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamC: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamD: vst_strncpy (text, "", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
}
}
VstInt32 DeRez2::canDo(char *text)
{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know
bool DeRez2::getEffectName(char* name) {
vst_strncpy(name, "DeRez2", kVstMaxProductStrLen); return true;
}
VstPlugCategory DeRez2::getPlugCategory() {return kPlugCategEffect;}
bool DeRez2::getProductString(char* text) {
vst_strncpy (text, "airwindows DeRez2", kVstMaxProductStrLen); return true;
}
bool DeRez2::getVendorString(char* text) {
vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true;
}

79
plugin/Source/FX/DeRez2.h Executable file
View file

@ -0,0 +1,79 @@
/* ========================================
* DeRez2 - DeRez2.h
* Created 8/12/11 by SPIAdmin
* Copyright (c) 2011 __MyCompanyName__, Airwindows uses the MIT license
* ======================================== */
#pragma once
#include "FXBase.h"
#include <set>
#include <string>
#include <math.h>
class DeRez2 :
public AudioEffectX
{
public:
enum {
kParamA = 0,
kParamB = 1,
kParamC = 2,
kParamD = 3,
kNumParameters = 4
}; //
static constexpr int kNumPrograms = 0;
static constexpr int kNumInputs = 2;
static constexpr int kNumOutputs = 2;
static constexpr unsigned long kUniqueId = 'eerz'; //Change this to what the AU identity is!
DeRez2(audioMasterCallback audioMaster);
~DeRez2();
virtual bool getEffectName(char* name); // The plug-in name
virtual VstPlugCategory getPlugCategory(); // The general category for the plug-in
virtual bool getProductString(char* text); // This is a unique plug-in string provided by Steinberg
virtual bool getVendorString(char* text); // Vendor info
virtual VstInt32 getVendorVersion(); // Version number
virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
virtual void processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames);
virtual void getProgramName(char *name); // read the name from the host
virtual void setProgramName(char *name); // changes the name of the preset displayed in the host
virtual VstInt32 getChunk (void** data, bool isPreset);
virtual VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset);
virtual float getParameter(VstInt32 index); // get the parameter value at the specified index
virtual void setParameter(VstInt32 index, float value); // set the parameter at index to value
virtual void getParameterLabel(VstInt32 index, char *text); // label for the parameter (eg dB)
virtual void getParameterName(VstInt32 index, char *text); // name of the parameter
virtual void getParameterDisplay(VstInt32 index, char *text); // text description of the current value
virtual VstInt32 canDo(char *text);
private:
char _programName[kVstMaxProgNameLen + 1];
std::set< std::string > _canDo;
double lastSampleL;
double heldSampleL;
double lastDrySampleL;
double lastOutputSampleL;
double lastSampleR;
double heldSampleR;
double lastDrySampleR;
double lastOutputSampleR;
double position;
double incrementA;
double incrementB;
uint32_t fpdL;
uint32_t fpdR;
//default stuff
float A;
float B;
float C;
float D;
};

366
plugin/Source/FX/DeRez2Proc.cpp Executable file
View file

@ -0,0 +1,366 @@
/* ========================================
* DeRez2 - DeRez2.h
* Copyright (c) 2016 airwindows, Airwindows uses the MIT license
* ======================================== */
#ifndef __DeRez2_H
#include "DeRez2.h"
#endif
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wfloat-conversion", "-Wimplicit-float-conversion", "-Wunused-parameter", "-Wunused-value")
void DeRez2::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
{
float* in1 = inputs[0];
float* in2 = inputs[1];
float* out1 = outputs[0];
float* out2 = outputs[1];
double targetA = pow(A,3)+0.0005;
if (targetA > 1.0) targetA = 1.0;
double soften = (1.0 + targetA)/2;
double targetB = pow(1.0-B,3) / 3;
double hard = C;
double wet = D;
double overallscale = 1.0;
overallscale /= 44100.0;
overallscale *= getSampleRate();
targetA /= overallscale;
while (--sampleFrames >= 0)
{
double inputSampleL = *in1;
double inputSampleR = *in2;
if (fabs(inputSampleL)<1.18e-23) inputSampleL = fpdL * 1.18e-17;
if (fabs(inputSampleR)<1.18e-23) inputSampleR = fpdR * 1.18e-17;
double drySampleL = inputSampleL;
double drySampleR = inputSampleR;
incrementA = ((incrementA*999.0)+targetA)/1000.0;
incrementB = ((incrementB*999.0)+targetB)/1000.0;
//incrementA is the frequency derez
//incrementB is the bit depth derez
position += incrementA;
double outputSampleL = heldSampleL;
double outputSampleR = heldSampleR;
if (position > 1.0)
{
position -= 1.0;
heldSampleL = (lastSampleL * position) + (inputSampleL * (1.0-position));
outputSampleL = (outputSampleL * (1.0-soften)) + (heldSampleL * soften);
//softens the edge of the derez
heldSampleR = (lastSampleR * position) + (inputSampleR * (1.0-position));
outputSampleR = (outputSampleR * (1.0-soften)) + (heldSampleR * soften);
//softens the edge of the derez
}
inputSampleL = outputSampleL;
inputSampleR = outputSampleR;
double tempL = inputSampleL;
double tempR = inputSampleR;
if (inputSampleL != lastOutputSampleL) {
tempL = inputSampleL;
inputSampleL = (inputSampleL * hard) + (lastDrySampleL * (1.0-hard));
//transitions get an intermediate dry sample
lastOutputSampleL = tempL; //only one intermediate sample
} else {
lastOutputSampleL = inputSampleL;
}
if (inputSampleR != lastOutputSampleR) {
tempR = inputSampleR;
inputSampleR = (inputSampleR * hard) + (lastDrySampleR * (1.0-hard));
//transitions get an intermediate dry sample
lastOutputSampleR = tempR; //only one intermediate sample
} else {
lastOutputSampleR = inputSampleR;
}
lastDrySampleL = drySampleL;
lastDrySampleR = drySampleR;
//freq section of soft/hard interpolates dry samples
tempL = inputSampleL;
tempR = inputSampleR;
if (inputSampleL > 1.0) inputSampleL = 1.0;
if (inputSampleL < -1.0) inputSampleL = -1.0;
if (inputSampleR > 1.0) inputSampleR = 1.0;
if (inputSampleR < -1.0) inputSampleR = -1.0;
if (inputSampleL > 0) inputSampleL = log(1.0+(255*fabs(inputSampleL))) / log(256);
if (inputSampleL < 0) inputSampleL = -log(1.0+(255*fabs(inputSampleL))) / log(256);
if (inputSampleR > 0) inputSampleR = log(1.0+(255*fabs(inputSampleR))) / log(256);
if (inputSampleR < 0) inputSampleR = -log(1.0+(255*fabs(inputSampleR))) / log(256);
inputSampleL = (tempL * hard) + (inputSampleL * (1.0-hard));
inputSampleR = (tempR * hard) + (inputSampleR * (1.0-hard)); //uLaw encode as part of soft/hard
tempL = inputSampleL;
tempR = inputSampleR;
if (incrementB > 0.0005)
{
if (inputSampleL > 0)
{
tempL = inputSampleL;
while (tempL > 0) {tempL -= incrementB;}
inputSampleL -= tempL;
//it's below 0 so subtracting adds the remainder
}
if (inputSampleR > 0)
{
tempR = inputSampleR;
while (tempR > 0) {tempR -= incrementB;}
inputSampleR -= tempR;
//it's below 0 so subtracting adds the remainder
}
if (inputSampleL < 0)
{
tempL = inputSampleL;
while (tempL < 0) {tempL += incrementB;}
inputSampleL -= tempL;
//it's above 0 so subtracting subtracts the remainder
}
if (inputSampleR < 0)
{
tempR = inputSampleR;
while (tempR < 0) {tempR += incrementB;}
inputSampleR -= tempR;
//it's above 0 so subtracting subtracts the remainder
}
inputSampleL *= (1.0 - incrementB);
inputSampleR *= (1.0 - incrementB);
}
tempL = inputSampleL;
tempR = inputSampleR;
if (inputSampleL > 1.0) inputSampleL = 1.0;
if (inputSampleL < -1.0) inputSampleL = -1.0;
if (inputSampleR > 1.0) inputSampleR = 1.0;
if (inputSampleR < -1.0) inputSampleR = -1.0;
if (inputSampleL > 0) inputSampleL = (pow(256,fabs(inputSampleL))-1.0) / 255;
if (inputSampleL < 0) inputSampleL = -(pow(256,fabs(inputSampleL))-1.0) / 255;
if (inputSampleR > 0) inputSampleR = (pow(256,fabs(inputSampleR))-1.0) / 255;
if (inputSampleR < 0) inputSampleR = -(pow(256,fabs(inputSampleR))-1.0) / 255;
inputSampleL = (tempL * hard) + (inputSampleL * (1.0-hard));
inputSampleR = (tempR * hard) + (inputSampleR * (1.0-hard)); //uLaw decode as part of soft/hard
if (wet !=1.0) {
inputSampleL = (inputSampleL * wet) + (drySampleL * (1.0-wet));
inputSampleR = (inputSampleR * wet) + (drySampleR * (1.0-wet));
}
//Dry/Wet control, defaults to the last slider
lastSampleL = drySampleL;
lastSampleR = drySampleR;
//begin 32 bit stereo floating point dither
int expon; frexpf((float)inputSampleL, &expon);
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
frexpf((float)inputSampleR, &expon);
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
//end 32 bit stereo floating point dither
*out1 = inputSampleL;
*out2 = inputSampleR;
*in1++;
*in2++;
*out1++;
*out2++;
}
}
void DeRez2::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames)
{
double* in1 = inputs[0];
double* in2 = inputs[1];
double* out1 = outputs[0];
double* out2 = outputs[1];
double targetA = pow(A,3)+0.0005;
if (targetA > 1.0) targetA = 1.0;
double soften = (1.0 + targetA)/2;
double targetB = pow(1.0-B,3) / 3;
double hard = C;
double wet = D;
double overallscale = 1.0;
overallscale /= 44100.0;
overallscale *= getSampleRate();
targetA /= overallscale;
while (--sampleFrames >= 0)
{
double inputSampleL = *in1;
double inputSampleR = *in2;
if (fabs(inputSampleL)<1.18e-23) inputSampleL = fpdL * 1.18e-17;
if (fabs(inputSampleR)<1.18e-23) inputSampleR = fpdR * 1.18e-17;
double drySampleL = inputSampleL;
double drySampleR = inputSampleR;
incrementA = ((incrementA*999.0)+targetA)/1000.0;
incrementB = ((incrementB*999.0)+targetB)/1000.0;
//incrementA is the frequency derez
//incrementB is the bit depth derez
position += incrementA;
double outputSampleL = heldSampleL;
double outputSampleR = heldSampleR;
if (position > 1.0)
{
position -= 1.0;
heldSampleL = (lastSampleL * position) + (inputSampleL * (1.0-position));
outputSampleL = (outputSampleL * (1.0-soften)) + (heldSampleL * soften);
//softens the edge of the derez
heldSampleR = (lastSampleR * position) + (inputSampleR * (1.0-position));
outputSampleR = (outputSampleR * (1.0-soften)) + (heldSampleR * soften);
//softens the edge of the derez
}
inputSampleL = outputSampleL;
inputSampleR = outputSampleR;
double tempL = inputSampleL;
double tempR = inputSampleR;
if (inputSampleL != lastOutputSampleL) {
tempL = inputSampleL;
inputSampleL = (inputSampleL * hard) + (lastDrySampleL * (1.0-hard));
//transitions get an intermediate dry sample
lastOutputSampleL = tempL; //only one intermediate sample
} else {
lastOutputSampleL = inputSampleL;
}
if (inputSampleR != lastOutputSampleR) {
tempR = inputSampleR;
inputSampleR = (inputSampleR * hard) + (lastDrySampleR * (1.0-hard));
//transitions get an intermediate dry sample
lastOutputSampleR = tempR; //only one intermediate sample
} else {
lastOutputSampleR = inputSampleR;
}
lastDrySampleL = drySampleL;
lastDrySampleR = drySampleR;
//freq section of soft/hard interpolates dry samples
tempL = inputSampleL;
tempR = inputSampleR;
if (inputSampleL > 1.0) inputSampleL = 1.0;
if (inputSampleL < -1.0) inputSampleL = -1.0;
if (inputSampleR > 1.0) inputSampleR = 1.0;
if (inputSampleR < -1.0) inputSampleR = -1.0;
if (inputSampleL > 0) inputSampleL = log(1.0+(255*fabs(inputSampleL))) / log(256);
if (inputSampleL < 0) inputSampleL = -log(1.0+(255*fabs(inputSampleL))) / log(256);
if (inputSampleR > 0) inputSampleR = log(1.0+(255*fabs(inputSampleR))) / log(256);
if (inputSampleR < 0) inputSampleR = -log(1.0+(255*fabs(inputSampleR))) / log(256);
inputSampleL = (tempL * hard) + (inputSampleL * (1.0-hard));
inputSampleR = (tempR * hard) + (inputSampleR * (1.0-hard)); //uLaw encode as part of soft/hard
tempL = inputSampleL;
tempR = inputSampleR;
if (incrementB > 0.0005)
{
if (inputSampleL > 0)
{
tempL = inputSampleL;
while (tempL > 0) {tempL -= incrementB;}
inputSampleL -= tempL;
//it's below 0 so subtracting adds the remainder
}
if (inputSampleR > 0)
{
tempR = inputSampleR;
while (tempR > 0) {tempR -= incrementB;}
inputSampleR -= tempR;
//it's below 0 so subtracting adds the remainder
}
if (inputSampleL < 0)
{
tempL = inputSampleL;
while (tempL < 0) {tempL += incrementB;}
inputSampleL -= tempL;
//it's above 0 so subtracting subtracts the remainder
}
if (inputSampleR < 0)
{
tempR = inputSampleR;
while (tempR < 0) {tempR += incrementB;}
inputSampleR -= tempR;
//it's above 0 so subtracting subtracts the remainder
}
inputSampleL *= (1.0 - incrementB);
inputSampleR *= (1.0 - incrementB);
}
tempL = inputSampleL;
tempR = inputSampleR;
if (inputSampleL > 1.0) inputSampleL = 1.0;
if (inputSampleL < -1.0) inputSampleL = -1.0;
if (inputSampleR > 1.0) inputSampleR = 1.0;
if (inputSampleR < -1.0) inputSampleR = -1.0;
if (inputSampleL > 0) inputSampleL = (pow(256,fabs(inputSampleL))-1.0) / 255;
if (inputSampleL < 0) inputSampleL = -(pow(256,fabs(inputSampleL))-1.0) / 255;
if (inputSampleR > 0) inputSampleR = (pow(256,fabs(inputSampleR))-1.0) / 255;
if (inputSampleR < 0) inputSampleR = -(pow(256,fabs(inputSampleR))-1.0) / 255;
inputSampleL = (tempL * hard) + (inputSampleL * (1.0-hard));
inputSampleR = (tempR * hard) + (inputSampleR * (1.0-hard)); //uLaw decode as part of soft/hard
if (wet !=1.0) {
inputSampleL = (inputSampleL * wet) + (drySampleL * (1.0-wet));
inputSampleR = (inputSampleR * wet) + (drySampleR * (1.0-wet));
}
//Dry/Wet control, defaults to the last slider
lastSampleL = drySampleL;
lastSampleR = drySampleR;
//begin 64 bit stereo floating point dither
//int expon; frexp((double)inputSampleL, &expon);
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
//inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
//frexp((double)inputSampleR, &expon);
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
//inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
//end 64 bit stereo floating point dither
*out1 = inputSampleL;
*out2 = inputSampleR;
*in1++;
*in2++;
*out1++;
*out2++;
}
}

108
plugin/Source/FX/FXBase.h Executable file
View file

@ -0,0 +1,108 @@
#pragma once
#include <JuceHeader.h>
#define VstInt32 int32_t
#define AudioEffect FXBase
#define AudioEffectX FXBase
#define audioMasterCallback FXBaseCallback
#define VstPlugCategory int
#define kPlugCategEffect 1
#define kVstMaxProgNameLen 32
#define kVstMaxParamStrLen 32
#define kVstMaxProductStrLen 32
#define kVstMaxVendorStrLen 32
#define vst_strncpy strncpy
inline void float2string (float f, char* text, int len)
{
int decimals = 0;
if (std::fabs (f) >= 10.0f)
decimals = 1;
else if (std::fabs (f) > 1.0f)
decimals = 2;
else
decimals = 3;
juce::String str (f, decimals);
str.copyToUTF8 (text, (size_t)len);
}
inline void int2string (float i, char* text, int len)
{
juce::String str (i);
str.copyToUTF8 (text, (size_t)len);
}
inline void dB2string (float value, char* text, int maxLen)
{
if (value <= 0)
vst_strncpy (text, "-oo", (size_t) maxLen);
else
float2string (20.0f * log10 (value), text, maxLen);
}
//==============================================================================
class FXBaseCallback
{
public:
FXBaseCallback (std::function<double()> cb_) : cb (cb_) {}
double getSampleRate()
{
return cb();
}
std::function<double()> cb;
};
//==============================================================================
class FXBase
{
public:
//==============================================================================
FXBase (FXBaseCallback c, int numPrograms_, int numParams_)
: numPrograms (numPrograms_), numParams (numParams_), callback (c)
{
}
virtual ~FXBase() = default;
int getNumInputs() { return numInputs; }
int getNumOutputs() { return numOutputs; }
int getNumParameters() { return numParams; }
//==============================================================================
virtual bool getEffectName(char* name) = 0;
virtual VstPlugCategory getPlugCategory() = 0;
virtual bool getProductString(char* text) = 0;
virtual bool getVendorString(char* text) = 0;
virtual VstInt32 getVendorVersion() = 0;
virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames) = 0;
virtual void processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames) = 0;
virtual void getProgramName(char* name) = 0;
virtual void setProgramName(char* name) = 0;
virtual VstInt32 getChunk (void** data, bool isPreset) { juce::ignoreUnused (data, isPreset); return 0; }
virtual VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset) { juce::ignoreUnused (data, byteSize, isPreset); return 0; }
virtual float getParameter(VstInt32 index) { juce::ignoreUnused (index); return 0; }
virtual void setParameter(VstInt32 index, float value) { juce::ignoreUnused (index, value); }
virtual void getParameterLabel(VstInt32 index, char* text) { juce::ignoreUnused (index, text); }
virtual void getParameterName(VstInt32 index, char* text) { juce::ignoreUnused (index, text); }
virtual void getParameterDisplay(VstInt32 index, char* text) { juce::ignoreUnused (index, text); }
virtual VstInt32 canDo(char *text) = 0;
protected:
//==============================================================================
void setNumInputs (int numIn) { numInputs = numIn; }
void setNumOutputs (int numOut) { numOutputs = numOut; }
void setUniqueID (int) {}
void canProcessReplacing() {}
void canDoubleReplacing() {}
void programsAreChunks (bool) {}
int numInputs = 0, numOutputs = 0, numPrograms = 0, numParams = 0;
FXBaseCallback callback;
double getSampleRate() { return callback.getSampleRate(); }
};

238
plugin/Source/FX/FireAmp.cpp Executable file
View file

@ -0,0 +1,238 @@
/* ========================================
* FireAmp - FireAmp.h
* Copyright (c) 2016 airwindows, Airwindows uses the MIT license
* ======================================== */
#ifndef __Gain_H
#include "FireAmp.h"
#endif
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wfloat-conversion", "-Wimplicit-float-conversion", "-Wunused-parameter")
FireAmp::FireAmp(audioMasterCallback audioMaster) :
AudioEffectX(audioMaster, kNumPrograms, kNumParameters)
{
A = 0.5;
B = 0.5;
C = 0.8;
D = 1.0;
lastSampleL = 0.0;
storeSampleL = 0.0;
smoothAL = 0.0;
smoothBL = 0.0;
smoothCL = 0.0;
smoothDL = 0.0;
smoothEL = 0.0;
smoothFL = 0.0;
smoothGL = 0.0;
smoothHL = 0.0;
smoothIL = 0.0;
smoothJL = 0.0;
smoothKL = 0.0;
smoothLL = 0.0;
iirSampleAL = 0.0;
iirSampleBL = 0.0;
iirSampleCL = 0.0;
iirSampleDL = 0.0;
iirSampleEL = 0.0;
iirSampleFL = 0.0;
iirSampleGL = 0.0;
iirSampleHL = 0.0;
iirSampleIL = 0.0;
iirSampleJL = 0.0;
iirSampleKL = 0.0;
iirSampleLL = 0.0;
iirLowpassL = 0.0;
iirSpkAL = 0.0;
iirSpkBL = 0.0;
iirSubL = 0.0;
lastSampleR = 0.0;
storeSampleR = 0.0;
smoothAR = 0.0;
smoothBR = 0.0;
smoothCR = 0.0;
smoothDR = 0.0;
smoothER = 0.0;
smoothFR = 0.0;
smoothGR = 0.0;
smoothHR = 0.0;
smoothIR = 0.0;
smoothJR = 0.0;
smoothKR = 0.0;
smoothLR = 0.0;
iirSampleAR = 0.0;
iirSampleBR = 0.0;
iirSampleCR = 0.0;
iirSampleDR = 0.0;
iirSampleER = 0.0;
iirSampleFR = 0.0;
iirSampleGR = 0.0;
iirSampleHR = 0.0;
iirSampleIR = 0.0;
iirSampleJR = 0.0;
iirSampleKR = 0.0;
iirSampleLR = 0.0;
iirLowpassR = 0.0;
iirSpkAR = 0.0;
iirSpkBR = 0.0;
iirSubR = 0.0;
for (int fcount = 0; fcount < 257; fcount++) {
OddL[fcount] = 0.0;
EvenL[fcount] = 0.0;
OddR[fcount] = 0.0;
EvenR[fcount] = 0.0;
}
count = 0;
flip = false; //amp
for(int fcount = 0; fcount < 90; fcount++) {
bL[fcount] = 0;
bR[fcount] = 0;
}
smoothCabAL = 0.0; smoothCabBL = 0.0; lastCabSampleL = 0.0; //cab
smoothCabAR = 0.0; smoothCabBR = 0.0; lastCabSampleR = 0.0; //cab
for (int fcount = 0; fcount < 9; fcount++) {
lastRefL[fcount] = 0.0;
lastRefR[fcount] = 0.0;
}
cycle = 0; //undersampling
for (int x = 0; x < fix_total; x++) {
fixA[x] = 0.0;
fixB[x] = 0.0;
fixC[x] = 0.0;
fixD[x] = 0.0;
fixE[x] = 0.0;
fixF[x] = 0.0;
} //filtering
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
//this is reset: values being initialized only once. Startup values, whatever they are.
_canDo.insert("plugAsChannelInsert"); // plug-in can be used as a channel insert effect.
_canDo.insert("plugAsSend"); // plug-in can be used as a send effect.
_canDo.insert("x2in2out");
setNumInputs(kNumInputs);
setNumOutputs(kNumOutputs);
setUniqueID(kUniqueId);
canProcessReplacing(); // supports output replacing
canDoubleReplacing(); // supports double precision processing
programsAreChunks(true);
vst_strncpy (_programName, "Default", kVstMaxProgNameLen); // default program name
}
FireAmp::~FireAmp() {}
VstInt32 FireAmp::getVendorVersion () {return 1000;}
void FireAmp::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);}
void FireAmp::getProgramName(char *name) {vst_strncpy (name, _programName, kVstMaxProgNameLen);}
//airwindows likes to ignore this stuff. Make your own programs, and make a different plugin rather than
//trying to do versioning and preventing people from using older versions. Maybe they like the old one!
static float pinParameter(float data)
{
if (data < 0.0f) return 0.0f;
if (data > 1.0f) return 1.0f;
return data;
}
VstInt32 FireAmp::getChunk (void** data, bool isPreset)
{
float *chunkData = (float *)calloc(kNumParameters, sizeof(float));
chunkData[0] = A;
chunkData[1] = B;
chunkData[2] = C;
chunkData[3] = D;
/* Note: The way this is set up, it will break if you manage to save settings on an Intel
machine and load them on a PPC Mac. However, it's fine if you stick to the machine you
started with. */
*data = chunkData;
return kNumParameters * sizeof(float);
}
VstInt32 FireAmp::setChunk (void* data, VstInt32 byteSize, bool isPreset)
{
float *chunkData = (float *)data;
A = pinParameter(chunkData[0]);
B = pinParameter(chunkData[1]);
C = pinParameter(chunkData[2]);
D = pinParameter(chunkData[3]);
/* We're ignoring byteSize as we found it to be a filthy liar */
/* calculate any other fields you need here - you could copy in
code from setParameter() here. */
return 0;
}
void FireAmp::setParameter(VstInt32 index, float value) {
switch (index) {
case kParamA: A = value; break;
case kParamB: B = value; break;
case kParamC: C = value; break;
case kParamD: D = value; break;
default: throw; // unknown parameter, shouldn't happen!
}
}
float FireAmp::getParameter(VstInt32 index) {
switch (index) {
case kParamA: return A; break;
case kParamB: return B; break;
case kParamC: return C; break;
case kParamD: return D; break;
default: break; // unknown parameter, shouldn't happen!
} return 0.0; //we only need to update the relevant name, this is simple to manage
}
void FireAmp::getParameterName(VstInt32 index, char *text) {
switch (index) {
case kParamA: vst_strncpy (text, "Gain", kVstMaxParamStrLen); break;
case kParamB: vst_strncpy (text, "Tone", kVstMaxParamStrLen); break;
case kParamC: vst_strncpy (text, "Output", kVstMaxParamStrLen); break;
case kParamD: vst_strncpy (text, "Dry/Wet", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} //this is our labels for displaying in the VST host
}
void FireAmp::getParameterDisplay(VstInt32 index, char *text) {
switch (index) {
case kParamA: float2string (A, text, kVstMaxParamStrLen); break;
case kParamB: float2string (B, text, kVstMaxParamStrLen); break;
case kParamC: float2string (C, text, kVstMaxParamStrLen); break;
case kParamD: float2string (D, text, kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} //this displays the values and handles 'popups' where it's discrete choices
}
void FireAmp::getParameterLabel(VstInt32 index, char *text) {
switch (index) {
case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamB: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamC: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamD: vst_strncpy (text, "", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
}
}
VstInt32 FireAmp::canDo(char *text)
{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know
bool FireAmp::getEffectName(char* name) {
vst_strncpy(name, "FireAmp", kVstMaxProductStrLen); return true;
}
VstPlugCategory FireAmp::getPlugCategory() {return kPlugCategEffect;}
bool FireAmp::getProductString(char* text) {
vst_strncpy (text, "airwindows FireAmp", kVstMaxProductStrLen); return true;
}
bool FireAmp::getVendorString(char* text) {
vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true;
}

168
plugin/Source/FX/FireAmp.h Executable file
View file

@ -0,0 +1,168 @@
/* ========================================
* FireAmp - FireAmp.h
* Created 8/12/11 by SPIAdmin
* Copyright (c) 2011 __MyCompanyName__, Airwindows uses the MIT license
* ======================================== */
#pragma once
#include "FXBase.h"
#include <set>
#include <string>
#include <math.h>
class FireAmp :
public AudioEffectX
{
public:
enum {
kParamA = 0,
kParamB = 1,
kParamC = 2,
kParamD = 3,
kNumParameters = 4
}; //
static constexpr int kNumPrograms = 0;
static constexpr int kNumInputs = 2;
static constexpr int kNumOutputs = 2;
static constexpr unsigned long kUniqueId = 'fira'; //Change this to what the AU identity is!
FireAmp(audioMasterCallback audioMaster);
~FireAmp();
virtual bool getEffectName(char* name); // The plug-in name
virtual VstPlugCategory getPlugCategory(); // The general category for the plug-in
virtual bool getProductString(char* text); // This is a unique plug-in string provided by Steinberg
virtual bool getVendorString(char* text); // Vendor info
virtual VstInt32 getVendorVersion(); // Version number
virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
virtual void processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames);
virtual void getProgramName(char *name); // read the name from the host
virtual void setProgramName(char *name); // changes the name of the preset displayed in the host
virtual VstInt32 getChunk (void** data, bool isPreset);
virtual VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset);
virtual float getParameter(VstInt32 index); // get the parameter value at the specified index
virtual void setParameter(VstInt32 index, float value); // set the parameter at index to value
virtual void getParameterLabel(VstInt32 index, char *text); // label for the parameter (eg dB)
virtual void getParameterName(VstInt32 index, char *text); // name of the parameter
virtual void getParameterDisplay(VstInt32 index, char *text); // text description of the current value
virtual VstInt32 canDo(char *text);
private:
char _programName[kVstMaxProgNameLen + 1];
std::set< std::string > _canDo;
double lastSampleL;
double storeSampleL;
double smoothAL;
double smoothBL;
double smoothCL;
double smoothDL;
double smoothEL;
double smoothFL;
double smoothGL;
double smoothHL;
double smoothIL;
double smoothJL;
double smoothKL;
double smoothLL;
double iirSampleAL;
double iirSampleBL;
double iirSampleCL;
double iirSampleDL;
double iirSampleEL;
double iirSampleFL;
double iirSampleGL;
double iirSampleHL;
double iirSampleIL;
double iirSampleJL;
double iirSampleKL;
double iirSampleLL;
double iirLowpassL;
double iirSpkAL;
double iirSpkBL;
double iirSubL;
double OddL[257];
double EvenL[257];
double lastSampleR;
double storeSampleR;
double smoothAR;
double smoothBR;
double smoothCR;
double smoothDR;
double smoothER;
double smoothFR;
double smoothGR;
double smoothHR;
double smoothIR;
double smoothJR;
double smoothKR;
double smoothLR;
double iirSampleAR;
double iirSampleBR;
double iirSampleCR;
double iirSampleDR;
double iirSampleER;
double iirSampleFR;
double iirSampleGR;
double iirSampleHR;
double iirSampleIR;
double iirSampleJR;
double iirSampleKR;
double iirSampleLR;
double iirLowpassR;
double iirSpkAR;
double iirSpkBR;
double iirSubR;
double OddR[257];
double EvenR[257];
bool flip;
int count; //amp
double bL[90];
double lastCabSampleL;
double smoothCabAL;
double smoothCabBL; //cab
double bR[90];
double lastCabSampleR;
double smoothCabAR;
double smoothCabBR; //cab
double lastRefL[10];
double lastRefR[10];
int cycle; //undersampling
enum {
fix_freq,
fix_reso,
fix_a0,
fix_a1,
fix_a2,
fix_b1,
fix_b2,
fix_sL1,
fix_sL2,
fix_sR1,
fix_sR2,
fix_total
}; //fixed frequency biquad filter for ultrasonics, stereo
double fixA[fix_total];
double fixB[fix_total];
double fixC[fix_total];
double fixD[fix_total];
double fixE[fix_total];
double fixF[fix_total]; //filtering
uint32_t fpdL;
uint32_t fpdR;
//default stuff
float A;
float B;
float C;
float D;
};

1709
plugin/Source/FX/FireAmpProc.cpp Executable file

File diff suppressed because it is too large Load diff

258
plugin/Source/FX/GrindAmp.cpp Executable file
View file

@ -0,0 +1,258 @@
/* ========================================
* GrindAmp - GrindAmp.h
* Copyright (c) 2016 airwindows, Airwindows uses the MIT license
* ======================================== */
#ifndef __Gain_H
#include "GrindAmp.h"
#endif
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wfloat-conversion", "-Wimplicit-float-conversion", "-Wunused-parameter")
GrindAmp::GrindAmp(audioMasterCallback audioMaster) :
AudioEffectX(audioMaster, kNumPrograms, kNumParameters)
{
A = 0.5;
B = 0.5;
C = 0.8;
D = 1.0;
smoothAL = 0.0;
smoothBL = 0.0;
smoothCL = 0.0;
smoothDL = 0.0;
smoothEL = 0.0;
smoothFL = 0.0;
smoothGL = 0.0;
smoothHL = 0.0;
smoothIL = 0.0;
smoothJL = 0.0;
smoothKL = 0.0;
secondAL = 0.0;
secondBL = 0.0;
secondCL = 0.0;
secondDL = 0.0;
secondEL = 0.0;
secondFL = 0.0;
secondGL = 0.0;
secondHL = 0.0;
secondIL = 0.0;
secondJL = 0.0;
secondKL = 0.0;
thirdAL = 0.0;
thirdBL = 0.0;
thirdCL = 0.0;
thirdDL = 0.0;
thirdEL = 0.0;
thirdFL = 0.0;
thirdGL = 0.0;
thirdHL = 0.0;
thirdIL = 0.0;
thirdJL = 0.0;
thirdKL = 0.0;
iirSampleAL = 0.0;
iirSampleBL = 0.0;
iirSampleCL = 0.0;
iirSampleDL = 0.0;
iirSampleEL = 0.0;
iirSampleFL = 0.0;
iirSampleGL = 0.0;
iirSampleHL = 0.0;
iirSampleIL = 0.0;
iirLowpassL = 0.0;
iirSubL = 0.0;
storeSampleL = 0.0; //amp
smoothAR = 0.0;
smoothBR = 0.0;
smoothCR = 0.0;
smoothDR = 0.0;
smoothER = 0.0;
smoothFR = 0.0;
smoothGR = 0.0;
smoothHR = 0.0;
smoothIR = 0.0;
smoothJR = 0.0;
smoothKR = 0.0;
secondAR = 0.0;
secondBR = 0.0;
secondCR = 0.0;
secondDR = 0.0;
secondER = 0.0;
secondFR = 0.0;
secondGR = 0.0;
secondHR = 0.0;
secondIR = 0.0;
secondJR = 0.0;
secondKR = 0.0;
thirdAR = 0.0;
thirdBR = 0.0;
thirdCR = 0.0;
thirdDR = 0.0;
thirdER = 0.0;
thirdFR = 0.0;
thirdGR = 0.0;
thirdHR = 0.0;
thirdIR = 0.0;
thirdJR = 0.0;
thirdKR = 0.0;
iirSampleAR = 0.0;
iirSampleBR = 0.0;
iirSampleCR = 0.0;
iirSampleDR = 0.0;
iirSampleER = 0.0;
iirSampleFR = 0.0;
iirSampleGR = 0.0;
iirSampleHR = 0.0;
iirSampleIR = 0.0;
iirLowpassR = 0.0;
iirSubR = 0.0;
storeSampleR = 0.0; //amp
for(int fcount = 0; fcount < 90; fcount++) {
bL[fcount] = 0;
bR[fcount] = 0;
}
smoothCabAL = 0.0; smoothCabBL = 0.0; lastCabSampleL = 0.0; //cab
smoothCabAR = 0.0; smoothCabBR = 0.0; lastCabSampleR = 0.0; //cab
for (int fcount = 0; fcount < 9; fcount++) {
lastRefL[fcount] = 0.0;
lastRefR[fcount] = 0.0;
}
cycle = 0; //undersampling
for (int x = 0; x < fix_total; x++) {
fixA[x] = 0.0;
fixB[x] = 0.0;
fixC[x] = 0.0;
fixD[x] = 0.0;
fixE[x] = 0.0;
fixF[x] = 0.0;
} //filtering
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
//this is reset: values being initialized only once. Startup values, whatever they are.
_canDo.insert("plugAsChannelInsert"); // plug-in can be used as a channel insert effect.
_canDo.insert("plugAsSend"); // plug-in can be used as a send effect.
_canDo.insert("x2in2out");
setNumInputs(kNumInputs);
setNumOutputs(kNumOutputs);
setUniqueID(kUniqueId);
canProcessReplacing(); // supports output replacing
canDoubleReplacing(); // supports double precision processing
programsAreChunks(true);
vst_strncpy (_programName, "Default", kVstMaxProgNameLen); // default program name
}
GrindAmp::~GrindAmp() {}
VstInt32 GrindAmp::getVendorVersion () {return 1000;}
void GrindAmp::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);}
void GrindAmp::getProgramName(char *name) {vst_strncpy (name, _programName, kVstMaxProgNameLen);}
//airwindows likes to ignore this stuff. Make your own programs, and make a different plugin rather than
//trying to do versioning and preventing people from using older versions. Maybe they like the old one!
static float pinParameter(float data)
{
if (data < 0.0f) return 0.0f;
if (data > 1.0f) return 1.0f;
return data;
}
VstInt32 GrindAmp::getChunk (void** data, bool isPreset)
{
float *chunkData = (float *)calloc(kNumParameters, sizeof(float));
chunkData[0] = A;
chunkData[1] = B;
chunkData[2] = C;
chunkData[3] = D;
/* Note: The way this is set up, it will break if you manage to save settings on an Intel
machine and load them on a PPC Mac. However, it's fine if you stick to the machine you
started with. */
*data = chunkData;
return kNumParameters * sizeof(float);
}
VstInt32 GrindAmp::setChunk (void* data, VstInt32 byteSize, bool isPreset)
{
float *chunkData = (float *)data;
A = pinParameter(chunkData[0]);
B = pinParameter(chunkData[1]);
C = pinParameter(chunkData[2]);
D = pinParameter(chunkData[3]);
/* We're ignoring byteSize as we found it to be a filthy liar */
/* calculate any other fields you need here - you could copy in
code from setParameter() here. */
return 0;
}
void GrindAmp::setParameter(VstInt32 index, float value) {
switch (index) {
case kParamA: A = value; break;
case kParamB: B = value; break;
case kParamC: C = value; break;
case kParamD: D = value; break;
default: throw; // unknown parameter, shouldn't happen!
}
}
float GrindAmp::getParameter(VstInt32 index) {
switch (index) {
case kParamA: return A; break;
case kParamB: return B; break;
case kParamC: return C; break;
case kParamD: return D; break;
default: break; // unknown parameter, shouldn't happen!
} return 0.0; //we only need to update the relevant name, this is simple to manage
}
void GrindAmp::getParameterName(VstInt32 index, char *text) {
switch (index) {
case kParamA: vst_strncpy (text, "Gain", kVstMaxParamStrLen); break;
case kParamB: vst_strncpy (text, "Tone", kVstMaxParamStrLen); break;
case kParamC: vst_strncpy (text, "Output", kVstMaxParamStrLen); break;
case kParamD: vst_strncpy (text, "Dry/Wet", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} //this is our labels for displaying in the VST host
}
void GrindAmp::getParameterDisplay(VstInt32 index, char *text) {
switch (index) {
case kParamA: float2string (A, text, kVstMaxParamStrLen); break;
case kParamB: float2string (B, text, kVstMaxParamStrLen); break;
case kParamC: float2string (C, text, kVstMaxParamStrLen); break;
case kParamD: float2string (D, text, kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} //this displays the values and handles 'popups' where it's discrete choices
}
void GrindAmp::getParameterLabel(VstInt32 index, char *text) {
switch (index) {
case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamB: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamC: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamD: vst_strncpy (text, "", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
}
}
VstInt32 GrindAmp::canDo(char *text)
{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know
bool GrindAmp::getEffectName(char* name) {
vst_strncpy(name, "GrindAmp", kVstMaxProductStrLen); return true;
}
VstPlugCategory GrindAmp::getPlugCategory() {return kPlugCategEffect;}
bool GrindAmp::getProductString(char* text) {
vst_strncpy (text, "airwindows GrindAmp", kVstMaxProductStrLen); return true;
}
bool GrindAmp::getVendorString(char* text) {
vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true;
}

190
plugin/Source/FX/GrindAmp.h Executable file
View file

@ -0,0 +1,190 @@
/* ========================================
* GrindAmp - GrindAmp.h
* Created 8/12/11 by SPIAdmin
* Copyright (c) 2011 __MyCompanyName__, Airwindows uses the MIT license
* ======================================== */
#pragma once
#include "FXBase.h"
#include <set>
#include <string>
#include <math.h>
class GrindAmp :
public AudioEffectX
{
public:
enum {
kParamA = 0,
kParamB = 1,
kParamC = 2,
kParamD = 3,
kNumParameters = 4
}; //
static constexpr int kNumPrograms = 0;
static constexpr int kNumInputs = 2;
static constexpr int kNumOutputs = 2;
static constexpr unsigned long kUniqueId = 'grda'; //Change this to what the AU identity is!
GrindAmp(audioMasterCallback audioMaster);
~GrindAmp();
virtual bool getEffectName(char* name); // The plug-in name
virtual VstPlugCategory getPlugCategory(); // The general category for the plug-in
virtual bool getProductString(char* text); // This is a unique plug-in string provided by Steinberg
virtual bool getVendorString(char* text); // Vendor info
virtual VstInt32 getVendorVersion(); // Version number
virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
virtual void processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames);
virtual void getProgramName(char *name); // read the name from the host
virtual void setProgramName(char *name); // changes the name of the preset displayed in the host
virtual VstInt32 getChunk (void** data, bool isPreset);
virtual VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset);
virtual float getParameter(VstInt32 index); // get the parameter value at the specified index
virtual void setParameter(VstInt32 index, float value); // set the parameter at index to value
virtual void getParameterLabel(VstInt32 index, char *text); // label for the parameter (eg dB)
virtual void getParameterName(VstInt32 index, char *text); // name of the parameter
virtual void getParameterDisplay(VstInt32 index, char *text); // text description of the current value
virtual VstInt32 canDo(char *text);
private:
char _programName[kVstMaxProgNameLen + 1];
std::set< std::string > _canDo;
double smoothAL;
double smoothBL;
double smoothCL;
double smoothDL;
double smoothEL;
double smoothFL;
double smoothGL;
double smoothHL;
double smoothIL;
double smoothJL;
double smoothKL;
double secondAL;
double secondBL;
double secondCL;
double secondDL;
double secondEL;
double secondFL;
double secondGL;
double secondHL;
double secondIL;
double secondJL;
double secondKL;
double thirdAL;
double thirdBL;
double thirdCL;
double thirdDL;
double thirdEL;
double thirdFL;
double thirdGL;
double thirdHL;
double thirdIL;
double thirdJL;
double thirdKL;
double iirSampleAL;
double iirSampleBL;
double iirSampleCL;
double iirSampleDL;
double iirSampleEL;
double iirSampleFL;
double iirSampleGL;
double iirSampleHL;
double iirSampleIL;
double iirLowpassL;
double iirSubL;
double storeSampleL; //amp
double smoothAR;
double smoothBR;
double smoothCR;
double smoothDR;
double smoothER;
double smoothFR;
double smoothGR;
double smoothHR;
double smoothIR;
double smoothJR;
double smoothKR;
double secondAR;
double secondBR;
double secondCR;
double secondDR;
double secondER;
double secondFR;
double secondGR;
double secondHR;
double secondIR;
double secondJR;
double secondKR;
double thirdAR;
double thirdBR;
double thirdCR;
double thirdDR;
double thirdER;
double thirdFR;
double thirdGR;
double thirdHR;
double thirdIR;
double thirdJR;
double thirdKR;
double iirSampleAR;
double iirSampleBR;
double iirSampleCR;
double iirSampleDR;
double iirSampleER;
double iirSampleFR;
double iirSampleGR;
double iirSampleHR;
double iirSampleIR;
double iirLowpassR;
double iirSubR;
double storeSampleR; //amp
double bL[90];
double lastCabSampleL;
double smoothCabAL;
double smoothCabBL; //cab
double bR[90];
double lastCabSampleR;
double smoothCabAR;
double smoothCabBR; //cab
double lastRefL[10];
double lastRefR[10];
int cycle; //undersampling
enum {
fix_freq,
fix_reso,
fix_a0,
fix_a1,
fix_a2,
fix_b1,
fix_b2,
fix_sL1,
fix_sL2,
fix_sR1,
fix_sR2,
fix_total
}; //fixed frequency biquad filter for ultrasonics, stereo
double fixA[fix_total];
double fixB[fix_total];
double fixC[fix_total];
double fixD[fix_total];
double fixE[fix_total];
double fixF[fix_total]; //filtering
uint32_t fpdL;
uint32_t fpdR;
//default stuff
float A;
float B;
float C;
float D;
};

1652
plugin/Source/FX/GrindAmpProc.cpp Executable file

File diff suppressed because it is too large Load diff

View file

@ -638,15 +638,16 @@ public:
getProperties().set ("fxId", fxGate);
addEnable (proc.gateParams.enable);
getHeader().setMouseCursor (juce::MouseCursor::LeftRightResizeCursor);
addControl (new gin::Select (proc.gateParams.beat), 0, 0);
addControl (new gin::Knob (proc.gateParams.length), 1, 0);
addControl (new gin::Knob (proc.gateParams.attack), 2, 0);
addControl (new gin::Knob (proc.gateParams.release), 3, 0);
addControl (new gin::Select (proc.gateParams.beat));
addControl (new gin::Knob (proc.gateParams.length));
addControl (new gin::Knob (proc.gateParams.attack));
addControl (new gin::Knob (proc.gateParams.release));
auto g = new gin::GateEffectComponent (Cfg::numGateSteps);
g->setParams (proc.gateParams.length, proc.gateParams.l, proc.gateParams.r, proc.gateParams.enable);
addControl (g, 0, 1, 4, 1);
addControl (g);
}
WavetableAudioProcessor& proc;
@ -663,6 +664,7 @@ public:
getProperties().set ("fxId", fxChorus);
addEnable (proc.chorusParams.enable);
getHeader().setMouseCursor (juce::MouseCursor::LeftRightResizeCursor);
addControl (new gin::Knob (proc.chorusParams.delay), 0, 0);
addControl (new gin::Knob (proc.chorusParams.rate), 1, 0);
@ -686,11 +688,110 @@ public:
getProperties().set ("fxId", fxDistort);
addEnable (proc.distortionParams.enable);
getHeader().setMouseCursor (juce::MouseCursor::LeftRightResizeCursor);
addControl (new gin::Knob (proc.distortionParams.amount), 0, 0);
{
page1 = new juce::Component ("page1");
page1->setInterceptsMouseClicks (false, true);
addControl (page1);
addControl (page1, new gin::Knob (proc.distortionParams.amount));
}
{
page2 = new juce::Component ("page2");
page2->setInterceptsMouseClicks (false, true);
addControl (page2);
addControl (page2, new gin::Knob (proc.bitcrusherParams.rate));
addControl (page2, new gin::Knob (proc.bitcrusherParams.rez));
addControl (page2, new gin::Knob (proc.bitcrusherParams.hard));
addControl (page2, new gin::Knob (proc.bitcrusherParams.mix));
}
{
page3 = new juce::Component ("page3");
page3->setInterceptsMouseClicks (false, true);
addControl (page3);
addControl (page3, new gin::Knob (proc.fireAmpParams.gain));
addControl (page3, new gin::Knob (proc.fireAmpParams.tone));
addControl (page3, new gin::Knob (proc.fireAmpParams.output));
addControl (page3, new gin::Knob (proc.fireAmpParams.mix));
}
{
page4 = new juce::Component ("page4");
page4->setInterceptsMouseClicks (false, true);
addControl (page4);
addControl (page4, new gin::Knob (proc.grindAmpParams.gain));
addControl (page4, new gin::Knob (proc.grindAmpParams.tone));
addControl (page4, new gin::Knob (proc.grindAmpParams.output));
addControl (page4, new gin::Knob (proc.grindAmpParams.mix));
}
auto& h = getHeader();
h.addAndMakeVisible (modeButton);
modeButton.onClick = [this]
{
juce::PopupMenu m;
m.setLookAndFeel (&getLookAndFeel());
m.addItem ("Simple", true, proc.fxParams.distMode->getUserValueInt() == 0, [this]
{
proc.fxParams.distMode->setUserValue (0.0f);
});
m.addItem ("Bitcrusher", true, proc.fxParams.distMode->getUserValueInt() == 1, [this]
{
proc.fxParams.distMode->setUserValue (1.0f);
});
m.addItem ("Fire Amp", true, proc.fxParams.distMode->getUserValueInt() == 2, [this]
{
proc.fxParams.distMode->setUserValue (2.0f);
});
m.addItem ("Grind Amp", true, proc.fxParams.distMode->getUserValueInt() == 3, [this]
{
proc.fxParams.distMode->setUserValue (3.0f);
});
m.showMenuAsync ({});
};
watchParam (proc.fxParams.distMode);
paramChanged();
}
void paramChanged() override
{
gin::ParamBox::paramChanged();
auto mode = proc.fxParams.distMode->getUserValueInt();
page1->setVisible (mode == 0);
page2->setVisible (mode == 1);
page3->setVisible (mode == 2);
page4->setVisible (mode == 3);
auto& h = getHeader();
if (mode == 0) h.setTitle ("Dist");
if (mode == 1) h.setTitle ("Crush");
if (mode == 2) h.setTitle ("Fire");
if (mode == 3) h.setTitle ("Grind");
}
juce::Component* page1;
juce::Component* page2;
juce::Component* page3;
juce::Component* page4;
WavetableAudioProcessor& proc;
gin::SVGButton modeButton { "mode", gin::Assets::caretDown, 6 };
};
//==============================================================================
@ -704,6 +805,7 @@ public:
getProperties().set ("fxId", fxDelay);
addEnable (proc.delayParams.enable);
getHeader().setMouseCursor (juce::MouseCursor::LeftRightResizeCursor);
addControl (t = new gin::Knob (proc.delayParams.time), 0, 0);
addControl (b = new gin::Select (proc.delayParams.beat), 0, 0);
@ -742,6 +844,7 @@ public:
getProperties().set ("fxId", fxReverb);
addEnable (proc.reverbParams.enable);
getHeader().setMouseCursor (juce::MouseCursor::LeftRightResizeCursor);
addControl (new gin::Knob (proc.reverbParams.size), 0, 0);
addControl (new gin::Knob (proc.reverbParams.decay), 1, 0);

View file

@ -365,11 +365,48 @@ void WavetableAudioProcessor::ReverbParams::setup (WavetableAudioProcessor& p)
//==============================================================================
void WavetableAudioProcessor::FXParams::setup (WavetableAudioProcessor& p)
{
fx1 = p.addIntParam ("fxOrder1", "FX1", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxGate, 0.0f);
fx2 = p.addIntParam ("fxOrder2", "FX2", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxChorus, 0.0f);
fx3 = p.addIntParam ("fxOrder3", "FX3", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxDistort, 0.0f);
fx4 = p.addIntParam ("fxOrder4", "FX4", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxDelay, 0.0f);
fx5 = p.addIntParam ("fxOrder5", "FX5", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxReverb, 0.0f);
fx1 = p.addIntParam ("fxOrder1", "FX1", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxGate, 0.0f);
fx2 = p.addIntParam ("fxOrder2", "FX2", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxChorus, 0.0f);
fx3 = p.addIntParam ("fxOrder3", "FX3", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxDistort, 0.0f);
fx4 = p.addIntParam ("fxOrder4", "FX4", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxDelay, 0.0f);
fx5 = p.addIntParam ("fxOrder5", "FX5", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxReverb, 0.0f);
distMode = p.addIntParam ("distMode", "Dist Mode", "", "", { 0.0, 3.0, 1.0, 1.0 }, 0, 0.0f);
}
//==============================================================================
void WavetableAudioProcessor::BitCrusherParams::setup (WavetableAudioProcessor& p)
{
juce::String id = "crush";
juce::String nm = "Crush ";
rate = p.addExtParam (id + "rate", nm + "Rate", "Rate", "", { 0.0, 1.0, 0.0, 1.0f }, 0.5f, 0.0f);
rez = p.addExtParam (id + "rez", nm + "Rez", "Rez", "", { 0.0, 1.0, 0.0, 1.0f }, 0.5f, 0.0f);
hard = p.addExtParam (id + "hard", nm + "Hard", "Hard", "", { 0.0, 1.0, 0.0, 1.0f }, 0.8f, 0.0f);
mix = p.addExtParam (id + "mix", nm + "Mix", "Mix", "", { 0.0, 1.0, 0.0, 1.0f }, 1.0f, 0.0f);
}
//==============================================================================
void WavetableAudioProcessor::FireAmpParams::setup (WavetableAudioProcessor& p)
{
juce::String id = "fire";
juce::String nm = "Fire ";
gain = p.addExtParam (id + "gain", nm + "Gain", "Gain", "", { 0.0, 1.0, 0.0, 1.0f }, 0.5f, 0.0f);
tone = p.addExtParam (id + "tone", nm + "Tone", "Tone", "", { 0.0, 1.0, 0.0, 1.0f }, 0.5f, 0.0f);
output = p.addExtParam (id + "output", nm + "Output", "Output", "", { 0.0, 1.0, 0.0, 1.0f }, 0.8f, 0.0f);
mix = p.addExtParam (id + "mix", nm + "Mix", "Mix", "", { 0.0, 1.0, 0.0, 1.0f }, 1.0f, 0.0f);
}
//==============================================================================
void WavetableAudioProcessor::GrindAmpParams::setup (WavetableAudioProcessor& p)
{
juce::String id = "grind";
juce::String nm = "Grind ";
gain = p.addExtParam (id + "gain", nm + "Gain", "Gain", "", { 0.0, 1.0, 0.0, 1.0f }, 0.5f, 0.0f);
tone = p.addExtParam (id + "tone", nm + "Tone", "Tone", "", { 0.0, 1.0, 0.0, 1.0f }, 0.5f, 0.0f);
output = p.addExtParam (id + "output", nm + "Output", "Output", "", { 0.0, 1.0, 0.0, 1.0f }, 0.8f, 0.0f);
mix = p.addExtParam (id + "mix", nm + "Mix", "Mix", "", { 0.0, 1.0, 0.0, 1.0f }, 1.0f, 0.0f);
}
#if 0
@ -467,7 +504,10 @@ void extractWavetables()
//==============================================================================
WavetableAudioProcessor::WavetableAudioProcessor()
: gin::Processor (juce::AudioProcessor::BusesProperties().withOutput ("Output", juce::AudioChannelSet::stereo(), true), false)
: gin::Processor (juce::AudioProcessor::BusesProperties().withOutput ("Output", juce::AudioChannelSet::stereo(), true), false),
bitcrusher (FXBaseCallback ([this] { return gin::Processor::getSampleRate(); })),
fireAmp (FXBaseCallback ([this] { return gin::Processor::getSampleRate(); })),
grindAmp (FXBaseCallback ([this] { return gin::Processor::getSampleRate(); }))
{
{
auto sz = 0;
@ -510,6 +550,11 @@ WavetableAudioProcessor::WavetableAudioProcessor()
reverbParams.setup (*this);
fxParams.setup (*this);
versionHint++;
bitcrusherParams.setup (*this);
fireAmpParams.setup (*this);
grindAmpParams.setup (*this);
for (int i = 0; i < 50; i++)
{
auto voice = new WavetableVoice (*this);
@ -885,8 +930,24 @@ void WavetableAudioProcessor::applyEffect (juce::AudioSampleBuffer& buffer, int
// Apply Distortion
if (fxId == fxDistort && distortionParams.enable->isOn())
{
auto clip = 1.0f / (2.0f * distortionVal);
gin::Distortion::processBlock (buffer, distortionVal, -clip, clip);
auto mode = fxParams.distMode->getUserValueInt();
if (mode == 0)
{
auto clip = 1.0f / (2.0f * distortionVal);
gin::Distortion::processBlock (buffer, distortionVal, -clip, clip);
}
else if (mode == 1)
{
bitcrusher.processReplacing ((float**)buffer.getArrayOfWritePointers(), (float**)buffer.getArrayOfWritePointers(), buffer.getNumSamples());
}
else if (mode == 2)
{
fireAmp.processReplacing ((float**)buffer.getArrayOfWritePointers(), (float**)buffer.getArrayOfWritePointers(), buffer.getNumSamples());
}
else if (mode == 3)
{
grindAmp.processReplacing ((float**)buffer.getArrayOfWritePointers(), (float**)buffer.getArrayOfWritePointers(), buffer.getNumSamples());
}
}
// Apply Delay
@ -999,7 +1060,34 @@ void WavetableAudioProcessor::updateParams (int newBlockSize)
// Update Distortion
if (distortionParams.enable->isOn())
distortionVal = modMatrix.getValue (distortionParams.amount);
{
auto mode = fxParams.distMode->getUserValueInt();
if (mode == 0)
{
distortionVal = modMatrix.getValue (distortionParams.amount);
}
else if (mode == 1)
{
bitcrusher.setParameter (0, modMatrix.getValue (bitcrusherParams.rez));
bitcrusher.setParameter (1, modMatrix.getValue (bitcrusherParams.rate));
bitcrusher.setParameter (2, modMatrix.getValue (bitcrusherParams.hard));
bitcrusher.setParameter (3, modMatrix.getValue (bitcrusherParams.mix));
}
else if (mode == 2)
{
fireAmp.setParameter (0, modMatrix.getValue (fireAmpParams.gain));
fireAmp.setParameter (1, modMatrix.getValue (fireAmpParams.tone));
fireAmp.setParameter (2, modMatrix.getValue (fireAmpParams.output));
fireAmp.setParameter (3, modMatrix.getValue (fireAmpParams.mix));
}
else if (mode == 3)
{
grindAmp.setParameter (0, modMatrix.getValue (grindAmpParams.gain));
grindAmp.setParameter (1, modMatrix.getValue (grindAmpParams.tone));
grindAmp.setParameter (2, modMatrix.getValue (grindAmpParams.output));
grindAmp.setParameter (3, modMatrix.getValue (grindAmpParams.mix));
}
}
// Update Delay
if (delayParams.enable->isOn())
@ -1032,7 +1120,6 @@ void WavetableAudioProcessor::updateParams (int newBlockSize)
reverb.setDamping (modMatrix.getValue (reverbParams.damping));
reverb.setPredelay (modMatrix.getValue (reverbParams.predelay));
reverb.setMix (modMatrix.getValue (reverbParams.mix));
}
// Output gain

View file

@ -3,6 +3,9 @@
#include <JuceHeader.h>
#include "WavetableVoice.h"
#include "FX/DeRez2.h"
#include "FX/FireAmp.h"
#include "FX/GrindAmp.h"
constexpr auto fxGate = 0;
constexpr auto fxChorus = 1;
@ -232,13 +235,46 @@ public:
{
FXParams() = default;
gin::Parameter::Ptr fx1, fx2, fx3, fx4, fx5;
gin::Parameter::Ptr fx1, fx2, fx3, fx4, fx5, distMode;
void setup (WavetableAudioProcessor& p);
JUCE_DECLARE_NON_COPYABLE (FXParams)
};
struct BitCrusherParams
{
BitCrusherParams() = default;
gin::Parameter::Ptr rate, rez, hard, mix;
void setup (WavetableAudioProcessor& p);
JUCE_DECLARE_NON_COPYABLE (BitCrusherParams)
};
struct FireAmpParams
{
FireAmpParams() = default;
gin::Parameter::Ptr gain, tone, output, mix;
void setup (WavetableAudioProcessor& p);
JUCE_DECLARE_NON_COPYABLE (FireAmpParams)
};
struct GrindAmpParams
{
GrindAmpParams() = default;
gin::Parameter::Ptr gain, tone, output, mix;
void setup (WavetableAudioProcessor& p);
JUCE_DECLARE_NON_COPYABLE (GrindAmpParams)
};
//==============================================================================
gin::ModSrcId modSrcPressure, modSrcTimbre, modSrcPitchbend, modScrPitchBend,
modSrcFilter, modSrcNote, modSrcVelocity, modSrcStep, modSrcMonoStep;
@ -264,6 +300,9 @@ public:
DistortionParams distortionParams;
DelayParams delayParams;
ReverbParams reverbParams;
BitCrusherParams bitcrusherParams;
FireAmpParams fireAmpParams;
GrindAmpParams grindAmpParams;
UIParams uiParams;
//==============================================================================
@ -274,6 +313,9 @@ public:
gin::GainProcessor outputGain;
gin::AudioFifo scopeFifo { 2, 44100 };
float distortionVal = 0.0f;
DeRez2 bitcrusher;
FireAmp fireAmp;
GrindAmp grindAmp;
juce::OwnedArray<gin::BandLimitedLookupTable> osc1Tables;
juce::OwnedArray<gin::BandLimitedLookupTable> osc2Tables;