-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
866 additions
and
360 deletions.
There are no files selected for viewing
Submodule airwindows
updated
82 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Air4 extends Air3 with controllable high frequency limiting. | ||
|
||
I'm pleased and honored to bring you Air4, which extends Air3 in a way that can help people trying my Meter plugin, and unable to get good high frequencies without bombing the slew section with red 'overslew' spikes. | ||
|
||
Back in the day, because of natural limitations of analog media and disc mastering, we didn't have extended treble, and yet there were still bright hit records. We more readily hear brightness when it's really upper-mids, but the really high stuff has special characteristics: first, it's harder to hear, and second, it conveys a spatial position in air. That position is 'CLOSE'. Within arm's reach, within a few inches, within a few millimeters… of your eardrum. | ||
|
||
This is because air is lossy, but digital isn't. Digital loses nothing, it just adds various distortions while it goes (this is why oversampling fans get excited about that: the extra distortions are rarely nice). For that reason, it's easy to make digital sounds unrealistically 'close', and this characterizes nearly all digital mixing. | ||
|
||
We see this in Airwindows Meter as massive red spikes. Because there's absolutely no flexibility or 'glue' to the highs, what happens is you get all the sonic cues of 'far too close to my ear' before you get the brightness lift you're expecting. Air3 only aggravates this: it's based on Kalman filtering, and it can boost ONLY that airy glitter, and then you've got that problem. Fine if you want that effect, but then you're also distorting. | ||
|
||
Air is the control for doing that, and Gnd means 'ground' and is literally everything else, so you can also adjust levels with it. Then there's the new controls. DarkF means 'dark filter', and it's the same as the control in Sinew (remember that? you already have it, but I saw it as a tube-fuzz sort of thing). And Ratio is basically a dry/wet for just DarkF, just Sinew (which, when it was invented, didn't get one: really novel stuff often appears as a super minimal plugin first). | ||
|
||
As seen in the video, if you adjust DarkF it produces a hard limit on the slews. It defaults to just over 0.5, which automatically stops 'red spikes' in the Slew section of Meter, no matter what treble boost you do. This'll be an aggressive sort of 'glue' for the highs, or a safety highs-restrictor if you want to not mess with the red spikes of brightness. | ||
|
||
To use it the way I use it, maybe lower the DarkF a bit, and then sneak Ratio back from full crank. What'll happen is, the spikes will gradually creep up towards their original volume, forming a spread-out cloud rather than a hard clipped line, except they'll be quieter than they were. The idea is to find the loudness you want for these bright peaks, and then work out how wide a range they're to cover. Doing this gives you brightness, but without the brittle harshness of digital treble boosting. | ||
|
||
I hope you like Air4! I'm working on ConsoleX every day now, and it'll get there. It's a LOT of work. | ||
|
||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/* ======================================== | ||
* Air4 - Air4.h | ||
* Copyright (c) airwindows, Airwindows uses the MIT license | ||
* ======================================== */ | ||
|
||
#ifndef __Air4_H | ||
#include "Air4.h" | ||
#endif | ||
#include <cmath> | ||
#include <algorithm> | ||
namespace airwinconsolidated::Air4 { | ||
|
||
AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new Air4(audioMaster);} | ||
|
||
Air4::Air4(audioMasterCallback audioMaster) : | ||
AudioEffectX(audioMaster, kNumPrograms, kNumParameters) | ||
{ | ||
A = 0.5; | ||
B = 0.5; | ||
C = 0.52; | ||
D = 0.0; | ||
|
||
for (int x = 0; x < air_total; x++) air[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 | ||
} | ||
|
||
Air4::~Air4() {} | ||
VstInt32 Air4::getVendorVersion () {return 1000;} | ||
void Air4::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} | ||
void Air4::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 Air4::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: break; // unknown parameter, shouldn't happen! | ||
} | ||
} | ||
|
||
float Air4::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 Air4::getParameterName(VstInt32 index, char *text) { | ||
switch (index) { | ||
case kParamA: vst_strncpy (text, "Air", kVstMaxParamStrLen); break; | ||
case kParamB: vst_strncpy (text, "Gnd", kVstMaxParamStrLen); break; | ||
case kParamC: vst_strncpy (text, "DarkF", kVstMaxParamStrLen); break; | ||
case kParamD: vst_strncpy (text, "Ratio", kVstMaxParamStrLen); break; | ||
default: break; // unknown parameter, shouldn't happen! | ||
} //this is our labels for displaying in the VST host | ||
} | ||
|
||
void Air4::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 Air4::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 Air4::canDo(char *text) | ||
{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know | ||
|
||
bool Air4::getEffectName(char* name) { | ||
vst_strncpy(name, "Air4", kVstMaxProductStrLen); return true; | ||
} | ||
|
||
VstPlugCategory Air4::getPlugCategory() {return kPlugCategEffect;} | ||
|
||
bool Air4::getProductString(char* text) { | ||
vst_strncpy (text, "airwindows Air4", kVstMaxProductStrLen); return true; | ||
} | ||
|
||
bool Air4::getVendorString(char* text) { | ||
vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; | ||
} | ||
bool Air4::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; } | ||
case kParamC: { auto b = string2float(text, value); return b; break; } | ||
case kParamD: { auto b = string2float(text, value); return b; break; } | ||
|
||
} | ||
return false; | ||
} | ||
bool Air4::canConvertParameterTextToValue(VstInt32 index) { | ||
switch(index) { | ||
case kParamA: return true; | ||
case kParamB: return true; | ||
case kParamC: return true; | ||
case kParamD: return true; | ||
|
||
} | ||
return false; | ||
} | ||
} // end namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* ======================================== | ||
* Air4 - Air4.h | ||
* Created 8/12/11 by SPIAdmin | ||
* Copyright (c) Airwindows, Airwindows uses the MIT license | ||
* ======================================== */ | ||
|
||
#ifndef __Air4_Air4_H | ||
#define __Air4_Air4_H | ||
|
||
#ifndef __audioeffect__ | ||
#include "../airwin_consolidated_base.h" | ||
#endif | ||
|
||
#include <set> | ||
#include <string> | ||
#include <math.h> | ||
|
||
namespace airwinconsolidated::Air4 { | ||
enum { | ||
kParamA =0, | ||
kParamB =1, | ||
kParamC =2, | ||
kParamD =3, | ||
kNumParameters = 4 | ||
}; // | ||
|
||
const int kNumPrograms = 0; | ||
const int kNumInputs = 2; | ||
const int kNumOutputs = 2; | ||
const unsigned long kUniqueId = 'aiyu'; //Change this to what the AU identity is! | ||
|
||
class Air4 : | ||
public AudioEffectX | ||
{ | ||
public: | ||
Air4(audioMasterCallback audioMaster); | ||
~Air4(); | ||
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; | ||
|
||
float A; | ||
float B; | ||
float C; | ||
float D; | ||
|
||
enum { | ||
pvAL1, | ||
pvSL1, | ||
accSL1, | ||
acc2SL1, | ||
pvAL2, | ||
pvSL2, | ||
accSL2, | ||
acc2SL2, | ||
pvAL3, | ||
pvSL3, | ||
accSL3, | ||
pvAL4, | ||
pvSL4, | ||
gndavgL, | ||
outAL, | ||
gainAL, | ||
lastSL, | ||
pvAR1, | ||
pvSR1, | ||
accSR1, | ||
acc2SR1, | ||
pvAR2, | ||
pvSR2, | ||
accSR2, | ||
acc2SR2, | ||
pvAR3, | ||
pvSR3, | ||
accSR3, | ||
pvAR4, | ||
pvSR4, | ||
gndavgR, | ||
outAR, | ||
gainAR, | ||
lastSR, | ||
air_total | ||
}; | ||
double air[air_total]; | ||
|
||
uint32_t fpdL; | ||
uint32_t fpdR; | ||
//default stuff | ||
}; | ||
|
||
#endif | ||
} // end namespace |
Oops, something went wrong.