Skip to content

Commit

Permalink
Update to Latest Airwin
Browse files Browse the repository at this point in the history
  • Loading branch information
baconpaul committed Sep 17, 2023
1 parent ec754da commit 922733a
Show file tree
Hide file tree
Showing 10 changed files with 2,203 additions and 165 deletions.
2 changes: 1 addition & 1 deletion libs/airwindows
Submodule airwindows updated 163 files
21 changes: 21 additions & 0 deletions res/awpdoc/ResEQ2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ResEQ2 is a single, sharp, sonorous mid peak.

This is another 'piece of an upcoming great plugin'. In order to do an MCI console properly I had to do a good mid peak.

And we're talking 'way better than just a sharp biquad filter' mid peak. I needed clarity and character beyond what regular digital EQ cookbooks could cook up.

ResEQ2 continues on the work I started in the original ResEQ, where I observed that Manley EQ impulses for sharp resonances seemed to be like a sine-like ring, except the onset did NOT seem to be at the same frequency: seemed to start faster, even double the frequency. I made a whole plugin, ResEQ, giving it my best shot for generating multiple resonant 'rings' and combining them, to produce a convolution impulse that was the sum of multiple analog-like resoances. It still exists: it's way before I routinely worked at 96k, and it's got a lot of quirks, but it does get a distinct sound.

I returned to those deep, murky waters when trying to come up with a sweepable mid peak like certain classic analog consoles.

ResEQ2 is the result. It's the opposite of what you'll normally find in great classic analog consoles. A lot of the classics really had quite limited analog EQ: detailed parametric sculpting came in with SSL, and to some extent API before that. In the olden days, things were a lot simpler (and you gained something sonically from this simplicity).

But there were a few special cases, and so you had MCI's sweepable mid, that could only boost. Not cut. It just gave you a sort of ring, wherever you wanted it. Not the most flexible circuit… but a hitmaker.

This is because, contrary to modern practice, there's huge power in being able to single out a midrange, upper-mid, or treble frequency, and sort of just open up the top of it so it can get effortlessly loud. Instead of just blasting everything, you find one presence peak on your track that really lets it speak, and you just give that a boost. More peak energy, more clarity exactly where it's most useful, and it's almost never in the same place for different instruments or vocalists, so the combined sound of the mix cuts through on dozens of sonorities at once, and everything is powerful and clear.

It's the mids equivalent of Airwindows Weight for bass, and it works incredibly well (even if you do it with biquads or EQ-design cookbooks). And I don't have the analog-Console projects finished yet… but you can have this part of it now.

Use the 'ow argh way too extreme' settings like 1.0, where everything kind of turns into an audio laser, to dial in exactly what spot opens up an instrument or voice for maximum passion and sonority. Then, dial it back to around 0.5 and begin increasing it, seeing at what point you've got too much of a good thing. ResEQ2 is great at being a subtle light-bringer and giving clarity to a track. It's also a full-on energy weapon that can be set to 'way too much', so use it however you please. The resonance increases as you turn it up, so feel free to dial it back if it gets ringy. Probably not a good plugin for mixing live sound unless you like dial-a-feedback :) hope you enjoy ResEQ2!


332 changes: 168 additions & 164 deletions src/ModuleAdd.h

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/autogen_airwin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ set(AIRWIN_SOURCES
src/autogen_airwin/Console8SubOutProc.cpp
src/autogen_airwin/Creature.cpp
src/autogen_airwin/CreatureProc.cpp
src/autogen_airwin/CrickBass.cpp
src/autogen_airwin/CrickBassProc.cpp
src/autogen_airwin/CrunchyGrooveWear.cpp
src/autogen_airwin/CrunchyGrooveWearProc.cpp
src/autogen_airwin/Crystal.cpp
Expand Down Expand Up @@ -527,6 +529,8 @@ set(AIRWIN_SOURCES
src/autogen_airwin/RemapProc.cpp
src/autogen_airwin/ResEQ.cpp
src/autogen_airwin/ResEQProc.cpp
src/autogen_airwin/ResEQ2.cpp
src/autogen_airwin/ResEQ2Proc.cpp
src/autogen_airwin/Reverb.cpp
src/autogen_airwin/ReverbProc.cpp
src/autogen_airwin/Righteous4.cpp
Expand Down
187 changes: 187 additions & 0 deletions src/autogen_airwin/CrickBass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/* ========================================
* CrickBass - CrickBass.h
* Copyright (c) airwindows, Airwindows uses the MIT license
* ======================================== */

#ifndef __CrickBass_H
#include "CrickBass.h"
#endif
namespace airwin2rack::CrickBass {

AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new CrickBass(audioMaster);}

CrickBass::CrickBass(audioMasterCallback audioMaster) :
AudioEffectX(audioMaster, kNumPrograms, kNumParameters)
{
A = 0.5;
B = 0.5;

lastASampleL = 0.0;
lastSlewL = 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;

lastASampleR = 0.0;
lastSlewR = 0.0;
iirSampleAR = 0.0;
iirSampleBR = 0.0;
iirSampleCR = 0.0;
iirSampleDR = 0.0;
iirSampleER = 0.0;
OddAR = 0.0;
OddBR = 0.0;
OddCR = 0.0;
OddDR = 0.0;
OddER = 0.0;
EvenAR = 0.0;
EvenBR = 0.0;
EvenCR = 0.0;
EvenDR = 0.0;
EvenER = 0.0;

for (int fcount = 0; fcount < 257; fcount++) {
OddL[fcount] = 0.0;
EvenL[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

lastSampleR = 0.0;
wasPosClipR = false;
wasNegClipR = false;
for (int x = 0; x < 16; x++) intermediateR[x] = 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
}

CrickBass::~CrickBass() {}
VstInt32 CrickBass::getVendorVersion () {return 1000;}
void CrickBass::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);}
void CrickBass::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;
}

void CrickBass::setParameter(VstInt32 index, float value) {
switch (index) {
case kParamA: A = value; break;
case kParamB: B = value; break;
default: break; // unknown parameter, shouldn't happen!
}
}

float CrickBass::getParameter(VstInt32 index) {
switch (index) {
case kParamA: return A; break;
case kParamB: return B; 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 CrickBass::getParameterName(VstInt32 index, char *text) {
switch (index) {
case kParamA: vst_strncpy (text, "Drive", kVstMaxParamStrLen); break;
case kParamB: vst_strncpy (text, "Tone", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} //this is our labels for displaying in the VST host
}

void CrickBass::getParameterDisplay(VstInt32 index, char *text) {
switch (index) {
case kParamA: float2string (A, text, kVstMaxParamStrLen); break;
case kParamB: float2string (B, text, kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} //this displays the values and handles 'popups' where it's discrete choices
}

void CrickBass::getParameterLabel(VstInt32 index, char *text) {
switch (index) {
case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break;
case kParamB: vst_strncpy (text, "", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
}
}

VstInt32 CrickBass::canDo(char *text)
{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know

bool CrickBass::getEffectName(char* name) {
vst_strncpy(name, "CrickBass", kVstMaxProductStrLen); return true;
}

VstPlugCategory CrickBass::getPlugCategory() {return kPlugCategEffect;}

bool CrickBass::getProductString(char* text) {
vst_strncpy (text, "airwindows CrickBass", kVstMaxProductStrLen); return true;
}

bool CrickBass::getVendorString(char* text) {
vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true;
}
bool CrickBass::parameterTextToValue(VstInt32 index, const char *text, float &value) {
switch(index) {
case kParamA: { auto b = string2float(text, value); return b; break; }
case kParamB: { auto b = string2float(text, value); return b; break; }

}
return false;
}
bool CrickBass::canConvertParameterTextToValue(VstInt32 index) {
switch(index) {
case kParamA: return true;
case kParamB: return true;

}
return false;
}
} // end namespace
145 changes: 145 additions & 0 deletions src/autogen_airwin/CrickBass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* ========================================
* CrickBass - CrickBass.h
* Created 8/12/11 by SPIAdmin
* Copyright (c) Airwindows, Airwindows uses the MIT license
* ======================================== */

#ifndef __CrickBass_CrickBass_H
#define __CrickBass_CrickBass_H

#ifndef __audioeffect__
#include "../airwin2rackbase.h"
#endif

#include <set>
#include <string>
#include <math.h>

namespace airwin2rack::CrickBass {
enum {
kParamA = 0,
kParamB = 1,
kNumParameters = 2
}; //

const int kNumPrograms = 0;
const int kNumInputs = 2;
const int kNumOutputs = 2;
const unsigned long kUniqueId = 'crik'; //Change this to what the AU identity is!

class CrickBass :
public AudioEffectX
{
public:
CrickBass(audioMasterCallback audioMaster);
~CrickBass();
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 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
// Added by the perl as inverses
virtual bool parameterTextToValue(VstInt32 index, const char *text, float &value);
virtual bool canConvertParameterTextToValue(VstInt32 index);
virtual VstInt32 canDo(char *text);
private:
char _programName[kVstMaxProgNameLen + 1];
std::set< std::string > _canDo;

uint32_t fpdL;
uint32_t fpdR;
//default stuff

double lastASampleL;
double lastSlewL;
double iirSampleAL;
double iirSampleBL;
double iirSampleCL;
double iirSampleDL;
double iirSampleEL;
double iirSampleFL;
double iirSampleGL;
double iirSampleHL;
double iirSampleIL;
double iirSampleJL;
double OddL[257];
double EvenL[257]; //amp

double bL[90];
double lastCabSampleL;
double smoothCabAL;
double smoothCabBL; //cab


double lastASampleR;
double lastSlewR;
double iirSampleAR;
double iirSampleBR;
double iirSampleCR;
double iirSampleDR;
double iirSampleER;
double OddAR;
double OddBR;
double OddCR;
double OddDR;
double OddER;
double EvenAR;
double EvenBR;
double EvenCR;
double EvenDR;
double EvenER;

double bR[90];
double lastCabSampleR;
double smoothCabAR;
double smoothCabBR; //cab


double lastRefL[10];
double lastRefR[10];
int cycle; //undersampling

bool flip;
int count; //amp

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

double lastSampleR;
double intermediateR[16];
bool wasPosClipR;
bool wasNegClipR; //ClipOnly2

float A;
float B;
};

#endif
} // end namespace
Loading

0 comments on commit 922733a

Please sign in to comment.