diff options
author | airwindows <jinx6568@sover.net> | 2018-02-12 19:08:23 -0500 |
---|---|---|
committer | airwindows <jinx6568@sover.net> | 2018-02-12 19:08:23 -0500 |
commit | 23a80ee10cb65213fd06ce3dd053395f1ec639c3 (patch) | |
tree | fa26a06393af637833c0be05652c2264ef48894f /plugins/LinuxVST | |
parent | b5918570e489f2660b96522fc5a6db0ff7072d47 (diff) | |
download | airwindows-lv2-port-23a80ee10cb65213fd06ce3dd053395f1ec639c3.tar.gz airwindows-lv2-port-23a80ee10cb65213fd06ce3dd053395f1ec639c3.tar.bz2 airwindows-lv2-port-23a80ee10cb65213fd06ce3dd053395f1ec639c3.zip |
Introducing LinuxVST
Diffstat (limited to 'plugins/LinuxVST')
47 files changed, 4176 insertions, 0 deletions
diff --git a/plugins/LinuxVST/CMakeLists.txt b/plugins/LinuxVST/CMakeLists.txt new file mode 100755 index 0000000..c547233 --- /dev/null +++ b/plugins/LinuxVST/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.9) +project(airwindows_ports) + +set(CMAKE_CXX_STANDARD 14) +add_compile_options(-O2 -D__cdecl=) + +include(Helpers.cmake) + +add_subdirectory(include/vstsdk) +add_airwindows_plugin(Acceleration) +add_airwindows_plugin(BitShiftGain) +add_airwindows_plugin(GrooveWear) +add_airwindows_plugin(PurestConsoleBuss) +add_airwindows_plugin(PurestConsoleChannel) +add_airwindows_plugin(PurestDrive) +add_airwindows_plugin(PurestGain) +add_airwindows_plugin(TPDFDither) diff --git a/plugins/LinuxVST/Helpers.cmake b/plugins/LinuxVST/Helpers.cmake new file mode 100755 index 0000000..9f77401 --- /dev/null +++ b/plugins/LinuxVST/Helpers.cmake @@ -0,0 +1,8 @@ +function(add_airwindows_plugin name) + file(GLOB plug_src + src/${name}/*.h + src/${name}/*.cpp) + add_library(${name} MODULE ${plug_src} ${VSTSDK_SOURCES}) + target_include_directories(${name} PRIVATE ${VSTSDK_ROOT}) + set_target_properties(${name} PROPERTIES PREFIX "") +endfunction(add_airwindows_plugin)
\ No newline at end of file diff --git a/plugins/LinuxVST/LICENSE b/plugins/LinuxVST/LICENSE new file mode 100755 index 0000000..0c4fcee --- /dev/null +++ b/plugins/LinuxVST/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Chris Johnson + +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.
\ No newline at end of file diff --git a/plugins/LinuxVST/README.md b/plugins/LinuxVST/README.md new file mode 100755 index 0000000..27edb9c --- /dev/null +++ b/plugins/LinuxVST/README.md @@ -0,0 +1,69 @@ +# Airwindows open-source VST plugins for Linux + +This repository contains a CMake project that builds Airwindows plugins for +Linux. Thanks to the Patreon supporters, Chris now publishes some of his plugins +under the MIT license on his GitHub, thus making this possible. Please, consider +supporting him. More info: + +1. <https://patreon.com/airwindows> +2. <https://github.com/airwindows/airwindows> +3. <http://airwindows.com> + +This CMake project is created by Eugene Cherny, whose work with CMake and scripting +allowed for every Airwindows plugin to be conveniently ported to LinuxVST, and +allowed for Linux as a platform to be targeted from now on. Thank you, ech2! +1. <https://github.com/ech2> +2. <http://oscii.ru> + +[[Download build](https://github.com/ech2/airwindows-ports/releases)] + +## Building + +Install CMake from your package manager: + +- Debian / Ubuntu: `apt install cmake` +- Fedora / CentOS: `dnf install cmake` +- Arch / Manjaro: `pacman -S cmake` + +To build the plugins you would need to grab the VST SDK and copy it to the +`include/vstsdk` directory. You need to do it yourself, because the Steinberg’s +license doesn’t allow to distribute their SDK with licenses other than GPL. You +can get it from the following page: +<https://www.steinberg.net/en/company/developers.html>. The structure of the +`include/vsdsdk` directory should be as follows: + +``` +include/vstsdk/ +├── pluginterfaces +│ └── vst2.x +│ ├── aeffect.h +│ ├── aeffectx.h +│ └── vstfxstore.h +├── aeffeditor.h +├── audioeffect.cpp +├── audioeffect.h +├── audioeffectx.cpp +├── audioeffectx.h +├── CMakeLists.txt +└── vstplugmain.cpp +``` + +Then, navigate to the `build` directory and run `cmake .. && make`. A number of +`.so` files should appear — these are your plugins. Copy them wherever you +would like or wherever your DAW can find them. + +## Adding new plugins + +1. Create a new directory `PluginName` in the `src` dir. +2. Copy the plugin’s `.cpp` and `.h` files to it. +3. Add line `add_airwindows_plugin(PluginName)` to the root `CMakeLists.txt`. + This will create a new target `PluginName` with all the sources copied, as + well as include VST-related files. +4. Build the project. + +## What’s needed + +- [X] Check the VS / Xcode projects for some extra compilation flags and add it + to this project. +- [ ] Try to make this build cross-platform and generate Xcode and VS projects. +- [ ] Automatic builds for different platforms. diff --git a/plugins/LinuxVST/build/.gitkeep b/plugins/LinuxVST/build/.gitkeep new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/plugins/LinuxVST/build/.gitkeep diff --git a/plugins/LinuxVST/build/CMakeCache.txt b/plugins/LinuxVST/build/CMakeCache.txt new file mode 100644 index 0000000..f9e5405 --- /dev/null +++ b/plugins/LinuxVST/build/CMakeCache.txt @@ -0,0 +1,52 @@ +# This is the CMakeCache file. +# For build in directory: /Users/christopherjohnson/Desktop/LinuxVST/build +# It was generated by CMake: /usr/local/Cellar/cmake/2.8.12.2/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + +//If true, cmake will use relative paths in makefiles and projects. +CMAKE_USE_RELATIVE_PATHS:BOOL=OFF + + +######################## +# INTERNAL cache entries +######################## + +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/Users/christopherjohnson/Desktop/LinuxVST/build +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=8 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=12 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/usr/local/Cellar/cmake/2.8.12.2/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/usr/local/Cellar/cmake/2.8.12.2/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/usr/local/Cellar/cmake/2.8.12.2/bin/ctest +//Path to cache edit program executable. +CMAKE_EDIT_COMMAND:INTERNAL=/usr/local/Cellar/cmake/2.8.12.2/bin/ccmake +//Name of generator toolset. +CMAKE_GENERATOR_TOOLSET:INTERNAL= +//Start directory with the top level CMakeLists.txt file for this +// project +CMAKE_HOME_DIRECTORY:INTERNAL=/Users/christopherjohnson/Desktop/LinuxVST +//number of local generators +CMAKE_NUMBER_OF_LOCAL_GENERATORS:INTERNAL=1 +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/usr/local/Cellar/cmake/2.8.12.2/share/cmake +//ADVANCED property for variable: CMAKE_USE_RELATIVE_PATHS +CMAKE_USE_RELATIVE_PATHS-ADVANCED:INTERNAL=1 + diff --git a/plugins/LinuxVST/build/CMakeFiles/cmake.check_cache b/plugins/LinuxVST/build/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/plugins/LinuxVST/build/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/plugins/LinuxVST/src/Acceleration/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/Acceleration/.vs/Console4Channel64/v14/.suo Binary files differnew file mode 100644 index 0000000..777b846 --- /dev/null +++ b/plugins/LinuxVST/src/Acceleration/.vs/Console4Channel64/v14/.suo diff --git a/plugins/LinuxVST/src/Acceleration/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/Acceleration/.vs/VSTProject/v14/.suo Binary files differnew file mode 100644 index 0000000..734c0c5 --- /dev/null +++ b/plugins/LinuxVST/src/Acceleration/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/Acceleration/Acceleration.cpp b/plugins/LinuxVST/src/Acceleration/Acceleration.cpp new file mode 100644 index 0000000..f20c8f2 --- /dev/null +++ b/plugins/LinuxVST/src/Acceleration/Acceleration.cpp @@ -0,0 +1,139 @@ +/* ======================================== + * Acceleration - Acceleration.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __Acceleration_H +#include "Acceleration.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new Acceleration(audioMaster);} + +Acceleration::Acceleration(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + A = 0.32; + B = 1.0; + ataLastOutL = 0.0; + s1L = s2L = s3L = 0.0; + o1L = o2L = o3L = 0.0; + m1L = m2L = desL = 0.0; + ataLastOutR = 0.0; + s1R = s2R = s3R = 0.0; + o1R = o2R = o3R = 0.0; + m1R = m2R = desR = 0.0; + + fpNShapeLA = 0.0; + fpNShapeLB = 0.0; + fpNShapeRA = 0.0; + fpNShapeRB = 0.0; + fpFlip = true; + //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 +} + +Acceleration::~Acceleration() {} +VstInt32 Acceleration::getVendorVersion () {return 1000;} +void Acceleration::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void Acceleration::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 Acceleration::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + chunkData[0] = A; + chunkData[1] = B; + /* 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 Acceleration::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + float *chunkData = (float *)data; + A = pinParameter(chunkData[0]); + B = pinParameter(chunkData[1]); + /* 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 Acceleration::setParameter(VstInt32 index, float value) { + switch (index) { + case kParamA: A = value; break; + case kParamB: B = value; break; + default: throw; // unknown parameter, shouldn't happen! + } +} + +float Acceleration::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 Acceleration::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Limit", kVstMaxParamStrLen); break; + case kParamB: 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 Acceleration::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 Acceleration::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 Acceleration::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool Acceleration::getEffectName(char* name) { + vst_strncpy(name, "Acceleration", kVstMaxProductStrLen); return true; +} + +VstPlugCategory Acceleration::getPlugCategory() {return kPlugCategEffect;} + +bool Acceleration::getProductString(char* text) { + vst_strncpy (text, "airwindows Acceleration", kVstMaxProductStrLen); return true; +} + +bool Acceleration::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/Acceleration/Acceleration.h b/plugins/LinuxVST/src/Acceleration/Acceleration.h new file mode 100644 index 0000000..a152e25 --- /dev/null +++ b/plugins/LinuxVST/src/Acceleration/Acceleration.h @@ -0,0 +1,88 @@ +/* ======================================== + * Acceleration - Acceleration.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __Acceleration_H +#define __Acceleration_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kParamA = 0, + kParamB = 1, + kNumParameters = 2 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'acel'; //Change this to what the AU identity is! + +class Acceleration : + public AudioEffectX +{ +public: + Acceleration(audioMasterCallback audioMaster); + ~Acceleration(); + 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; + + long double fpNShapeLA; + long double fpNShapeLB; + long double fpNShapeRA; + long double fpNShapeRB; + bool fpFlip; + //default stuff + double ataLastOutL; + double s1L; + double s2L; + double s3L; + double o1L; + double o2L; + double o3L; + double m1L; + double m2L; + double desL; + + double ataLastOutR; + double s1R; + double s2R; + double s3R; + double o1R; + double o2R; + double o3R; + double m1R; + double m2R; + double desR; + + float A; + float B; +}; + +#endif diff --git a/plugins/LinuxVST/src/Acceleration/AccelerationProc.cpp b/plugins/LinuxVST/src/Acceleration/AccelerationProc.cpp new file mode 100644 index 0000000..4785e37 --- /dev/null +++ b/plugins/LinuxVST/src/Acceleration/AccelerationProc.cpp @@ -0,0 +1,324 @@ +/* ======================================== + * Acceleration - Acceleration.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __Acceleration_H +#include "Acceleration.h" +#endif + +void Acceleration::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + double overallscale = 1.0; + overallscale /= 44100.0; + overallscale *= getSampleRate(); + float fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + double intensity = pow(A,3)*(32/overallscale); + double wet = B; + double dry = 1.0 - wet; + + double senseL; + double smoothL; + double senseR; + double smoothR; + double accumulatorSample; + double drySampleL; + double drySampleR; + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + drySampleL = inputSampleL; + drySampleR = inputSampleR; + + s3L = s2L; + s2L = s1L; + s1L = inputSampleL; + smoothL = (s3L + s2L + s1L) / 3.0; + m1L = (s1L-s2L)*((s1L-s2L)/1.3); + m2L = (s2L-s3L)*((s1L-s2L)/1.3); + senseL = fabs(m1L-m2L); + senseL = (intensity*intensity*senseL); + o3L = o2L; + o2L = o1L; + o1L = senseL; + if (o2L > senseL) senseL = o2L; + if (o3L > senseL) senseL = o3L; + //sense on the most intense + + s3R = s2R; + s2R = s1R; + s1R = inputSampleR; + smoothR = (s3R + s2R + s1R) / 3.0; + m1R = (s1R-s2R)*((s1R-s2R)/1.3); + m2R = (s2R-s3R)*((s1R-s2R)/1.3); + senseR = fabs(m1R-m2R); + senseR = (intensity*intensity*senseR); + o3R = o2R; + o2R = o1R; + o1R = senseR; + if (o2R > senseR) senseR = o2R; + if (o3R > senseR) senseR = o3R; + //sense on the most intense + + if (senseL > 1.0) senseL = 1.0; + if (senseR > 1.0) senseR = 1.0; + + inputSampleL *= (1.0-senseL); + inputSampleR *= (1.0-senseR); + + inputSampleL += (smoothL*senseL); + inputSampleR += (smoothR*senseR); + + senseL /= 2.0; + senseR /= 2.0; + + accumulatorSample = (ataLastOutL*senseL)+(inputSampleL*(1.0-senseL)); + ataLastOutL = inputSampleL; + inputSampleL = accumulatorSample; + + accumulatorSample = (ataLastOutR*senseR)+(inputSampleR*(1.0-senseR)); + ataLastOutR = inputSampleR; + inputSampleR = accumulatorSample; + + if (wet !=1.0) { + inputSampleL = (inputSampleL * wet) + (drySampleL * dry); + inputSampleR = (inputSampleR * wet) + (drySampleR * dry); + } + + //noise shaping to 32-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void Acceleration::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + double overallscale = 1.0; + overallscale /= 44100.0; + overallscale *= getSampleRate(); + double fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + double intensity = pow(A,3)*(32/overallscale); + double wet = B; + double dry = 1.0 - wet; + + double senseL; + double smoothL; + double senseR; + double smoothR; + double accumulatorSample; + double drySampleL; + double drySampleR; + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + drySampleL = inputSampleL; + drySampleR = inputSampleR; + + s3L = s2L; + s2L = s1L; + s1L = inputSampleL; + smoothL = (s3L + s2L + s1L) / 3.0; + m1L = (s1L-s2L)*((s1L-s2L)/1.3); + m2L = (s2L-s3L)*((s1L-s2L)/1.3); + senseL = fabs(m1L-m2L); + senseL = (intensity*intensity*senseL); + o3L = o2L; + o2L = o1L; + o1L = senseL; + if (o2L > senseL) senseL = o2L; + if (o3L > senseL) senseL = o3L; + //sense on the most intense + + s3R = s2R; + s2R = s1R; + s1R = inputSampleR; + smoothR = (s3R + s2R + s1R) / 3.0; + m1R = (s1R-s2R)*((s1R-s2R)/1.3); + m2R = (s2R-s3R)*((s1R-s2R)/1.3); + senseR = fabs(m1R-m2R); + senseR = (intensity*intensity*senseR); + o3R = o2R; + o2R = o1R; + o1R = senseR; + if (o2R > senseR) senseR = o2R; + if (o3R > senseR) senseR = o3R; + //sense on the most intense + + if (senseL > 1.0) senseL = 1.0; + if (senseR > 1.0) senseR = 1.0; + + inputSampleL *= (1.0-senseL); + inputSampleR *= (1.0-senseR); + + inputSampleL += (smoothL*senseL); + inputSampleR += (smoothR*senseR); + + senseL /= 2.0; + senseR /= 2.0; + + accumulatorSample = (ataLastOutL*senseL)+(inputSampleL*(1.0-senseL)); + ataLastOutL = inputSampleL; + inputSampleL = accumulatorSample; + + accumulatorSample = (ataLastOutR*senseR)+(inputSampleR*(1.0-senseR)); + ataLastOutR = inputSampleR; + inputSampleR = accumulatorSample; + + if (wet !=1.0) { + inputSampleL = (inputSampleL * wet) + (drySampleL * dry); + inputSampleR = (inputSampleR * wet) + (drySampleR * dry); + } + + //noise shaping to 64-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 64 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +}
\ No newline at end of file diff --git a/plugins/LinuxVST/src/BitShiftGain/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/BitShiftGain/.vs/Console4Channel64/v14/.suo Binary files differnew file mode 100644 index 0000000..777b846 --- /dev/null +++ b/plugins/LinuxVST/src/BitShiftGain/.vs/Console4Channel64/v14/.suo diff --git a/plugins/LinuxVST/src/BitShiftGain/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/BitShiftGain/.vs/VSTProject/v14/.suo Binary files differnew file mode 100644 index 0000000..0b76ac5 --- /dev/null +++ b/plugins/LinuxVST/src/BitShiftGain/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/BitShiftGain/BitShiftGain.cpp b/plugins/LinuxVST/src/BitShiftGain/BitShiftGain.cpp new file mode 100644 index 0000000..c89bb9f --- /dev/null +++ b/plugins/LinuxVST/src/BitShiftGain/BitShiftGain.cpp @@ -0,0 +1,117 @@ +/* ======================================== + * BitShiftGain - BitShiftGain.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __BitShiftGain_H +#include "BitShiftGain.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new BitShiftGain(audioMaster);} + +BitShiftGain::BitShiftGain(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + A = 0.5; + //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 +} + +BitShiftGain::~BitShiftGain() {} +VstInt32 BitShiftGain::getVendorVersion () {return 1000;} +void BitShiftGain::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void BitShiftGain::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 BitShiftGain::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + chunkData[0] = A; + /* 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 BitShiftGain::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + float *chunkData = (float *)data; + A = pinParameter(chunkData[0]); + /* 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 BitShiftGain::setParameter(VstInt32 index, float value) { + switch (index) { + case kParamA: A = value; break; + default: throw; // unknown parameter, shouldn't happen! + } +} + +float BitShiftGain::getParameter(VstInt32 index) { + switch (index) { + case kParamA: return A; 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 BitShiftGain::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "BitShift", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host +} + +void BitShiftGain::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + case kParamA: int2string ((VstInt32)((A * 32)-16), text, kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices +} + +void BitShiftGain::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "bits", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } +} + +VstInt32 BitShiftGain::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool BitShiftGain::getEffectName(char* name) { + vst_strncpy(name, "BitShiftGain", kVstMaxProductStrLen); return true; +} + +VstPlugCategory BitShiftGain::getPlugCategory() {return kPlugCategEffect;} + +bool BitShiftGain::getProductString(char* text) { + vst_strncpy (text, "airwindows BitShiftGain", kVstMaxProductStrLen); return true; +} + +bool BitShiftGain::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/BitShiftGain/BitShiftGain.h b/plugins/LinuxVST/src/BitShiftGain/BitShiftGain.h new file mode 100644 index 0000000..00400a2 --- /dev/null +++ b/plugins/LinuxVST/src/BitShiftGain/BitShiftGain.h @@ -0,0 +1,59 @@ +/* ======================================== + * BitShiftGain - BitShiftGain.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __BitShiftGain_H +#define __BitShiftGain_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kParamA = 0, + kNumParameters = 1 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'btsh'; //Change this to what the AU identity is! + +class BitShiftGain : + public AudioEffectX +{ +public: + BitShiftGain(audioMasterCallback audioMaster); + ~BitShiftGain(); + 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; + + + float A; +}; + +#endif diff --git a/plugins/LinuxVST/src/BitShiftGain/BitShiftGainProc.cpp b/plugins/LinuxVST/src/BitShiftGain/BitShiftGainProc.cpp new file mode 100644 index 0000000..c680ebe --- /dev/null +++ b/plugins/LinuxVST/src/BitShiftGain/BitShiftGainProc.cpp @@ -0,0 +1,126 @@ +/* ======================================== + * BitShiftGain - BitShiftGain.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __BitShiftGain_H +#include "BitShiftGain.h" +#endif + +void BitShiftGain::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + int bitshiftGain = (A * 32)-16; + double gain = 1.0; + switch (bitshiftGain) + { + case -16: gain = 0.0000152587890625; break; + case -15: gain = 0.000030517578125; break; + case -14: gain = 0.00006103515625; break; + case -13: gain = 0.0001220703125; break; + case -12: gain = 0.000244140625; break; + case -11: gain = 0.00048828125; break; + case -10: gain = 0.0009765625; break; + case -9: gain = 0.001953125; break; + case -8: gain = 0.00390625; break; + case -7: gain = 0.0078125; break; + case -6: gain = 0.015625; break; + case -5: gain = 0.03125; break; + case -4: gain = 0.0625; break; + case -3: gain = 0.125; break; + case -2: gain = 0.25; break; + case -1: gain = 0.5; break; + case 0: gain = 1.0; break; + case 1: gain = 2.0; break; + case 2: gain = 4.0; break; + case 3: gain = 8.0; break; + case 4: gain = 16.0; break; + case 5: gain = 32.0; break; + case 6: gain = 64.0; break; + case 7: gain = 128.0; break; + case 8: gain = 256.0; break; + case 9: gain = 512.0; break; + case 10: gain = 1024.0; break; + case 11: gain = 2048.0; break; + case 12: gain = 4096.0; break; + case 13: gain = 8192.0; break; + case 14: gain = 16384.0; break; + case 15: gain = 32768.0; break; + case 16: gain = 65536.0; break; + } + //we are directly punching in the gain values rather than calculating them + + while (--sampleFrames >= 0) + { + *out1 = *in1 * gain; + *out2 = *in2 * gain; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void BitShiftGain::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + int bitshiftGain = (A * 32)-16; + double gain = 1.0; + switch (bitshiftGain) + { + case -16: gain = 0.0000152587890625; break; + case -15: gain = 0.000030517578125; break; + case -14: gain = 0.00006103515625; break; + case -13: gain = 0.0001220703125; break; + case -12: gain = 0.000244140625; break; + case -11: gain = 0.00048828125; break; + case -10: gain = 0.0009765625; break; + case -9: gain = 0.001953125; break; + case -8: gain = 0.00390625; break; + case -7: gain = 0.0078125; break; + case -6: gain = 0.015625; break; + case -5: gain = 0.03125; break; + case -4: gain = 0.0625; break; + case -3: gain = 0.125; break; + case -2: gain = 0.25; break; + case -1: gain = 0.5; break; + case 0: gain = 1.0; break; + case 1: gain = 2.0; break; + case 2: gain = 4.0; break; + case 3: gain = 8.0; break; + case 4: gain = 16.0; break; + case 5: gain = 32.0; break; + case 6: gain = 64.0; break; + case 7: gain = 128.0; break; + case 8: gain = 256.0; break; + case 9: gain = 512.0; break; + case 10: gain = 1024.0; break; + case 11: gain = 2048.0; break; + case 12: gain = 4096.0; break; + case 13: gain = 8192.0; break; + case 14: gain = 16384.0; break; + case 15: gain = 32768.0; break; + case 16: gain = 65536.0; break; + } + //we are directly punching in the gain values rather than calculating them + + while (--sampleFrames >= 0) + { + *out1 = *in1 * gain; + *out2 = *in2 * gain; + + *in1++; + *in2++; + *out1++; + *out2++; + } +}
\ No newline at end of file diff --git a/plugins/LinuxVST/src/GrooveWear/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/GrooveWear/.vs/Console4Channel64/v14/.suo Binary files differnew file mode 100644 index 0000000..777b846 --- /dev/null +++ b/plugins/LinuxVST/src/GrooveWear/.vs/Console4Channel64/v14/.suo diff --git a/plugins/LinuxVST/src/GrooveWear/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/GrooveWear/.vs/VSTProject/v14/.suo Binary files differnew file mode 100644 index 0000000..76a8251 --- /dev/null +++ b/plugins/LinuxVST/src/GrooveWear/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/GrooveWear/GrooveWear.cpp b/plugins/LinuxVST/src/GrooveWear/GrooveWear.cpp new file mode 100644 index 0000000..e553daa --- /dev/null +++ b/plugins/LinuxVST/src/GrooveWear/GrooveWear.cpp @@ -0,0 +1,152 @@ +/* ======================================== + * GrooveWear - GrooveWear.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __GrooveWear_H +#include "GrooveWear.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new GrooveWear(audioMaster);} + +GrooveWear::GrooveWear(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + A = 0.064; + B = 1.0; + + for(int count = 0; count < 21; count++) { + aMidL[count] = 0.0; + bMidL[count] = 0.0; + cMidL[count] = 0.0; + dMidL[count] = 0.0; + aMidR[count] = 0.0; + bMidR[count] = 0.0; + cMidR[count] = 0.0; + dMidR[count] = 0.0; + fMid[count] = 0.0; + } + aMidPrevL = 0.0; + bMidPrevL = 0.0; + cMidPrevL = 0.0; + dMidPrevL = 0.0; + + aMidPrevR = 0.0; + bMidPrevR = 0.0; + cMidPrevR = 0.0; + dMidPrevR = 0.0; + + fpNShapeLA = 0.0; + fpNShapeLB = 0.0; + fpNShapeRA = 0.0; + fpNShapeRB = 0.0; + fpFlip = true; + //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 +} + +GrooveWear::~GrooveWear() {} +VstInt32 GrooveWear::getVendorVersion () {return 1000;} +void GrooveWear::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void GrooveWear::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 GrooveWear::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + chunkData[0] = A; + chunkData[1] = B; + /* 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 GrooveWear::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + float *chunkData = (float *)data; + A = pinParameter(chunkData[0]); + B = pinParameter(chunkData[1]); + /* 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 GrooveWear::setParameter(VstInt32 index, float value) { + switch (index) { + case kParamA: A = value; break; + case kParamB: B = value; break; + default: throw; // unknown parameter, shouldn't happen! + } +} + +float GrooveWear::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 GrooveWear::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Wear", kVstMaxParamStrLen); break; + case kParamB: 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 GrooveWear::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 GrooveWear::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 GrooveWear::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool GrooveWear::getEffectName(char* name) { + vst_strncpy(name, "GrooveWear", kVstMaxProductStrLen); return true; +} + +VstPlugCategory GrooveWear::getPlugCategory() {return kPlugCategEffect;} + +bool GrooveWear::getProductString(char* text) { + vst_strncpy (text, "airwindows GrooveWear", kVstMaxProductStrLen); return true; +} + +bool GrooveWear::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/GrooveWear/GrooveWear.h b/plugins/LinuxVST/src/GrooveWear/GrooveWear.h new file mode 100644 index 0000000..7b933c2 --- /dev/null +++ b/plugins/LinuxVST/src/GrooveWear/GrooveWear.h @@ -0,0 +1,87 @@ +/* ======================================== + * GrooveWear - GrooveWear.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __GrooveWear_H +#define __GrooveWear_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kParamA = 0, + kParamB = 1, + kNumParameters = 2 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'grvw'; //Change this to what the AU identity is! + +class GrooveWear : + public AudioEffectX +{ +public: + GrooveWear(audioMasterCallback audioMaster); + ~GrooveWear(); + 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; + + long double fpNShapeLA; + long double fpNShapeLB; + long double fpNShapeRA; + long double fpNShapeRB; + bool fpFlip; + //default stuff + + double aMidL[21]; + double aMidPrevL; + double bMidL[21]; + double bMidPrevL; + double cMidL[21]; + double cMidPrevL; + double dMidL[21]; + double dMidPrevL; + + double aMidR[21]; + double aMidPrevR; + double bMidR[21]; + double bMidPrevR; + double cMidR[21]; + double cMidPrevR; + double dMidR[21]; + double dMidPrevR; + + double fMid[21]; + + float A; + float B; +}; + +#endif diff --git a/plugins/LinuxVST/src/GrooveWear/GrooveWearProc.cpp b/plugins/LinuxVST/src/GrooveWear/GrooveWearProc.cpp new file mode 100644 index 0000000..a22f6df --- /dev/null +++ b/plugins/LinuxVST/src/GrooveWear/GrooveWearProc.cpp @@ -0,0 +1,920 @@ +/* ======================================== + * GrooveWear - GrooveWear.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __GrooveWear_H +#include "GrooveWear.h" +#endif + +void GrooveWear::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + float fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + double overallscale = (pow(A,2)*19.0)+1.0; + double gain = overallscale; + //mid groove wear + if (gain > 1.0) {fMid[0] = 1.0; gain -= 1.0;} else {fMid[0] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[1] = 1.0; gain -= 1.0;} else {fMid[1] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[2] = 1.0; gain -= 1.0;} else {fMid[2] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[3] = 1.0; gain -= 1.0;} else {fMid[3] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[4] = 1.0; gain -= 1.0;} else {fMid[4] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[5] = 1.0; gain -= 1.0;} else {fMid[5] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[6] = 1.0; gain -= 1.0;} else {fMid[6] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[7] = 1.0; gain -= 1.0;} else {fMid[7] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[8] = 1.0; gain -= 1.0;} else {fMid[8] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[9] = 1.0; gain -= 1.0;} else {fMid[9] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[10] = 1.0; gain -= 1.0;} else {fMid[10] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[11] = 1.0; gain -= 1.0;} else {fMid[11] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[12] = 1.0; gain -= 1.0;} else {fMid[12] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[13] = 1.0; gain -= 1.0;} else {fMid[13] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[14] = 1.0; gain -= 1.0;} else {fMid[14] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[15] = 1.0; gain -= 1.0;} else {fMid[15] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[16] = 1.0; gain -= 1.0;} else {fMid[16] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[17] = 1.0; gain -= 1.0;} else {fMid[17] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[18] = 1.0; gain -= 1.0;} else {fMid[18] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[19] = 1.0; gain -= 1.0;} else {fMid[19] = gain; gain = 0.0;} + //there, now we have a neat little moving average with remainders, in stereo + + if (overallscale < 1.0) overallscale = 1.0; + fMid[0] /= overallscale; + fMid[1] /= overallscale; + fMid[2] /= overallscale; + fMid[3] /= overallscale; + fMid[4] /= overallscale; + fMid[5] /= overallscale; + fMid[6] /= overallscale; + fMid[7] /= overallscale; + fMid[8] /= overallscale; + fMid[9] /= overallscale; + fMid[10] /= overallscale; + fMid[11] /= overallscale; + fMid[12] /= overallscale; + fMid[13] /= overallscale; + fMid[14] /= overallscale; + fMid[15] /= overallscale; + fMid[16] /= overallscale; + fMid[17] /= overallscale; + fMid[18] /= overallscale; + fMid[19] /= overallscale; + //and now it's neatly scaled, too + + double accumulatorSampleL; + double correctionL; + double accumulatorSampleR; + double correctionR; + + + double aWet = 1.0; + double bWet = 1.0; + double cWet = 1.0; + double dWet = B*4.0; + //four-stage wet/dry control using progressive stages that bypass when not engaged + if (dWet < 1.0) {aWet = dWet; bWet = 0.0; cWet = 0.0; dWet = 0.0;} + else if (dWet < 2.0) {bWet = dWet - 1.0; cWet = 0.0; dWet = 0.0;} + else if (dWet < 3.0) {cWet = dWet - 2.0; dWet = 0.0;} + else {dWet -= 3.0;} + //this is one way to make a little set of dry/wet stages that are successively added to the + //output as the control is turned up. Each one independently goes from 0-1 and stays at 1 + //beyond that point: this is a way to progressively add a 'black box' sound processing + //which lets you fall through to simpler processing at lower settings. + + //now we set them up so each full intensity one is blended evenly with dry for each stage. + //That's because the GrooveWear algorithm works best combined with dry. + aWet *= 0.5; + bWet *= 0.5; + cWet *= 0.5; + dWet *= 0.5; + //if you are using a more typical algorithm (like a sin() or something) you won't use this part + + double aDry = 1.0 - aWet; + double bDry = 1.0 - bWet; + double cDry = 1.0 - cWet; + double dDry = 1.0 - dWet; + + double drySampleL; + double drySampleR; + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + drySampleL = inputSampleL; + drySampleR = inputSampleR; + + if (aWet > 0.0) { + aMidL[19] = aMidL[18]; aMidL[18] = aMidL[17]; aMidL[17] = aMidL[16]; aMidL[16] = aMidL[15]; + aMidL[15] = aMidL[14]; aMidL[14] = aMidL[13]; aMidL[13] = aMidL[12]; aMidL[12] = aMidL[11]; + aMidL[11] = aMidL[10]; aMidL[10] = aMidL[9]; + aMidL[9] = aMidL[8]; aMidL[8] = aMidL[7]; aMidL[7] = aMidL[6]; aMidL[6] = aMidL[5]; + aMidL[5] = aMidL[4]; aMidL[4] = aMidL[3]; aMidL[3] = aMidL[2]; aMidL[2] = aMidL[1]; + aMidL[1] = aMidL[0]; aMidL[0] = accumulatorSampleL = (inputSampleL-aMidPrevL); + //this is different from Aura because that is accumulating rates of change OF the rate of change + //this is just averaging slews directly, and we have two stages of it. + + accumulatorSampleL *= fMid[0]; + accumulatorSampleL += (aMidL[1] * fMid[1]); + accumulatorSampleL += (aMidL[2] * fMid[2]); + accumulatorSampleL += (aMidL[3] * fMid[3]); + accumulatorSampleL += (aMidL[4] * fMid[4]); + accumulatorSampleL += (aMidL[5] * fMid[5]); + accumulatorSampleL += (aMidL[6] * fMid[6]); + accumulatorSampleL += (aMidL[7] * fMid[7]); + accumulatorSampleL += (aMidL[8] * fMid[8]); + accumulatorSampleL += (aMidL[9] * fMid[9]); + accumulatorSampleL += (aMidL[10] * fMid[10]); + accumulatorSampleL += (aMidL[11] * fMid[11]); + accumulatorSampleL += (aMidL[12] * fMid[12]); + accumulatorSampleL += (aMidL[13] * fMid[13]); + accumulatorSampleL += (aMidL[14] * fMid[14]); + accumulatorSampleL += (aMidL[15] * fMid[15]); + accumulatorSampleL += (aMidL[16] * fMid[16]); + accumulatorSampleL += (aMidL[17] * fMid[17]); + accumulatorSampleL += (aMidL[18] * fMid[18]); + accumulatorSampleL += (aMidL[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionL = (inputSampleL-aMidPrevL) - accumulatorSampleL; + aMidPrevL = inputSampleL; + inputSampleL -= correctionL; + inputSampleL = (inputSampleL * aWet) + (drySampleL * aDry); + drySampleL = inputSampleL; + + aMidR[19] = aMidR[18]; aMidR[18] = aMidR[17]; aMidR[17] = aMidR[16]; aMidR[16] = aMidR[15]; + aMidR[15] = aMidR[14]; aMidR[14] = aMidR[13]; aMidR[13] = aMidR[12]; aMidR[12] = aMidR[11]; + aMidR[11] = aMidR[10]; aMidR[10] = aMidR[9]; + aMidR[9] = aMidR[8]; aMidR[8] = aMidR[7]; aMidR[7] = aMidR[6]; aMidR[6] = aMidR[5]; + aMidR[5] = aMidR[4]; aMidR[4] = aMidR[3]; aMidR[3] = aMidR[2]; aMidR[2] = aMidR[1]; + aMidR[1] = aMidR[0]; aMidR[0] = accumulatorSampleR = (inputSampleR-aMidPrevR); + //this is different from Aura because that is accumulating rates of change OF the rate of change + //this is just averaging slews directly, and we have two stages of it. + + accumulatorSampleR *= fMid[0]; + accumulatorSampleR += (aMidR[1] * fMid[1]); + accumulatorSampleR += (aMidR[2] * fMid[2]); + accumulatorSampleR += (aMidR[3] * fMid[3]); + accumulatorSampleR += (aMidR[4] * fMid[4]); + accumulatorSampleR += (aMidR[5] * fMid[5]); + accumulatorSampleR += (aMidR[6] * fMid[6]); + accumulatorSampleR += (aMidR[7] * fMid[7]); + accumulatorSampleR += (aMidR[8] * fMid[8]); + accumulatorSampleR += (aMidR[9] * fMid[9]); + accumulatorSampleR += (aMidR[10] * fMid[10]); + accumulatorSampleR += (aMidR[11] * fMid[11]); + accumulatorSampleR += (aMidR[12] * fMid[12]); + accumulatorSampleR += (aMidR[13] * fMid[13]); + accumulatorSampleR += (aMidR[14] * fMid[14]); + accumulatorSampleR += (aMidR[15] * fMid[15]); + accumulatorSampleR += (aMidR[16] * fMid[16]); + accumulatorSampleR += (aMidR[17] * fMid[17]); + accumulatorSampleR += (aMidR[18] * fMid[18]); + accumulatorSampleR += (aMidR[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionR = (inputSampleR-aMidPrevR) - accumulatorSampleR; + aMidPrevR = inputSampleR; + inputSampleR -= correctionR; + inputSampleR = (inputSampleR * aWet) + (drySampleR * aDry); + drySampleR = inputSampleR; + } + + if (bWet > 0.0) { + bMidL[19] = bMidL[18]; bMidL[18] = bMidL[17]; bMidL[17] = bMidL[16]; bMidL[16] = bMidL[15]; + bMidL[15] = bMidL[14]; bMidL[14] = bMidL[13]; bMidL[13] = bMidL[12]; bMidL[12] = bMidL[11]; + bMidL[11] = bMidL[10]; bMidL[10] = bMidL[9]; + bMidL[9] = bMidL[8]; bMidL[8] = bMidL[7]; bMidL[7] = bMidL[6]; bMidL[6] = bMidL[5]; + bMidL[5] = bMidL[4]; bMidL[4] = bMidL[3]; bMidL[3] = bMidL[2]; bMidL[2] = bMidL[1]; + bMidL[1] = bMidL[0]; bMidL[0] = accumulatorSampleL = (inputSampleL-bMidPrevL); + + accumulatorSampleL *= fMid[0]; + accumulatorSampleL += (bMidL[1] * fMid[1]); + accumulatorSampleL += (bMidL[2] * fMid[2]); + accumulatorSampleL += (bMidL[3] * fMid[3]); + accumulatorSampleL += (bMidL[4] * fMid[4]); + accumulatorSampleL += (bMidL[5] * fMid[5]); + accumulatorSampleL += (bMidL[6] * fMid[6]); + accumulatorSampleL += (bMidL[7] * fMid[7]); + accumulatorSampleL += (bMidL[8] * fMid[8]); + accumulatorSampleL += (bMidL[9] * fMid[9]); + accumulatorSampleL += (bMidL[10] * fMid[10]); + accumulatorSampleL += (bMidL[11] * fMid[11]); + accumulatorSampleL += (bMidL[12] * fMid[12]); + accumulatorSampleL += (bMidL[13] * fMid[13]); + accumulatorSampleL += (bMidL[14] * fMid[14]); + accumulatorSampleL += (bMidL[15] * fMid[15]); + accumulatorSampleL += (bMidL[16] * fMid[16]); + accumulatorSampleL += (bMidL[17] * fMid[17]); + accumulatorSampleL += (bMidL[18] * fMid[18]); + accumulatorSampleL += (bMidL[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionL = (inputSampleL-bMidPrevL) - accumulatorSampleL; + bMidPrevL = inputSampleL; + inputSampleL -= correctionL; + inputSampleL = (inputSampleL * bWet) + (drySampleL * bDry); + drySampleL = inputSampleL; + + bMidR[19] = bMidR[18]; bMidR[18] = bMidR[17]; bMidR[17] = bMidR[16]; bMidR[16] = bMidR[15]; + bMidR[15] = bMidR[14]; bMidR[14] = bMidR[13]; bMidR[13] = bMidR[12]; bMidR[12] = bMidR[11]; + bMidR[11] = bMidR[10]; bMidR[10] = bMidR[9]; + bMidR[9] = bMidR[8]; bMidR[8] = bMidR[7]; bMidR[7] = bMidR[6]; bMidR[6] = bMidR[5]; + bMidR[5] = bMidR[4]; bMidR[4] = bMidR[3]; bMidR[3] = bMidR[2]; bMidR[2] = bMidR[1]; + bMidR[1] = bMidR[0]; bMidR[0] = accumulatorSampleR = (inputSampleR-bMidPrevR); + + accumulatorSampleR *= fMid[0]; + accumulatorSampleR += (bMidR[1] * fMid[1]); + accumulatorSampleR += (bMidR[2] * fMid[2]); + accumulatorSampleR += (bMidR[3] * fMid[3]); + accumulatorSampleR += (bMidR[4] * fMid[4]); + accumulatorSampleR += (bMidR[5] * fMid[5]); + accumulatorSampleR += (bMidR[6] * fMid[6]); + accumulatorSampleR += (bMidR[7] * fMid[7]); + accumulatorSampleR += (bMidR[8] * fMid[8]); + accumulatorSampleR += (bMidR[9] * fMid[9]); + accumulatorSampleR += (bMidR[10] * fMid[10]); + accumulatorSampleR += (bMidR[11] * fMid[11]); + accumulatorSampleR += (bMidR[12] * fMid[12]); + accumulatorSampleR += (bMidR[13] * fMid[13]); + accumulatorSampleR += (bMidR[14] * fMid[14]); + accumulatorSampleR += (bMidR[15] * fMid[15]); + accumulatorSampleR += (bMidR[16] * fMid[16]); + accumulatorSampleR += (bMidR[17] * fMid[17]); + accumulatorSampleR += (bMidR[18] * fMid[18]); + accumulatorSampleR += (bMidR[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionR = (inputSampleR-bMidPrevR) - accumulatorSampleR; + bMidPrevR = inputSampleR; + inputSampleR -= correctionR; + inputSampleR = (inputSampleR * bWet) + (drySampleR * bDry); + drySampleR = inputSampleR; + } + + if (cWet > 0.0) { + cMidL[19] = cMidL[18]; cMidL[18] = cMidL[17]; cMidL[17] = cMidL[16]; cMidL[16] = cMidL[15]; + cMidL[15] = cMidL[14]; cMidL[14] = cMidL[13]; cMidL[13] = cMidL[12]; cMidL[12] = cMidL[11]; + cMidL[11] = cMidL[10]; cMidL[10] = cMidL[9]; + cMidL[9] = cMidL[8]; cMidL[8] = cMidL[7]; cMidL[7] = cMidL[6]; cMidL[6] = cMidL[5]; + cMidL[5] = cMidL[4]; cMidL[4] = cMidL[3]; cMidL[3] = cMidL[2]; cMidL[2] = cMidL[1]; + cMidL[1] = cMidL[0]; cMidL[0] = accumulatorSampleL = (inputSampleL-cMidPrevL); + + accumulatorSampleL *= fMid[0]; + accumulatorSampleL += (cMidL[1] * fMid[1]); + accumulatorSampleL += (cMidL[2] * fMid[2]); + accumulatorSampleL += (cMidL[3] * fMid[3]); + accumulatorSampleL += (cMidL[4] * fMid[4]); + accumulatorSampleL += (cMidL[5] * fMid[5]); + accumulatorSampleL += (cMidL[6] * fMid[6]); + accumulatorSampleL += (cMidL[7] * fMid[7]); + accumulatorSampleL += (cMidL[8] * fMid[8]); + accumulatorSampleL += (cMidL[9] * fMid[9]); + accumulatorSampleL += (cMidL[10] * fMid[10]); + accumulatorSampleL += (cMidL[11] * fMid[11]); + accumulatorSampleL += (cMidL[12] * fMid[12]); + accumulatorSampleL += (cMidL[13] * fMid[13]); + accumulatorSampleL += (cMidL[14] * fMid[14]); + accumulatorSampleL += (cMidL[15] * fMid[15]); + accumulatorSampleL += (cMidL[16] * fMid[16]); + accumulatorSampleL += (cMidL[17] * fMid[17]); + accumulatorSampleL += (cMidL[18] * fMid[18]); + accumulatorSampleL += (cMidL[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionL = (inputSampleL-cMidPrevL) - accumulatorSampleL; + cMidPrevL = inputSampleL; + inputSampleL -= correctionL; + inputSampleL = (inputSampleL * cWet) + (drySampleL * cDry); + drySampleL = inputSampleL; + + cMidR[19] = cMidR[18]; cMidR[18] = cMidR[17]; cMidR[17] = cMidR[16]; cMidR[16] = cMidR[15]; + cMidR[15] = cMidR[14]; cMidR[14] = cMidR[13]; cMidR[13] = cMidR[12]; cMidR[12] = cMidR[11]; + cMidR[11] = cMidR[10]; cMidR[10] = cMidR[9]; + cMidR[9] = cMidR[8]; cMidR[8] = cMidR[7]; cMidR[7] = cMidR[6]; cMidR[6] = cMidR[5]; + cMidR[5] = cMidR[4]; cMidR[4] = cMidR[3]; cMidR[3] = cMidR[2]; cMidR[2] = cMidR[1]; + cMidR[1] = cMidR[0]; cMidR[0] = accumulatorSampleR = (inputSampleR-cMidPrevR); + + accumulatorSampleR *= fMid[0]; + accumulatorSampleR += (cMidR[1] * fMid[1]); + accumulatorSampleR += (cMidR[2] * fMid[2]); + accumulatorSampleR += (cMidR[3] * fMid[3]); + accumulatorSampleR += (cMidR[4] * fMid[4]); + accumulatorSampleR += (cMidR[5] * fMid[5]); + accumulatorSampleR += (cMidR[6] * fMid[6]); + accumulatorSampleR += (cMidR[7] * fMid[7]); + accumulatorSampleR += (cMidR[8] * fMid[8]); + accumulatorSampleR += (cMidR[9] * fMid[9]); + accumulatorSampleR += (cMidR[10] * fMid[10]); + accumulatorSampleR += (cMidR[11] * fMid[11]); + accumulatorSampleR += (cMidR[12] * fMid[12]); + accumulatorSampleR += (cMidR[13] * fMid[13]); + accumulatorSampleR += (cMidR[14] * fMid[14]); + accumulatorSampleR += (cMidR[15] * fMid[15]); + accumulatorSampleR += (cMidR[16] * fMid[16]); + accumulatorSampleR += (cMidR[17] * fMid[17]); + accumulatorSampleR += (cMidR[18] * fMid[18]); + accumulatorSampleR += (cMidR[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionR = (inputSampleR-cMidPrevR) - accumulatorSampleR; + cMidPrevR = inputSampleR; + inputSampleR -= correctionR; + inputSampleR = (inputSampleR * cWet) + (drySampleR * cDry); + drySampleR = inputSampleR; + } + + if (dWet > 0.0) { + dMidL[19] = dMidL[18]; dMidL[18] = dMidL[17]; dMidL[17] = dMidL[16]; dMidL[16] = dMidL[15]; + dMidL[15] = dMidL[14]; dMidL[14] = dMidL[13]; dMidL[13] = dMidL[12]; dMidL[12] = dMidL[11]; + dMidL[11] = dMidL[10]; dMidL[10] = dMidL[9]; + dMidL[9] = dMidL[8]; dMidL[8] = dMidL[7]; dMidL[7] = dMidL[6]; dMidL[6] = dMidL[5]; + dMidL[5] = dMidL[4]; dMidL[4] = dMidL[3]; dMidL[3] = dMidL[2]; dMidL[2] = dMidL[1]; + dMidL[1] = dMidL[0]; dMidL[0] = accumulatorSampleL = (inputSampleL-dMidPrevL); + + accumulatorSampleL *= fMid[0]; + accumulatorSampleL += (dMidL[1] * fMid[1]); + accumulatorSampleL += (dMidL[2] * fMid[2]); + accumulatorSampleL += (dMidL[3] * fMid[3]); + accumulatorSampleL += (dMidL[4] * fMid[4]); + accumulatorSampleL += (dMidL[5] * fMid[5]); + accumulatorSampleL += (dMidL[6] * fMid[6]); + accumulatorSampleL += (dMidL[7] * fMid[7]); + accumulatorSampleL += (dMidL[8] * fMid[8]); + accumulatorSampleL += (dMidL[9] * fMid[9]); + accumulatorSampleL += (dMidL[10] * fMid[10]); + accumulatorSampleL += (dMidL[11] * fMid[11]); + accumulatorSampleL += (dMidL[12] * fMid[12]); + accumulatorSampleL += (dMidL[13] * fMid[13]); + accumulatorSampleL += (dMidL[14] * fMid[14]); + accumulatorSampleL += (dMidL[15] * fMid[15]); + accumulatorSampleL += (dMidL[16] * fMid[16]); + accumulatorSampleL += (dMidL[17] * fMid[17]); + accumulatorSampleL += (dMidL[18] * fMid[18]); + accumulatorSampleL += (dMidL[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionL = (inputSampleL-dMidPrevL) - accumulatorSampleL; + dMidPrevL = inputSampleL; + inputSampleL -= correctionL; + inputSampleL = (inputSampleL * dWet) + (drySampleL * dDry); + drySampleL = inputSampleL; + + dMidR[19] = dMidR[18]; dMidR[18] = dMidR[17]; dMidR[17] = dMidR[16]; dMidR[16] = dMidR[15]; + dMidR[15] = dMidR[14]; dMidR[14] = dMidR[13]; dMidR[13] = dMidR[12]; dMidR[12] = dMidR[11]; + dMidR[11] = dMidR[10]; dMidR[10] = dMidR[9]; + dMidR[9] = dMidR[8]; dMidR[8] = dMidR[7]; dMidR[7] = dMidR[6]; dMidR[6] = dMidR[5]; + dMidR[5] = dMidR[4]; dMidR[4] = dMidR[3]; dMidR[3] = dMidR[2]; dMidR[2] = dMidR[1]; + dMidR[1] = dMidR[0]; dMidR[0] = accumulatorSampleR = (inputSampleR-dMidPrevR); + + accumulatorSampleR *= fMid[0]; + accumulatorSampleR += (dMidR[1] * fMid[1]); + accumulatorSampleR += (dMidR[2] * fMid[2]); + accumulatorSampleR += (dMidR[3] * fMid[3]); + accumulatorSampleR += (dMidR[4] * fMid[4]); + accumulatorSampleR += (dMidR[5] * fMid[5]); + accumulatorSampleR += (dMidR[6] * fMid[6]); + accumulatorSampleR += (dMidR[7] * fMid[7]); + accumulatorSampleR += (dMidR[8] * fMid[8]); + accumulatorSampleR += (dMidR[9] * fMid[9]); + accumulatorSampleR += (dMidR[10] * fMid[10]); + accumulatorSampleR += (dMidR[11] * fMid[11]); + accumulatorSampleR += (dMidR[12] * fMid[12]); + accumulatorSampleR += (dMidR[13] * fMid[13]); + accumulatorSampleR += (dMidR[14] * fMid[14]); + accumulatorSampleR += (dMidR[15] * fMid[15]); + accumulatorSampleR += (dMidR[16] * fMid[16]); + accumulatorSampleR += (dMidR[17] * fMid[17]); + accumulatorSampleR += (dMidR[18] * fMid[18]); + accumulatorSampleR += (dMidR[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionR = (inputSampleR-dMidPrevR) - accumulatorSampleR; + dMidPrevR = inputSampleR; + inputSampleR -= correctionR; + inputSampleR = (inputSampleR * dWet) + (drySampleR * dDry); + drySampleR = inputSampleR; + } + + //noise shaping to 32-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void GrooveWear::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + double fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + double overallscale = (pow(A,2)*19.0)+1.0; + double gain = overallscale; + //mid groove wear + if (gain > 1.0) {fMid[0] = 1.0; gain -= 1.0;} else {fMid[0] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[1] = 1.0; gain -= 1.0;} else {fMid[1] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[2] = 1.0; gain -= 1.0;} else {fMid[2] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[3] = 1.0; gain -= 1.0;} else {fMid[3] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[4] = 1.0; gain -= 1.0;} else {fMid[4] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[5] = 1.0; gain -= 1.0;} else {fMid[5] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[6] = 1.0; gain -= 1.0;} else {fMid[6] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[7] = 1.0; gain -= 1.0;} else {fMid[7] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[8] = 1.0; gain -= 1.0;} else {fMid[8] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[9] = 1.0; gain -= 1.0;} else {fMid[9] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[10] = 1.0; gain -= 1.0;} else {fMid[10] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[11] = 1.0; gain -= 1.0;} else {fMid[11] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[12] = 1.0; gain -= 1.0;} else {fMid[12] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[13] = 1.0; gain -= 1.0;} else {fMid[13] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[14] = 1.0; gain -= 1.0;} else {fMid[14] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[15] = 1.0; gain -= 1.0;} else {fMid[15] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[16] = 1.0; gain -= 1.0;} else {fMid[16] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[17] = 1.0; gain -= 1.0;} else {fMid[17] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[18] = 1.0; gain -= 1.0;} else {fMid[18] = gain; gain = 0.0;} + if (gain > 1.0) {fMid[19] = 1.0; gain -= 1.0;} else {fMid[19] = gain; gain = 0.0;} + //there, now we have a neat little moving average with remainders, in stereo + + if (overallscale < 1.0) overallscale = 1.0; + fMid[0] /= overallscale; + fMid[1] /= overallscale; + fMid[2] /= overallscale; + fMid[3] /= overallscale; + fMid[4] /= overallscale; + fMid[5] /= overallscale; + fMid[6] /= overallscale; + fMid[7] /= overallscale; + fMid[8] /= overallscale; + fMid[9] /= overallscale; + fMid[10] /= overallscale; + fMid[11] /= overallscale; + fMid[12] /= overallscale; + fMid[13] /= overallscale; + fMid[14] /= overallscale; + fMid[15] /= overallscale; + fMid[16] /= overallscale; + fMid[17] /= overallscale; + fMid[18] /= overallscale; + fMid[19] /= overallscale; + //and now it's neatly scaled, too + + double accumulatorSampleL; + double correctionL; + double accumulatorSampleR; + double correctionR; + + + double aWet = 1.0; + double bWet = 1.0; + double cWet = 1.0; + double dWet = B*4.0; + //four-stage wet/dry control using progressive stages that bypass when not engaged + if (dWet < 1.0) {aWet = dWet; bWet = 0.0; cWet = 0.0; dWet = 0.0;} + else if (dWet < 2.0) {bWet = dWet - 1.0; cWet = 0.0; dWet = 0.0;} + else if (dWet < 3.0) {cWet = dWet - 2.0; dWet = 0.0;} + else {dWet -= 3.0;} + //this is one way to make a little set of dry/wet stages that are successively added to the + //output as the control is turned up. Each one independently goes from 0-1 and stays at 1 + //beyond that point: this is a way to progressively add a 'black box' sound processing + //which lets you fall through to simpler processing at lower settings. + + //now we set them up so each full intensity one is blended evenly with dry for each stage. + //That's because the GrooveWear algorithm works best combined with dry. + aWet *= 0.5; + bWet *= 0.5; + cWet *= 0.5; + dWet *= 0.5; + //if you are using a more typical algorithm (like a sin() or something) you won't use this part + + double aDry = 1.0 - aWet; + double bDry = 1.0 - bWet; + double cDry = 1.0 - cWet; + double dDry = 1.0 - dWet; + + double drySampleL; + double drySampleR; + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + drySampleL = inputSampleL; + drySampleR = inputSampleR; + + if (aWet > 0.0) { + aMidL[19] = aMidL[18]; aMidL[18] = aMidL[17]; aMidL[17] = aMidL[16]; aMidL[16] = aMidL[15]; + aMidL[15] = aMidL[14]; aMidL[14] = aMidL[13]; aMidL[13] = aMidL[12]; aMidL[12] = aMidL[11]; + aMidL[11] = aMidL[10]; aMidL[10] = aMidL[9]; + aMidL[9] = aMidL[8]; aMidL[8] = aMidL[7]; aMidL[7] = aMidL[6]; aMidL[6] = aMidL[5]; + aMidL[5] = aMidL[4]; aMidL[4] = aMidL[3]; aMidL[3] = aMidL[2]; aMidL[2] = aMidL[1]; + aMidL[1] = aMidL[0]; aMidL[0] = accumulatorSampleL = (inputSampleL-aMidPrevL); + //this is different from Aura because that is accumulating rates of change OF the rate of change + //this is just averaging slews directly, and we have two stages of it. + + accumulatorSampleL *= fMid[0]; + accumulatorSampleL += (aMidL[1] * fMid[1]); + accumulatorSampleL += (aMidL[2] * fMid[2]); + accumulatorSampleL += (aMidL[3] * fMid[3]); + accumulatorSampleL += (aMidL[4] * fMid[4]); + accumulatorSampleL += (aMidL[5] * fMid[5]); + accumulatorSampleL += (aMidL[6] * fMid[6]); + accumulatorSampleL += (aMidL[7] * fMid[7]); + accumulatorSampleL += (aMidL[8] * fMid[8]); + accumulatorSampleL += (aMidL[9] * fMid[9]); + accumulatorSampleL += (aMidL[10] * fMid[10]); + accumulatorSampleL += (aMidL[11] * fMid[11]); + accumulatorSampleL += (aMidL[12] * fMid[12]); + accumulatorSampleL += (aMidL[13] * fMid[13]); + accumulatorSampleL += (aMidL[14] * fMid[14]); + accumulatorSampleL += (aMidL[15] * fMid[15]); + accumulatorSampleL += (aMidL[16] * fMid[16]); + accumulatorSampleL += (aMidL[17] * fMid[17]); + accumulatorSampleL += (aMidL[18] * fMid[18]); + accumulatorSampleL += (aMidL[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionL = (inputSampleL-aMidPrevL) - accumulatorSampleL; + aMidPrevL = inputSampleL; + inputSampleL -= correctionL; + inputSampleL = (inputSampleL * aWet) + (drySampleL * aDry); + drySampleL = inputSampleL; + + aMidR[19] = aMidR[18]; aMidR[18] = aMidR[17]; aMidR[17] = aMidR[16]; aMidR[16] = aMidR[15]; + aMidR[15] = aMidR[14]; aMidR[14] = aMidR[13]; aMidR[13] = aMidR[12]; aMidR[12] = aMidR[11]; + aMidR[11] = aMidR[10]; aMidR[10] = aMidR[9]; + aMidR[9] = aMidR[8]; aMidR[8] = aMidR[7]; aMidR[7] = aMidR[6]; aMidR[6] = aMidR[5]; + aMidR[5] = aMidR[4]; aMidR[4] = aMidR[3]; aMidR[3] = aMidR[2]; aMidR[2] = aMidR[1]; + aMidR[1] = aMidR[0]; aMidR[0] = accumulatorSampleR = (inputSampleR-aMidPrevR); + //this is different from Aura because that is accumulating rates of change OF the rate of change + //this is just averaging slews directly, and we have two stages of it. + + accumulatorSampleR *= fMid[0]; + accumulatorSampleR += (aMidR[1] * fMid[1]); + accumulatorSampleR += (aMidR[2] * fMid[2]); + accumulatorSampleR += (aMidR[3] * fMid[3]); + accumulatorSampleR += (aMidR[4] * fMid[4]); + accumulatorSampleR += (aMidR[5] * fMid[5]); + accumulatorSampleR += (aMidR[6] * fMid[6]); + accumulatorSampleR += (aMidR[7] * fMid[7]); + accumulatorSampleR += (aMidR[8] * fMid[8]); + accumulatorSampleR += (aMidR[9] * fMid[9]); + accumulatorSampleR += (aMidR[10] * fMid[10]); + accumulatorSampleR += (aMidR[11] * fMid[11]); + accumulatorSampleR += (aMidR[12] * fMid[12]); + accumulatorSampleR += (aMidR[13] * fMid[13]); + accumulatorSampleR += (aMidR[14] * fMid[14]); + accumulatorSampleR += (aMidR[15] * fMid[15]); + accumulatorSampleR += (aMidR[16] * fMid[16]); + accumulatorSampleR += (aMidR[17] * fMid[17]); + accumulatorSampleR += (aMidR[18] * fMid[18]); + accumulatorSampleR += (aMidR[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionR = (inputSampleR-aMidPrevR) - accumulatorSampleR; + aMidPrevR = inputSampleR; + inputSampleR -= correctionR; + inputSampleR = (inputSampleR * aWet) + (drySampleR * aDry); + drySampleR = inputSampleR; + } + + if (bWet > 0.0) { + bMidL[19] = bMidL[18]; bMidL[18] = bMidL[17]; bMidL[17] = bMidL[16]; bMidL[16] = bMidL[15]; + bMidL[15] = bMidL[14]; bMidL[14] = bMidL[13]; bMidL[13] = bMidL[12]; bMidL[12] = bMidL[11]; + bMidL[11] = bMidL[10]; bMidL[10] = bMidL[9]; + bMidL[9] = bMidL[8]; bMidL[8] = bMidL[7]; bMidL[7] = bMidL[6]; bMidL[6] = bMidL[5]; + bMidL[5] = bMidL[4]; bMidL[4] = bMidL[3]; bMidL[3] = bMidL[2]; bMidL[2] = bMidL[1]; + bMidL[1] = bMidL[0]; bMidL[0] = accumulatorSampleL = (inputSampleL-bMidPrevL); + + accumulatorSampleL *= fMid[0]; + accumulatorSampleL += (bMidL[1] * fMid[1]); + accumulatorSampleL += (bMidL[2] * fMid[2]); + accumulatorSampleL += (bMidL[3] * fMid[3]); + accumulatorSampleL += (bMidL[4] * fMid[4]); + accumulatorSampleL += (bMidL[5] * fMid[5]); + accumulatorSampleL += (bMidL[6] * fMid[6]); + accumulatorSampleL += (bMidL[7] * fMid[7]); + accumulatorSampleL += (bMidL[8] * fMid[8]); + accumulatorSampleL += (bMidL[9] * fMid[9]); + accumulatorSampleL += (bMidL[10] * fMid[10]); + accumulatorSampleL += (bMidL[11] * fMid[11]); + accumulatorSampleL += (bMidL[12] * fMid[12]); + accumulatorSampleL += (bMidL[13] * fMid[13]); + accumulatorSampleL += (bMidL[14] * fMid[14]); + accumulatorSampleL += (bMidL[15] * fMid[15]); + accumulatorSampleL += (bMidL[16] * fMid[16]); + accumulatorSampleL += (bMidL[17] * fMid[17]); + accumulatorSampleL += (bMidL[18] * fMid[18]); + accumulatorSampleL += (bMidL[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionL = (inputSampleL-bMidPrevL) - accumulatorSampleL; + bMidPrevL = inputSampleL; + inputSampleL -= correctionL; + inputSampleL = (inputSampleL * bWet) + (drySampleL * bDry); + drySampleL = inputSampleL; + + bMidR[19] = bMidR[18]; bMidR[18] = bMidR[17]; bMidR[17] = bMidR[16]; bMidR[16] = bMidR[15]; + bMidR[15] = bMidR[14]; bMidR[14] = bMidR[13]; bMidR[13] = bMidR[12]; bMidR[12] = bMidR[11]; + bMidR[11] = bMidR[10]; bMidR[10] = bMidR[9]; + bMidR[9] = bMidR[8]; bMidR[8] = bMidR[7]; bMidR[7] = bMidR[6]; bMidR[6] = bMidR[5]; + bMidR[5] = bMidR[4]; bMidR[4] = bMidR[3]; bMidR[3] = bMidR[2]; bMidR[2] = bMidR[1]; + bMidR[1] = bMidR[0]; bMidR[0] = accumulatorSampleR = (inputSampleR-bMidPrevR); + + accumulatorSampleR *= fMid[0]; + accumulatorSampleR += (bMidR[1] * fMid[1]); + accumulatorSampleR += (bMidR[2] * fMid[2]); + accumulatorSampleR += (bMidR[3] * fMid[3]); + accumulatorSampleR += (bMidR[4] * fMid[4]); + accumulatorSampleR += (bMidR[5] * fMid[5]); + accumulatorSampleR += (bMidR[6] * fMid[6]); + accumulatorSampleR += (bMidR[7] * fMid[7]); + accumulatorSampleR += (bMidR[8] * fMid[8]); + accumulatorSampleR += (bMidR[9] * fMid[9]); + accumulatorSampleR += (bMidR[10] * fMid[10]); + accumulatorSampleR += (bMidR[11] * fMid[11]); + accumulatorSampleR += (bMidR[12] * fMid[12]); + accumulatorSampleR += (bMidR[13] * fMid[13]); + accumulatorSampleR += (bMidR[14] * fMid[14]); + accumulatorSampleR += (bMidR[15] * fMid[15]); + accumulatorSampleR += (bMidR[16] * fMid[16]); + accumulatorSampleR += (bMidR[17] * fMid[17]); + accumulatorSampleR += (bMidR[18] * fMid[18]); + accumulatorSampleR += (bMidR[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionR = (inputSampleR-bMidPrevR) - accumulatorSampleR; + bMidPrevR = inputSampleR; + inputSampleR -= correctionR; + inputSampleR = (inputSampleR * bWet) + (drySampleR * bDry); + drySampleR = inputSampleR; + } + + if (cWet > 0.0) { + cMidL[19] = cMidL[18]; cMidL[18] = cMidL[17]; cMidL[17] = cMidL[16]; cMidL[16] = cMidL[15]; + cMidL[15] = cMidL[14]; cMidL[14] = cMidL[13]; cMidL[13] = cMidL[12]; cMidL[12] = cMidL[11]; + cMidL[11] = cMidL[10]; cMidL[10] = cMidL[9]; + cMidL[9] = cMidL[8]; cMidL[8] = cMidL[7]; cMidL[7] = cMidL[6]; cMidL[6] = cMidL[5]; + cMidL[5] = cMidL[4]; cMidL[4] = cMidL[3]; cMidL[3] = cMidL[2]; cMidL[2] = cMidL[1]; + cMidL[1] = cMidL[0]; cMidL[0] = accumulatorSampleL = (inputSampleL-cMidPrevL); + + accumulatorSampleL *= fMid[0]; + accumulatorSampleL += (cMidL[1] * fMid[1]); + accumulatorSampleL += (cMidL[2] * fMid[2]); + accumulatorSampleL += (cMidL[3] * fMid[3]); + accumulatorSampleL += (cMidL[4] * fMid[4]); + accumulatorSampleL += (cMidL[5] * fMid[5]); + accumulatorSampleL += (cMidL[6] * fMid[6]); + accumulatorSampleL += (cMidL[7] * fMid[7]); + accumulatorSampleL += (cMidL[8] * fMid[8]); + accumulatorSampleL += (cMidL[9] * fMid[9]); + accumulatorSampleL += (cMidL[10] * fMid[10]); + accumulatorSampleL += (cMidL[11] * fMid[11]); + accumulatorSampleL += (cMidL[12] * fMid[12]); + accumulatorSampleL += (cMidL[13] * fMid[13]); + accumulatorSampleL += (cMidL[14] * fMid[14]); + accumulatorSampleL += (cMidL[15] * fMid[15]); + accumulatorSampleL += (cMidL[16] * fMid[16]); + accumulatorSampleL += (cMidL[17] * fMid[17]); + accumulatorSampleL += (cMidL[18] * fMid[18]); + accumulatorSampleL += (cMidL[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionL = (inputSampleL-cMidPrevL) - accumulatorSampleL; + cMidPrevL = inputSampleL; + inputSampleL -= correctionL; + inputSampleL = (inputSampleL * cWet) + (drySampleL * cDry); + drySampleL = inputSampleL; + + cMidR[19] = cMidR[18]; cMidR[18] = cMidR[17]; cMidR[17] = cMidR[16]; cMidR[16] = cMidR[15]; + cMidR[15] = cMidR[14]; cMidR[14] = cMidR[13]; cMidR[13] = cMidR[12]; cMidR[12] = cMidR[11]; + cMidR[11] = cMidR[10]; cMidR[10] = cMidR[9]; + cMidR[9] = cMidR[8]; cMidR[8] = cMidR[7]; cMidR[7] = cMidR[6]; cMidR[6] = cMidR[5]; + cMidR[5] = cMidR[4]; cMidR[4] = cMidR[3]; cMidR[3] = cMidR[2]; cMidR[2] = cMidR[1]; + cMidR[1] = cMidR[0]; cMidR[0] = accumulatorSampleR = (inputSampleR-cMidPrevR); + + accumulatorSampleR *= fMid[0]; + accumulatorSampleR += (cMidR[1] * fMid[1]); + accumulatorSampleR += (cMidR[2] * fMid[2]); + accumulatorSampleR += (cMidR[3] * fMid[3]); + accumulatorSampleR += (cMidR[4] * fMid[4]); + accumulatorSampleR += (cMidR[5] * fMid[5]); + accumulatorSampleR += (cMidR[6] * fMid[6]); + accumulatorSampleR += (cMidR[7] * fMid[7]); + accumulatorSampleR += (cMidR[8] * fMid[8]); + accumulatorSampleR += (cMidR[9] * fMid[9]); + accumulatorSampleR += (cMidR[10] * fMid[10]); + accumulatorSampleR += (cMidR[11] * fMid[11]); + accumulatorSampleR += (cMidR[12] * fMid[12]); + accumulatorSampleR += (cMidR[13] * fMid[13]); + accumulatorSampleR += (cMidR[14] * fMid[14]); + accumulatorSampleR += (cMidR[15] * fMid[15]); + accumulatorSampleR += (cMidR[16] * fMid[16]); + accumulatorSampleR += (cMidR[17] * fMid[17]); + accumulatorSampleR += (cMidR[18] * fMid[18]); + accumulatorSampleR += (cMidR[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionR = (inputSampleR-cMidPrevR) - accumulatorSampleR; + cMidPrevR = inputSampleR; + inputSampleR -= correctionR; + inputSampleR = (inputSampleR * cWet) + (drySampleR * cDry); + drySampleR = inputSampleR; + } + + if (dWet > 0.0) { + dMidL[19] = dMidL[18]; dMidL[18] = dMidL[17]; dMidL[17] = dMidL[16]; dMidL[16] = dMidL[15]; + dMidL[15] = dMidL[14]; dMidL[14] = dMidL[13]; dMidL[13] = dMidL[12]; dMidL[12] = dMidL[11]; + dMidL[11] = dMidL[10]; dMidL[10] = dMidL[9]; + dMidL[9] = dMidL[8]; dMidL[8] = dMidL[7]; dMidL[7] = dMidL[6]; dMidL[6] = dMidL[5]; + dMidL[5] = dMidL[4]; dMidL[4] = dMidL[3]; dMidL[3] = dMidL[2]; dMidL[2] = dMidL[1]; + dMidL[1] = dMidL[0]; dMidL[0] = accumulatorSampleL = (inputSampleL-dMidPrevL); + + accumulatorSampleL *= fMid[0]; + accumulatorSampleL += (dMidL[1] * fMid[1]); + accumulatorSampleL += (dMidL[2] * fMid[2]); + accumulatorSampleL += (dMidL[3] * fMid[3]); + accumulatorSampleL += (dMidL[4] * fMid[4]); + accumulatorSampleL += (dMidL[5] * fMid[5]); + accumulatorSampleL += (dMidL[6] * fMid[6]); + accumulatorSampleL += (dMidL[7] * fMid[7]); + accumulatorSampleL += (dMidL[8] * fMid[8]); + accumulatorSampleL += (dMidL[9] * fMid[9]); + accumulatorSampleL += (dMidL[10] * fMid[10]); + accumulatorSampleL += (dMidL[11] * fMid[11]); + accumulatorSampleL += (dMidL[12] * fMid[12]); + accumulatorSampleL += (dMidL[13] * fMid[13]); + accumulatorSampleL += (dMidL[14] * fMid[14]); + accumulatorSampleL += (dMidL[15] * fMid[15]); + accumulatorSampleL += (dMidL[16] * fMid[16]); + accumulatorSampleL += (dMidL[17] * fMid[17]); + accumulatorSampleL += (dMidL[18] * fMid[18]); + accumulatorSampleL += (dMidL[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionL = (inputSampleL-dMidPrevL) - accumulatorSampleL; + dMidPrevL = inputSampleL; + inputSampleL -= correctionL; + inputSampleL = (inputSampleL * dWet) + (drySampleL * dDry); + drySampleL = inputSampleL; + + dMidR[19] = dMidR[18]; dMidR[18] = dMidR[17]; dMidR[17] = dMidR[16]; dMidR[16] = dMidR[15]; + dMidR[15] = dMidR[14]; dMidR[14] = dMidR[13]; dMidR[13] = dMidR[12]; dMidR[12] = dMidR[11]; + dMidR[11] = dMidR[10]; dMidR[10] = dMidR[9]; + dMidR[9] = dMidR[8]; dMidR[8] = dMidR[7]; dMidR[7] = dMidR[6]; dMidR[6] = dMidR[5]; + dMidR[5] = dMidR[4]; dMidR[4] = dMidR[3]; dMidR[3] = dMidR[2]; dMidR[2] = dMidR[1]; + dMidR[1] = dMidR[0]; dMidR[0] = accumulatorSampleR = (inputSampleR-dMidPrevR); + + accumulatorSampleR *= fMid[0]; + accumulatorSampleR += (dMidR[1] * fMid[1]); + accumulatorSampleR += (dMidR[2] * fMid[2]); + accumulatorSampleR += (dMidR[3] * fMid[3]); + accumulatorSampleR += (dMidR[4] * fMid[4]); + accumulatorSampleR += (dMidR[5] * fMid[5]); + accumulatorSampleR += (dMidR[6] * fMid[6]); + accumulatorSampleR += (dMidR[7] * fMid[7]); + accumulatorSampleR += (dMidR[8] * fMid[8]); + accumulatorSampleR += (dMidR[9] * fMid[9]); + accumulatorSampleR += (dMidR[10] * fMid[10]); + accumulatorSampleR += (dMidR[11] * fMid[11]); + accumulatorSampleR += (dMidR[12] * fMid[12]); + accumulatorSampleR += (dMidR[13] * fMid[13]); + accumulatorSampleR += (dMidR[14] * fMid[14]); + accumulatorSampleR += (dMidR[15] * fMid[15]); + accumulatorSampleR += (dMidR[16] * fMid[16]); + accumulatorSampleR += (dMidR[17] * fMid[17]); + accumulatorSampleR += (dMidR[18] * fMid[18]); + accumulatorSampleR += (dMidR[19] * fMid[19]); + //we are doing our repetitive calculations on a separate value + correctionR = (inputSampleR-dMidPrevR) - accumulatorSampleR; + dMidPrevR = inputSampleR; + inputSampleR -= correctionR; + inputSampleR = (inputSampleR * dWet) + (drySampleR * dDry); + drySampleR = inputSampleR; + } + + //noise shaping to 64-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 64 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +}
\ No newline at end of file diff --git a/plugins/LinuxVST/src/PurestConsoleBuss/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/PurestConsoleBuss/.vs/Console4Channel64/v14/.suo Binary files differnew file mode 100644 index 0000000..777b846 --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleBuss/.vs/Console4Channel64/v14/.suo diff --git a/plugins/LinuxVST/src/PurestConsoleBuss/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/PurestConsoleBuss/.vs/VSTProject/v14/.suo Binary files differnew file mode 100644 index 0000000..be45c22 --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleBuss/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBuss.cpp b/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBuss.cpp new file mode 100644 index 0000000..ed0b223 --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBuss.cpp @@ -0,0 +1,102 @@ +/* ======================================== + * PurestConsoleBuss - PurestConsoleBuss.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __PurestConsoleBuss_H +#include "PurestConsoleBuss.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new PurestConsoleBuss(audioMaster);} + +PurestConsoleBuss::PurestConsoleBuss(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + fpNShapeLA = 0.0; + fpNShapeLB = 0.0; + fpNShapeRA = 0.0; + fpNShapeRB = 0.0; + fpFlip = true; + //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 +} + +PurestConsoleBuss::~PurestConsoleBuss() {} +VstInt32 PurestConsoleBuss::getVendorVersion () {return 1000;} +void PurestConsoleBuss::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void PurestConsoleBuss::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! + +VstInt32 PurestConsoleBuss::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + /* 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 PurestConsoleBuss::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + return 0; +} + +void PurestConsoleBuss::setParameter(VstInt32 index, float value) { + switch (index) { + default: throw; // unknown parameter, shouldn't happen! + } +} + +float PurestConsoleBuss::getParameter(VstInt32 index) { + switch (index) { + default: break; // unknown parameter, shouldn't happen! + } return 0.0; //we only need to update the relevant name, this is simple to manage +} + +void PurestConsoleBuss::getParameterName(VstInt32 index, char *text) { + switch (index) { + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host +} + +void PurestConsoleBuss::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices +} + +void PurestConsoleBuss::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + default: break; // unknown parameter, shouldn't happen! + } +} + +VstInt32 PurestConsoleBuss::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool PurestConsoleBuss::getEffectName(char* name) { + vst_strncpy(name, "PurestConsoleBuss", kVstMaxProductStrLen); return true; +} + +VstPlugCategory PurestConsoleBuss::getPlugCategory() {return kPlugCategEffect;} + +bool PurestConsoleBuss::getProductString(char* text) { + vst_strncpy (text, "airwindows PurestConsoleBuss", kVstMaxProductStrLen); return true; +} + +bool PurestConsoleBuss::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBuss.h b/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBuss.h new file mode 100644 index 0000000..0d237ec --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBuss.h @@ -0,0 +1,62 @@ +/* ======================================== + * PurestConsoleBuss - PurestConsoleBuss.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __PurestConsoleBuss_H +#define __PurestConsoleBuss_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kNumParameters = 0 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'pcob'; //Change this to what the AU identity is! + +class PurestConsoleBuss : + public AudioEffectX +{ +public: + PurestConsoleBuss(audioMasterCallback audioMaster); + ~PurestConsoleBuss(); + 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; + + long double fpNShapeLA; + long double fpNShapeLB; + long double fpNShapeRA; + long double fpNShapeRB; + bool fpFlip; + //default stuff +}; + +#endif diff --git a/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBussProc.cpp b/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBussProc.cpp new file mode 100644 index 0000000..c06258a --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleBuss/PurestConsoleBussProc.cpp @@ -0,0 +1,202 @@ +/* ======================================== + * PurestConsoleBuss - PurestConsoleBuss.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __PurestConsoleBuss_H +#include "PurestConsoleBuss.h" +#endif + +void PurestConsoleBuss::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + float fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + + 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; + //without this, you can get a NaN condition where it spits out DC offset at full blast! + + inputSampleL = asin(inputSampleL); + inputSampleR = asin(inputSampleR); + //amplitude aspect + + //noise shaping to 32-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void PurestConsoleBuss::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + double fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + + 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; + //without this, you can get a NaN condition where it spits out DC offset at full blast! + + inputSampleL = asin(inputSampleL); + inputSampleR = asin(inputSampleR); + //amplitude aspect + + //noise shaping to 64-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 64 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +}
\ No newline at end of file diff --git a/plugins/LinuxVST/src/PurestConsoleChannel/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/PurestConsoleChannel/.vs/Console4Channel64/v14/.suo Binary files differnew file mode 100644 index 0000000..777b846 --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleChannel/.vs/Console4Channel64/v14/.suo diff --git a/plugins/LinuxVST/src/PurestConsoleChannel/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/PurestConsoleChannel/.vs/VSTProject/v14/.suo Binary files differnew file mode 100644 index 0000000..506b762 --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleChannel/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannel.cpp b/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannel.cpp new file mode 100644 index 0000000..b9f3e04 --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannel.cpp @@ -0,0 +1,107 @@ +/* ======================================== + * PurestConsoleChannel - PurestConsoleChannel.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __PurestConsoleChannel_H +#include "PurestConsoleChannel.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new PurestConsoleChannel(audioMaster);} + +PurestConsoleChannel::PurestConsoleChannel(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + fpNShapeLA = 0.0; + fpNShapeLB = 0.0; + fpNShapeRA = 0.0; + fpNShapeRB = 0.0; + fpFlip = true; + //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 +} + +PurestConsoleChannel::~PurestConsoleChannel() {} +VstInt32 PurestConsoleChannel::getVendorVersion () {return 1000;} +void PurestConsoleChannel::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void PurestConsoleChannel::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! + +VstInt32 PurestConsoleChannel::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + /* 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 PurestConsoleChannel::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + float *chunkData = (float *)data; + /* 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 PurestConsoleChannel::setParameter(VstInt32 index, float value) { + switch (index) { + default: throw; // unknown parameter, shouldn't happen! + } +} + +float PurestConsoleChannel::getParameter(VstInt32 index) { + switch (index) { + default: break; // unknown parameter, shouldn't happen! + } return 0.0; //we only need to update the relevant name, this is simple to manage +} + +void PurestConsoleChannel::getParameterName(VstInt32 index, char *text) { + switch (index) { + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host +} + +void PurestConsoleChannel::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices +} + +void PurestConsoleChannel::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + default: break; // unknown parameter, shouldn't happen! + } +} + +VstInt32 PurestConsoleChannel::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool PurestConsoleChannel::getEffectName(char* name) { + vst_strncpy(name, "PurestConsoleChannel", kVstMaxProductStrLen); return true; +} + +VstPlugCategory PurestConsoleChannel::getPlugCategory() {return kPlugCategEffect;} + +bool PurestConsoleChannel::getProductString(char* text) { + vst_strncpy (text, "airwindows PurestConsoleChannel", kVstMaxProductStrLen); return true; +} + +bool PurestConsoleChannel::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannel.h b/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannel.h new file mode 100644 index 0000000..c0a1648 --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannel.h @@ -0,0 +1,63 @@ +/* ======================================== + * PurestConsoleChannel - PurestConsoleChannel.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __PurestConsoleChannel_H +#define __PurestConsoleChannel_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kNumParameters = 0 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'pcoc'; //Change this to what the AU identity is! + +class PurestConsoleChannel : + public AudioEffectX +{ +public: + PurestConsoleChannel(audioMasterCallback audioMaster); + ~PurestConsoleChannel(); + 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; + + long double fpNShapeLA; + long double fpNShapeLB; + long double fpNShapeRA; + long double fpNShapeRB; + bool fpFlip; + //default stuff + +}; + +#endif diff --git a/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannelProc.cpp b/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannelProc.cpp new file mode 100644 index 0000000..630cba7 --- /dev/null +++ b/plugins/LinuxVST/src/PurestConsoleChannel/PurestConsoleChannelProc.cpp @@ -0,0 +1,190 @@ +/* ======================================== + * PurestConsoleChannel - PurestConsoleChannel.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __PurestConsoleChannel_H +#include "PurestConsoleChannel.h" +#endif + +void PurestConsoleChannel::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + float fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + + inputSampleL = sin(inputSampleL); + inputSampleR = sin(inputSampleR); + //amplitude aspect + + //noise shaping to 32-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void PurestConsoleChannel::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + double fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + + inputSampleL = sin(inputSampleL); + inputSampleR = sin(inputSampleR); + //amplitude aspect + + //noise shaping to 64-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 64 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +}
\ No newline at end of file diff --git a/plugins/LinuxVST/src/PurestDrive/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/PurestDrive/.vs/Console4Channel64/v14/.suo Binary files differnew file mode 100644 index 0000000..777b846 --- /dev/null +++ b/plugins/LinuxVST/src/PurestDrive/.vs/Console4Channel64/v14/.suo diff --git a/plugins/LinuxVST/src/PurestDrive/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/PurestDrive/.vs/VSTProject/v14/.suo Binary files differnew file mode 100644 index 0000000..2c7648b --- /dev/null +++ b/plugins/LinuxVST/src/PurestDrive/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/PurestDrive/PurestDrive.cpp b/plugins/LinuxVST/src/PurestDrive/PurestDrive.cpp new file mode 100644 index 0000000..e2451fe --- /dev/null +++ b/plugins/LinuxVST/src/PurestDrive/PurestDrive.cpp @@ -0,0 +1,126 @@ +/* ======================================== + * PurestDrive - PurestDrive.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __PurestDrive_H +#include "PurestDrive.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new PurestDrive(audioMaster);} + +PurestDrive::PurestDrive(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + A = 0.0; + + previousSampleL = 0.0; + previousSampleR = 0.0; + + fpNShapeLA = 0.0; + fpNShapeLB = 0.0; + fpNShapeRA = 0.0; + fpNShapeRB = 0.0; + fpFlip = true; + //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 +} + +PurestDrive::~PurestDrive() {} +VstInt32 PurestDrive::getVendorVersion () {return 1000;} +void PurestDrive::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void PurestDrive::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 PurestDrive::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + chunkData[0] = A; + /* 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 PurestDrive::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + float *chunkData = (float *)data; + A = pinParameter(chunkData[0]); + /* 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 PurestDrive::setParameter(VstInt32 index, float value) { + switch (index) { + case kParamA: A = value; break; + default: throw; // unknown parameter, shouldn't happen! + } +} + +float PurestDrive::getParameter(VstInt32 index) { + switch (index) { + case kParamA: return A; 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 PurestDrive::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Drive", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host +} + +void PurestDrive::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + case kParamA: float2string (A, text, kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices +} + +void PurestDrive::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } +} + +VstInt32 PurestDrive::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool PurestDrive::getEffectName(char* name) { + vst_strncpy(name, "PurestDrive", kVstMaxProductStrLen); return true; +} + +VstPlugCategory PurestDrive::getPlugCategory() {return kPlugCategEffect;} + +bool PurestDrive::getProductString(char* text) { + vst_strncpy (text, "airwindows PurestDrive", kVstMaxProductStrLen); return true; +} + +bool PurestDrive::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/PurestDrive/PurestDrive.h b/plugins/LinuxVST/src/PurestDrive/PurestDrive.h new file mode 100644 index 0000000..1f5b349 --- /dev/null +++ b/plugins/LinuxVST/src/PurestDrive/PurestDrive.h @@ -0,0 +1,73 @@ +/* ======================================== + * PurestDrive - PurestDrive.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __PurestDrive_H +#define __PurestDrive_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kParamA = 0, + kNumParameters = 1 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'purd'; //Change this to what the AU identity is! + +class PurestDrive : + public AudioEffectX +{ +public: + PurestDrive(audioMasterCallback audioMaster); + ~PurestDrive(); + 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; + + long double fpNShapeLA; + long double fpNShapeLB; + long double fpNShapeRA; + long double fpNShapeRB; + bool fpFlip; + //default stuff + + double previousSampleL; + double previousSampleR; + + float A; + float B; + float C; + float D; + float E; //parameters. Always 0-1, and we scale/alter them elsewhere. + +}; + +#endif diff --git a/plugins/LinuxVST/src/PurestDrive/PurestDriveProc.cpp b/plugins/LinuxVST/src/PurestDrive/PurestDriveProc.cpp new file mode 100644 index 0000000..e453883 --- /dev/null +++ b/plugins/LinuxVST/src/PurestDrive/PurestDriveProc.cpp @@ -0,0 +1,235 @@ +/* ======================================== + * PurestDrive - PurestDrive.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __PurestDrive_H +#include "PurestDrive.h" +#endif + +void PurestDrive::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + float fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + double intensity = A; + double drySampleL; + double drySampleR; + long double inputSampleL; + long double inputSampleR; + double apply; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + drySampleL = inputSampleL; + drySampleR = inputSampleR; + + inputSampleL = sin(inputSampleL); + //basic distortion factor + apply = (fabs(previousSampleL + inputSampleL) / 2.0) * intensity; + //saturate less if previous sample was undistorted and low level, or if it was + //inverse polarity. Lets through highs and brightness more. + inputSampleL = (drySampleL * (1.0 - apply)) + (inputSampleL * apply); + //dry-wet control for intensity also has FM modulation to clean up highs + previousSampleL = sin(drySampleL); + //apply the sine while storing previous sample + + inputSampleR = sin(inputSampleR); + //basic distortion factor + apply = (fabs(previousSampleR + inputSampleR) / 2.0) * intensity; + //saturate less if previous sample was undistorted and low level, or if it was + //inverse polarity. Lets through highs and brightness more. + inputSampleR = (drySampleR * (1.0 - apply)) + (inputSampleR * apply); + //dry-wet control for intensity also has FM modulation to clean up highs + previousSampleR = sin(drySampleR); + //apply the sine while storing previous sample + + //noise shaping to 32-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void PurestDrive::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + double fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + double intensity = A; + double drySampleL; + double drySampleR; + long double inputSampleL; + long double inputSampleR; + double apply; + + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + drySampleL = inputSampleL; + drySampleR = inputSampleR; + + inputSampleL = sin(inputSampleL); + //basic distortion factor + apply = (fabs(previousSampleL + inputSampleL) / 2.0) * intensity; + //saturate less if previous sample was undistorted and low level, or if it was + //inverse polarity. Lets through highs and brightness more. + inputSampleL = (drySampleL * (1.0 - apply)) + (inputSampleL * apply); + //dry-wet control for intensity also has FM modulation to clean up highs + previousSampleL = sin(drySampleL); + //apply the sine while storing previous sample + + inputSampleR = sin(inputSampleR); + //basic distortion factor + apply = (fabs(previousSampleR + inputSampleR) / 2.0) * intensity; + //saturate less if previous sample was undistorted and low level, or if it was + //inverse polarity. Lets through highs and brightness more. + inputSampleR = (drySampleR * (1.0 - apply)) + (inputSampleR * apply); + //dry-wet control for intensity also has FM modulation to clean up highs + previousSampleR = sin(drySampleR); + //apply the sine while storing previous sample + + //noise shaping to 64-bit floating point + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } + else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 64 bit output + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +}
\ No newline at end of file diff --git a/plugins/LinuxVST/src/PurestGain/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/PurestGain/.vs/Console4Channel64/v14/.suo Binary files differnew file mode 100644 index 0000000..777b846 --- /dev/null +++ b/plugins/LinuxVST/src/PurestGain/.vs/Console4Channel64/v14/.suo diff --git a/plugins/LinuxVST/src/PurestGain/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/PurestGain/.vs/VSTProject/v14/.suo Binary files differnew file mode 100644 index 0000000..60f3507 --- /dev/null +++ b/plugins/LinuxVST/src/PurestGain/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/PurestGain/PurestGain.cpp b/plugins/LinuxVST/src/PurestGain/PurestGain.cpp new file mode 100644 index 0000000..3091a12 --- /dev/null +++ b/plugins/LinuxVST/src/PurestGain/PurestGain.cpp @@ -0,0 +1,134 @@ +/* ======================================== + * PurestGain - PurestGain.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __PurestGain_H +#include "PurestGain.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new PurestGain(audioMaster);} + +PurestGain::PurestGain(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + A = 0.5; + B = 1.0; + gainchase = -90.0; + settingchase = -90.0; + gainBchase = -90.0; + chasespeed = 350.0; + fpNShapeLA = 0.0; + fpNShapeLB = 0.0; + fpNShapeRA = 0.0; + fpNShapeRB = 0.0; + fpFlip = true; + //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 +} + +PurestGain::~PurestGain() {} +VstInt32 PurestGain::getVendorVersion () {return 1000;} +void PurestGain::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void PurestGain::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 PurestGain::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + chunkData[0] = A; + chunkData[1] = B; + /* 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 PurestGain::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + float *chunkData = (float *)data; + A = pinParameter(chunkData[0]); + B = pinParameter(chunkData[1]); + /* 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 PurestGain::setParameter(VstInt32 index, float value) { + switch (index) { + case kParamA: A = value; break; + case kParamB: B = value; break; //percent. Using this value, it'll be 0-100 everywhere + default: throw; // unknown parameter, shouldn't happen! + } +} + +float PurestGain::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 PurestGain::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Gain", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "Slow Fade", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host +} + +void PurestGain::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + case kParamA: float2string ((A*80.0)-40.0, 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 PurestGain::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "dB", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, " ", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } +} + +VstInt32 PurestGain::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool PurestGain::getEffectName(char* name) { + vst_strncpy(name, "PurestGain", kVstMaxProductStrLen); return true; +} + +VstPlugCategory PurestGain::getPlugCategory() {return kPlugCategEffect;} + +bool PurestGain::getProductString(char* text) { + vst_strncpy (text, "airwindows PurestGain", kVstMaxProductStrLen); return true; +} + +bool PurestGain::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/PurestGain/PurestGain.h b/plugins/LinuxVST/src/PurestGain/PurestGain.h new file mode 100644 index 0000000..7869425 --- /dev/null +++ b/plugins/LinuxVST/src/PurestGain/PurestGain.h @@ -0,0 +1,72 @@ +/* ======================================== + * PurestGain - PurestGain.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __PurestGain_H +#define __PurestGain_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kParamA = 0, + kParamB = 1, + kNumParameters = 2 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'purg'; //Change this to what the AU identity is! + +class PurestGain : + public AudioEffectX +{ +public: + PurestGain(audioMasterCallback audioMaster); + ~PurestGain(); + 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; + + long double fpNShapeLA; + long double fpNShapeLB; + long double fpNShapeRA; + long double fpNShapeRB; + bool fpFlip; + //default stuff + double gainchase; + double settingchase; + double gainBchase; + double chasespeed; + + float A; + float B; + +}; + +#endif diff --git a/plugins/LinuxVST/src/PurestGain/PurestGainProc.cpp b/plugins/LinuxVST/src/PurestGain/PurestGainProc.cpp new file mode 100644 index 0000000..38f2849 --- /dev/null +++ b/plugins/LinuxVST/src/PurestGain/PurestGainProc.cpp @@ -0,0 +1,324 @@ +/* ======================================== + * PurestGain - PurestGain.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __PurestGain_H +#include "PurestGain.h" +#endif + +void PurestGain::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + double overallscale = 1.0; + overallscale /= 44100.0; + overallscale *= getSampleRate(); + + double inputgain = (A * 80.0)-40.0; + if (settingchase != inputgain) { + chasespeed *= 2.0; + settingchase = inputgain; + //increment the slowness for each fader movement + //continuous alteration makes it react smoother + //sudden jump to setting, not so much + } + if (chasespeed > 2500.0) chasespeed = 2500.0; + //bail out if it's too extreme + if (gainchase < -60.0) { + gainchase = pow(10.0,inputgain/20.0); + //shouldn't even be a negative number + //this is about starting at whatever's set, when + //plugin is instantiated. + //Otherwise it's the target, in dB. + } + double targetgain; + //done with top controller + double targetBgain = B; + if (gainBchase < 0.0) gainBchase = targetBgain; + //this one is not a dB value, but straight multiplication + //done with slow fade controller + double outputgain; + + float fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + long double inputSampleL; + long double inputSampleR; + + //A is 0-1 (you can't feed other values to VST hosts, it's always 0-1 internally) + //B is 0-1 and you need to multiply it by 100 if you want to use the 'percent' + //C is 0-1 and if you can use a 0-1 value you can use it directly + //D is 0-1 and you must set global parameters in PurestGain.SetParameter() to use it as a 'popup' + //assign values here, possibly using const values as they won't change in this context + + while (--sampleFrames >= 0) + { + targetgain = pow(10.0,settingchase/20.0); + //now we have the target in our temp variable + + chasespeed *= 0.9999; + chasespeed -= 0.01; + if (chasespeed < 350.0) chasespeed = 350.0; + //we have our chase speed compensated for recent fader activity + + gainchase = (((gainchase*chasespeed)+targetgain)/(chasespeed+1.0)); + //gainchase is chasing the target, as a simple multiply gain factor + + gainBchase = (((gainBchase*4000)+targetBgain)/4001); + //gainchase is chasing the target, as a simple multiply gain factor + + outputgain = gainchase * gainBchase; + //directly multiply the dB gain by the straight multiply gain + + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + + if (1.0 == outputgain) + { + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + *out1 = *in1; + *out2 = *in2; + } else { + inputSampleL *= outputgain; + inputSampleR *= outputgain; + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + *out1 = inputSampleL; + *out2 = inputSampleR; + } + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void PurestGain::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + double overallscale = 1.0; + overallscale /= 44100.0; + overallscale *= getSampleRate(); + + double inputgain = (A * 80.0)-40.0; + if (settingchase != inputgain) { + chasespeed *= 2.0; + settingchase = inputgain; + //increment the slowness for each fader movement + //continuous alteration makes it react smoother + //sudden jump to setting, not so much + } + if (chasespeed > 2500.0) chasespeed = 2500.0; + //bail out if it's too extreme + if (gainchase < -60.0) { + gainchase = pow(10.0,inputgain/20.0); + //shouldn't even be a negative number + //this is about starting at whatever's set, when + //plugin is instantiated. + //Otherwise it's the target, in dB. + } + double targetgain; + //done with top controller + double targetBgain = B; + if (gainBchase < 0.0) gainBchase = targetBgain; + //this one is not a dB value, but straight multiplication + //done with slow fade controller + double outputgain; + + double fpTemp; //this is different from singlereplacing + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + targetgain = pow(10.0,settingchase/20.0); + //now we have the target in our temp variable + + chasespeed *= 0.9999; + chasespeed -= 0.01; + if (chasespeed < 350.0) chasespeed = 350.0; + //we have our chase speed compensated for recent fader activity + + gainchase = (((gainchase*chasespeed)+targetgain)/(chasespeed+1.0)); + //gainchase is chasing the target, as a simple multiply gain factor + + gainBchase = (((gainBchase*4000)+targetBgain)/4001); + //gainchase is chasing the target, as a simple multiply gain factor + + outputgain = gainchase * gainBchase; + //directly multiply the dB gain by the straight multiply gain + + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + + if (1.0 == outputgain) + { + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + *out1 = *in1; + *out2 = *in2; + } else { + inputSampleL *= outputgain; + inputSampleR *= outputgain; + if (fpFlip) { + fpTemp = inputSampleL; + fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLA; + fpTemp = inputSampleR; + fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRA; + } else { + fpTemp = inputSampleL; + fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew); + inputSampleL += fpNShapeLB; + fpTemp = inputSampleR; + fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew); + inputSampleR += fpNShapeRB; + } + fpFlip = !fpFlip; + //end noise shaping on 32 bit output + *out1 = inputSampleL; + *out2 = inputSampleR; + } + + *in1++; + *in2++; + *out1++; + *out2++; + } +}
\ No newline at end of file diff --git a/plugins/LinuxVST/src/TPDFDither/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/TPDFDither/.vs/Console4Channel64/v14/.suo Binary files differnew file mode 100644 index 0000000..777b846 --- /dev/null +++ b/plugins/LinuxVST/src/TPDFDither/.vs/Console4Channel64/v14/.suo diff --git a/plugins/LinuxVST/src/TPDFDither/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/TPDFDither/.vs/VSTProject/v14/.suo Binary files differnew file mode 100644 index 0000000..b623e36 --- /dev/null +++ b/plugins/LinuxVST/src/TPDFDither/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/TPDFDither/TPDFDither.cpp b/plugins/LinuxVST/src/TPDFDither/TPDFDither.cpp new file mode 100644 index 0000000..656e461 --- /dev/null +++ b/plugins/LinuxVST/src/TPDFDither/TPDFDither.cpp @@ -0,0 +1,76 @@ +/* ======================================== + * TPDFDither - TPDFDither.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __TPDFDither_H +#include "TPDFDither.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new TPDFDither(audioMaster);} + +TPDFDither::TPDFDither(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + + _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 +} + +TPDFDither::~TPDFDither() {} +VstInt32 TPDFDither::getVendorVersion () {return 1000;} +void TPDFDither::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void TPDFDither::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! + +VstInt32 TPDFDither::getChunk (void** data, bool isPreset) +{ + return kNumParameters * sizeof(float); +} + +VstInt32 TPDFDither::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + return 0; +} + +void TPDFDither::setParameter(VstInt32 index, float value) { +} + +float TPDFDither::getParameter(VstInt32 index) { + return 0.0; //we only need to update the relevant name, this is simple to manage +} + +void TPDFDither::getParameterName(VstInt32 index, char *text) { +} + +void TPDFDither::getParameterDisplay(VstInt32 index, char *text) { +} + +void TPDFDither::getParameterLabel(VstInt32 index, char *text) { +} + +VstInt32 TPDFDither::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool TPDFDither::getEffectName(char* name) { + vst_strncpy(name, "TPDFDither", kVstMaxProductStrLen); return true; +} + +VstPlugCategory TPDFDither::getPlugCategory() {return kPlugCategEffect;} + +bool TPDFDither::getProductString(char* text) { + vst_strncpy (text, "airwindows TPDFDither", kVstMaxProductStrLen); return true; +} + +bool TPDFDither::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/TPDFDither/TPDFDither.h b/plugins/LinuxVST/src/TPDFDither/TPDFDither.h new file mode 100644 index 0000000..8b17deb --- /dev/null +++ b/plugins/LinuxVST/src/TPDFDither/TPDFDither.h @@ -0,0 +1,56 @@ +/* ======================================== + * TPDFDither - TPDFDither.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __TPDFDither_H +#define __TPDFDither_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kNumParameters = 0 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'tpdf'; //Change this to what the AU identity is! + +class TPDFDither : + public AudioEffectX +{ +public: + TPDFDither(audioMasterCallback audioMaster); + ~TPDFDither(); + 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; + +}; + +#endif diff --git a/plugins/LinuxVST/src/TPDFDither/TPDFDitherProc.cpp b/plugins/LinuxVST/src/TPDFDither/TPDFDitherProc.cpp new file mode 100644 index 0000000..2dadaed --- /dev/null +++ b/plugins/LinuxVST/src/TPDFDither/TPDFDitherProc.cpp @@ -0,0 +1,174 @@ +/* ======================================== + * TPDFDither - TPDFDither.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __TPDFDither_H +#include "TPDFDither.h" +#endif + +void TPDFDither::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + + inputSampleL *= 8388608.0; + inputSampleR *= 8388608.0; + //0-1 is now one bit, now we dither + + inputSampleL -= 1.0; + inputSampleR -= 1.0; + + inputSampleL += (rand()/(double)RAND_MAX); + inputSampleR += (rand()/(double)RAND_MAX); + + inputSampleL += (rand()/(double)RAND_MAX); + inputSampleR += (rand()/(double)RAND_MAX); + + inputSampleL = floor(inputSampleL); + inputSampleR = floor(inputSampleR); + //TPDF: two 0-1 random noises + + inputSampleL /= 8388608.0; + inputSampleR /= 8388608.0; + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void TPDFDither::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + long double inputSampleL; + long double inputSampleR; + + while (--sampleFrames >= 0) + { + inputSampleL = *in1; + inputSampleR = *in2; + if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { + static int noisesource = 0; + //this declares a variable before anything else is compiled. It won't keep assigning + //it to 0 for every sample, it's as if the declaration doesn't exist in this context, + //but it lets me add this denormalization fix in a single place rather than updating + //it in three different locations. The variable isn't thread-safe but this is only + //a random seed and we can share it with whatever. + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleL = applyresidue; + } + if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { + static int noisesource = 0; + noisesource = noisesource % 1700021; noisesource++; + int residue = noisesource * noisesource; + residue = residue % 170003; residue *= residue; + residue = residue % 17011; residue *= residue; + residue = residue % 1709; residue *= residue; + residue = residue % 173; residue *= residue; + residue = residue % 17; + double applyresidue = residue; + applyresidue *= 0.00000001; + applyresidue *= 0.00000001; + inputSampleR = applyresidue; + //this denormalization routine produces a white noise at -300 dB which the noise + //shaping will interact with to produce a bipolar output, but the noise is actually + //all positive. That should stop any variables from going denormal, and the routine + //only kicks in if digital black is input. As a final touch, if you save to 24-bit + //the silence will return to being digital black again. + } + + inputSampleL *= 8388608.0; + inputSampleR *= 8388608.0; + //0-1 is now one bit, now we dither + + inputSampleL -= 1.0; + inputSampleR -= 1.0; + + inputSampleL += (rand()/(double)RAND_MAX); + inputSampleR += (rand()/(double)RAND_MAX); + + inputSampleL += (rand()/(double)RAND_MAX); + inputSampleR += (rand()/(double)RAND_MAX); + + inputSampleL = floor(inputSampleL); + inputSampleR = floor(inputSampleR); + //TPDF: two 0-1 random noises + + inputSampleL /= 8388608.0; + inputSampleR /= 8388608.0; + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +}
\ No newline at end of file |