| @@ -0,0 +1,36 @@ | |||||
| /* | |||||
| * Grain Juice Plugin | |||||
| * Copyright (C) 2014 Andre Sklenar <andre.sklenar@gmail.com>, www.juicelab.cz | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License as | |||||
| * published by the Free Software Foundation; either version 2 of | |||||
| * the License, or any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
| */ | |||||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | |||||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | |||||
| #define DISTRHO_PLUGIN_NAME "GrainJuice" | |||||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||||
| #define DISTRHO_PLUGIN_IS_SYNTH 0 | |||||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||||
| #define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||||
| #define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||||
| #define DISTRHO_PLUGIN_WANT_STATE 0 | |||||
| #define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||||
| #define DISTRHO_PLUGIN_URI "urn:distrho:GrainJuice" | |||||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||||
| @@ -0,0 +1,35 @@ | |||||
| /* (Auto-generated binary data file). */ | |||||
| #ifndef BINARY_GRAINJUICEARTWORK_HPP | |||||
| #define BINARY_GRAINJUICEARTWORK_HPP | |||||
| namespace GrainJuiceArtwork | |||||
| { | |||||
| extern const char* aboutData; | |||||
| const unsigned int aboutDataSize = 180000; | |||||
| const unsigned int aboutWidth = 300; | |||||
| const unsigned int aboutHeight = 200; | |||||
| extern const char* aboutButtonHoverData; | |||||
| const unsigned int aboutButtonHoverDataSize = 5888; | |||||
| const unsigned int aboutButtonHoverWidth = 92; | |||||
| const unsigned int aboutButtonHoverHeight = 16; | |||||
| extern const char* aboutButtonNormalData; | |||||
| const unsigned int aboutButtonNormalDataSize = 5888; | |||||
| const unsigned int aboutButtonNormalWidth = 92; | |||||
| const unsigned int aboutButtonNormalHeight = 16; | |||||
| extern const char* backgroundData; | |||||
| const unsigned int backgroundDataSize = 450000; | |||||
| const unsigned int backgroundWidth = 500; | |||||
| const unsigned int backgroundHeight = 300; | |||||
| extern const char* knobData; | |||||
| const unsigned int knobDataSize = 6084; | |||||
| const unsigned int knobWidth = 39; | |||||
| const unsigned int knobHeight = 39; | |||||
| } | |||||
| #endif // BINARY_GRAINJUICEARTWORK_HPP | |||||
| @@ -0,0 +1,520 @@ | |||||
| /* | |||||
| * Grain Juice Plugin | |||||
| * Copyright (C) 2014 Andre Sklenar <andre.sklenar@gmail.com>, www.juicelab.cz | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License as | |||||
| * published by the Free Software Foundation; either version 2 of | |||||
| * the License, or any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
| */ | |||||
| #include "GrainJuicePlugin.hpp" | |||||
| #include <iostream> | |||||
| #include <math.h> | |||||
| #include <cmath> | |||||
| START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------- | |||||
| GrainJuicePlugin::GrainJuicePlugin() | |||||
| : Plugin(paramCount, 1, 0) { // 1 program, 0 states | |||||
| // set default values | |||||
| d_setProgram(0); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| // Init | |||||
| void GrainJuicePlugin::d_initParameter(uint32_t index, Parameter& parameter) { | |||||
| switch (index) { | |||||
| case paramSize: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Size"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramScatter: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Scatter"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramGain: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Gain"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramDensity: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Density"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramLPF: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "LPF"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramHPF: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "HPF"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramSizeR: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Size"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramScatterR: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Size"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramGainR: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Size"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramDensityR: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Size"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramLPFR: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Size"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| case paramHPFR: | |||||
| parameter.hints = kParameterIsAutomable; | |||||
| parameter.name = "Size"; | |||||
| parameter.symbol = "siz"; | |||||
| parameter.unit = ""; | |||||
| parameter.ranges.def = 0.5f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| break; | |||||
| } | |||||
| } | |||||
| void GrainJuicePlugin::d_initProgramName(uint32_t index, d_string& programName) { | |||||
| if (index != 0) | |||||
| return; | |||||
| programName = "Default"; | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| // Internal data | |||||
| float GrainJuicePlugin::d_getParameterValue(uint32_t index) const { | |||||
| switch (index) { | |||||
| case paramSize: | |||||
| return size; | |||||
| case paramScatter: | |||||
| return scatter; | |||||
| case paramGain: | |||||
| return gain; | |||||
| case paramDensity: | |||||
| return density; | |||||
| case paramLPF: | |||||
| return LPF; | |||||
| case paramHPF: | |||||
| return HPF; | |||||
| case paramSizeR: | |||||
| return sizeR; | |||||
| case paramScatterR: | |||||
| return scatterR; | |||||
| case paramGainR: | |||||
| return gainR; | |||||
| case paramDensityR: | |||||
| return densityR; | |||||
| case paramLPFR: | |||||
| return LPFR; | |||||
| case paramHPFR: | |||||
| return HPFR; | |||||
| default: | |||||
| return 0.0f; | |||||
| } | |||||
| } | |||||
| void GrainJuicePlugin::d_setParameterValue(uint32_t index, float value) { | |||||
| switch (index) { | |||||
| case paramSize: | |||||
| size = value; | |||||
| break; | |||||
| case paramScatter: | |||||
| scatter = value; | |||||
| break; | |||||
| case paramGain: | |||||
| gain = value; | |||||
| break; | |||||
| case paramDensity: | |||||
| density = value; | |||||
| break; | |||||
| case paramLPF: | |||||
| LPF = value; | |||||
| break; | |||||
| case paramHPF: | |||||
| HPF = value; | |||||
| break; | |||||
| case paramSizeR: | |||||
| sizeR = value; | |||||
| break; | |||||
| case paramScatterR: | |||||
| scatterR = value; | |||||
| break; | |||||
| case paramGainR: | |||||
| gainR = value; | |||||
| break; | |||||
| case paramDensityR: | |||||
| densityR = value; | |||||
| break; | |||||
| case paramLPFR: | |||||
| LPFR = value; | |||||
| break; | |||||
| case paramHPFR: | |||||
| HPFR = value; | |||||
| break; | |||||
| } | |||||
| } | |||||
| void GrainJuicePlugin::d_setProgram(uint32_t index) { | |||||
| if (index != 0) | |||||
| return; | |||||
| /* Default parameter values */ | |||||
| size=scatter=gain=density=HPF=LPF=1.f; | |||||
| sizeR=scatterR=gainR=densityR=HPFR=LPFR=1.f; | |||||
| prevTotalGrains = 0; | |||||
| /* Default variable values */ | |||||
| srand (time(NULL)); | |||||
| nSample = new float[2]; | |||||
| prevSample = new float[2]; | |||||
| std::cout << "Starting." << std::endl; | |||||
| for (int i=0; i<1000; i++) { | |||||
| logTable[i] = expf((logf(0.999f)-logf(0.001f))*(i/1000.0f)+logf(0.999f)); | |||||
| } | |||||
| logTable[0] = 0.0f; | |||||
| concurrentFilling = 0; | |||||
| d_activate(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| // GRAINS | |||||
| GrainJuicePlugin::CGrain::CGrain(uint32_t nLength, uint32_t nDelay, float lpf, float hpf, float nGain) { | |||||
| length = nLength; | |||||
| readyForPlayback = false; | |||||
| delay = nDelay; | |||||
| playhead = 0; | |||||
| gain = nGain; | |||||
| //highPass = new HPF[2]; | |||||
| //lowPass = new LPF[2]; | |||||
| highPass[0].setSampleRate(48000); | |||||
| highPass[1].setSampleRate(48000); | |||||
| highPass[0].setReso(0.1f); | |||||
| highPass[1].setReso(0.1f); | |||||
| highPass[0].setFreq(hpf); | |||||
| highPass[1].setFreq(hpf); | |||||
| highPass[0].compute(); | |||||
| highPass[1].compute(); | |||||
| lowPass[0].setSampleRate(48000); | |||||
| lowPass[1].setSampleRate(48000); | |||||
| lowPass[0].setReso(1.4f); | |||||
| lowPass[1].setReso(1.4f); | |||||
| lowPass[0].setFreq(lpf); | |||||
| lowPass[1].setFreq(lpf); | |||||
| lowPass[0].compute(); | |||||
| lowPass[1].compute(); | |||||
| } | |||||
| bool GrainJuicePlugin::CGrain::wantsSample() { | |||||
| if (playhead<length && !readyForPlayback) { | |||||
| return true; | |||||
| } else { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| void GrainJuicePlugin::CGrain::fillSample(float *nSample) { | |||||
| //std::cout << "omnom" << std::endl; | |||||
| //std::cout << "playhead: " << playhead << std::endl; | |||||
| //std::cout << "length: " << length << std::endl; | |||||
| samples[playhead][0] = nSample[0]; | |||||
| samples[playhead][1] = nSample[1]; | |||||
| playhead++; | |||||
| if (playhead==length-5) { | |||||
| readyForPlayback = true; | |||||
| applyEnvelope(); | |||||
| playhead = length-5; | |||||
| } | |||||
| } | |||||
| float *GrainJuicePlugin::CGrain::getSample() { | |||||
| playhead--; | |||||
| float coeff = 0.5f * (1 - cosf((2.f * M_PI * playhead)/(length-1))); | |||||
| float newSample[2]; | |||||
| for (int i = 0; i < 2; i++) { | |||||
| newSample[i] = samples[playhead][i]; | |||||
| newSample[i] *= coeff*gain; | |||||
| newSample[i] = lowPass[i].process(newSample[i]); | |||||
| //newSample[i] = highPass[i].process(newSample[i]); | |||||
| } | |||||
| samples[playhead][0] = newSample[0]; | |||||
| samples[playhead][1] = newSample[1]; | |||||
| return samples[playhead]; | |||||
| } | |||||
| bool GrainJuicePlugin::CGrain::inDelay() { | |||||
| if (delay>0) { | |||||
| playhead = length; | |||||
| delay--; | |||||
| return true; | |||||
| } else { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| uint32_t GrainJuicePlugin::CGrain::getLength() { | |||||
| return length; | |||||
| } | |||||
| bool GrainJuicePlugin::CGrain::donePlaying() { | |||||
| if (playhead<1) { //TODO: fix so all the samples get played/recorded | |||||
| return true; | |||||
| } else { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| void GrainJuicePlugin::CGrain::applyEnvelope() { | |||||
| } | |||||
| void GrainJuicePlugin::CGrain::updateParams(float nDensity, float nScatter, uint32_t nSRT) { | |||||
| density = nDensity; | |||||
| scatter = nScatter; | |||||
| SRT = nSRT; | |||||
| } | |||||
| void GrainJuicePlugin::CGrain::setDelay(uint32_t nDelay) { | |||||
| delay = nDelay; | |||||
| } | |||||
| float GrainJuicePlugin::CGrain::inspectSample(uint32_t index, int channel) { | |||||
| return samples[index][channel]; | |||||
| } | |||||
| void GrainJuicePlugin::newGrain(bool first) { | |||||
| // create a new grain | |||||
| concurrentFilling = 0; | |||||
| bool create = false; | |||||
| if (first) { | |||||
| create = true; | |||||
| } else if (grains.size()+1 <= density*MAXGRAINS) { | |||||
| create = true; | |||||
| } | |||||
| if (create) { | |||||
| uint32_t newGrainSize =(int) size*d_getSampleRate()*MAXGRAINSIZE; | |||||
| newGrainSize = rand() % newGrainSize-1000; | |||||
| newGrainSize += 1000; | |||||
| uint32_t delayChance = (1000 - (rand() % (int) (density*1000.f)))/25+1; | |||||
| //std::cout << "grain fill!" << std::endl; | |||||
| //std::cout << "chance: " << delayChance << std::endl;; | |||||
| //delayChance = 2; | |||||
| for (int d=0; d<delayChance; d++) { | |||||
| if (grains.size()+1 > density*MAXGRAINS) { | |||||
| break; | |||||
| } | |||||
| int newDelayTime = rand() % (int) (MAXSCATTER*scatter*d_getSampleRate()); | |||||
| newDelayTime += 100; | |||||
| int newLPF = LPF*998; | |||||
| int random = (rand() % (int) (LPFR*1000+1))-(rand() % (int) (LPFR*500+1)); | |||||
| newLPF = limit(newLPF-random); | |||||
| int LPFLimit = newLPF; | |||||
| newLPF = logTable[newLPF]*20+100; | |||||
| if (newLPF>20000) newLPF = 20000; | |||||
| if (newLPF<100) newLPF = 100; | |||||
| int newHPF = HPF*998; | |||||
| random = (rand() % (int) (HPFR*1000+1))-(rand() % (int) (HPFR*500+1)); | |||||
| newHPF = limit(newHPF-random); | |||||
| newHPF = logTable[newHPF]*20+20; | |||||
| if (newHPF>20000) newHPF = 20000; | |||||
| newHPF *= newLPF/20000.f; | |||||
| if (newHPF<50) newHPF = 50; | |||||
| std::cout << newHPF << std::endl; | |||||
| //int newHPF = rand() % (int) (LPF); | |||||
| int newGain = rand() % (int) (1000); | |||||
| grains.push_back(new CGrain(newGrainSize, newDelayTime, newLPF, newHPF, newGain/1000.f)); | |||||
| //grains.push_back(new CGrain(newGrainSize, newDelayTime)); | |||||
| concurrentFilling++; | |||||
| } | |||||
| } | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| // Process | |||||
| void GrainJuicePlugin::d_activate() { | |||||
| } | |||||
| void GrainJuicePlugin::d_run(const float** inputs, float** outputs, uint32_t frames) { | |||||
| static int k = 0; | |||||
| for (uint32_t i = 0; i < frames; i++) { | |||||
| // RUNTIME CODE HERE | |||||
| //std::cout << "..record" << std::endl; | |||||
| //------------------------------------- | |||||
| // RECORD | |||||
| //std::cout << "total grains:" << grains.size() << std::endl; | |||||
| //std::cout << "max grains:" << density*MAXGRAINS << std::endl; | |||||
| if (grains.size() <= density*MAXGRAINS) { | |||||
| //std::cout << "not enough full grains" << std::endl; | |||||
| if (grains.size() == 0) { | |||||
| newGrain(true); | |||||
| } | |||||
| if (grains.back() -> wantsSample()) { | |||||
| nSample[0] = inputs[0][i]; | |||||
| nSample[1] = inputs[1][i]; | |||||
| for (int q=0; q<concurrentFilling; q++) { | |||||
| grains[grains.size()-1-q] -> fillSample(nSample); | |||||
| } | |||||
| } else { | |||||
| newGrain(false); | |||||
| } | |||||
| } | |||||
| //std::cout << "..playback" << std::endl; | |||||
| //------------------------------------- | |||||
| // PLAYBACK | |||||
| outputs[0][i] = 0.0f; | |||||
| outputs[1][i] = 0.0f; | |||||
| eraseIndex = 0; | |||||
| int grainsPlaying = 0; | |||||
| int l = 0; | |||||
| for (uint32_t j = 0; j < grains.size(); j++) { | |||||
| if (!grains[j]->wantsSample()) { | |||||
| grainsPlaying++; | |||||
| if (!grains[j]->inDelay()) { | |||||
| //play this sample back | |||||
| grains[j]->updateParams(density, scatter, d_getSampleRate()); | |||||
| if (grains[j]->donePlaying()) { | |||||
| // mark grains for erase | |||||
| eraseGrains[eraseIndex] = j; | |||||
| eraseIndex++; | |||||
| //grains.erase(grains.begin()+j); | |||||
| //j--; // COME ON BABY LIGHT MY FIRE | |||||
| } else { | |||||
| nSample = grains[j]->getSample(); | |||||
| outputs[0][i] += nSample[0]; | |||||
| outputs[1][i] += nSample[1]; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| for (int j=0; j<eraseIndex; j++) { | |||||
| grains.erase(grains.begin()+eraseGrains[j]); | |||||
| } | |||||
| if (grains.size() != prevTotalGrains) { | |||||
| //std::cout << "total grains: " << grainsPlaying << " conc: " << concurrentFilling << " size: " << grains.size() << std::endl; | |||||
| //std::cout << "total grains playing: " << grainsPlaying << std::endl; | |||||
| prevTotalGrains = grainsPlaying; | |||||
| } | |||||
| if (k==9) k=0; | |||||
| } | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| Plugin* createPlugin() { | |||||
| return new GrainJuicePlugin(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DISTRHO | |||||
| @@ -0,0 +1,307 @@ | |||||
| /* | |||||
| * Grain Juice Plugin | |||||
| * Copyright (C) 2014 Andre Sklenar <andre.sklenar@gmail.com>, www.juicelab.cz | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License as | |||||
| * published by the Free Software Foundation; either version 2 of | |||||
| * the License, or any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
| */ | |||||
| #ifndef GrainJUICEPLUGIN_HPP_INCLUDED | |||||
| #define GrainJUICEPLUGIN_HPP_INCLUDED | |||||
| #include "DistrhoPlugin.hpp" | |||||
| #include <cstdlib> | |||||
| #include <time.h> | |||||
| #include <vector> | |||||
| #define MAXGRAINSIZE 0.5f // in seconds | |||||
| #define MAXSCATTER 3.f // in seconds | |||||
| #define MAXGRAINS 300 // in grains | |||||
| START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------- | |||||
| class GrainJuicePlugin : public Plugin { | |||||
| public: | |||||
| enum Parameters { | |||||
| paramSize = 0, | |||||
| paramScatter, | |||||
| paramGain, | |||||
| paramDensity, | |||||
| paramLPF, | |||||
| paramHPF, | |||||
| paramSizeR, | |||||
| paramScatterR, | |||||
| paramGainR, | |||||
| paramDensityR, | |||||
| paramLPFR, | |||||
| paramHPFR, | |||||
| paramCount | |||||
| }; | |||||
| GrainJuicePlugin(); | |||||
| protected: | |||||
| // ------------------------------------------------------------------- | |||||
| // Information | |||||
| const char* d_getLabel() const noexcept override { | |||||
| return "GrainJuice"; | |||||
| } | |||||
| const char* d_getMaker() const noexcept override { | |||||
| return "Andre Sklenar"; | |||||
| } | |||||
| const char* d_getLicense() const noexcept override { | |||||
| return "GPL v2+"; | |||||
| } | |||||
| uint32_t d_getVersion() const noexcept override { | |||||
| return 0x1000; | |||||
| } | |||||
| long d_getUniqueId() const noexcept override { | |||||
| return d_cconst('G', 'r', 'n', 'J'); | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| // Init | |||||
| void d_initParameter(uint32_t index, Parameter& parameter) override; | |||||
| void d_initProgramName(uint32_t index, d_string& programName) override; | |||||
| // ------------------------------------------------------------------- | |||||
| // Internal data | |||||
| float d_getParameterValue(uint32_t index) const override; | |||||
| void d_setParameterValue(uint32_t index, float value) override; | |||||
| void d_setProgram(uint32_t index) override; | |||||
| // ------------------------------------------------------------------- | |||||
| // Process | |||||
| void d_activate() override; | |||||
| void d_run(const float** inputs, float** outputs, uint32_t frames) override; | |||||
| // ------------------------------------------------------------------- | |||||
| private: | |||||
| float size, scatter, gain, density, LPF, HPF; | |||||
| float sizeR, scatterR, gainR, densityR, LPFR, HPFR; | |||||
| float *nSample; | |||||
| float *prevSample; | |||||
| int concurrentFilling; | |||||
| int eraseIndex; | |||||
| int eraseGrains[100]; | |||||
| float logTable[1000]; | |||||
| int limit(int what) { | |||||
| if (what>1000) | |||||
| return 999; | |||||
| if (what<0) | |||||
| return 0; | |||||
| return what; | |||||
| } | |||||
| void newGrain(bool first); | |||||
| //float *nSample; | |||||
| bool isNan(float& value ) { | |||||
| if (((*(uint32_t *) &value) & 0x7fffffff) > 0x7f800000) { | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| uint32_t prevTotalGrains; | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(GrainJuicePlugin) | |||||
| class CGrain { | |||||
| public: | |||||
| CGrain(uint32_t nLength, uint32_t nDelay, float lpf, float hpf, float nGain); | |||||
| uint32_t getLength(); | |||||
| void fillSample(float *nSample); | |||||
| bool wantsSample(); | |||||
| float *getSample(); | |||||
| bool donePlaying(); | |||||
| void cleanUp(); | |||||
| bool inDelay(); | |||||
| uint32_t length; | |||||
| bool repeat(); | |||||
| void setDelay(uint32_t nDelay); | |||||
| void updateParams(float nDensity, float nScatter, uint32_t nSRT); | |||||
| float inspectSample(uint32_t index, int channel); | |||||
| private: | |||||
| void applyEnvelope(); | |||||
| float samples[(int)(48000*MAXGRAINSIZE)][2]; | |||||
| uint32_t playhead; | |||||
| bool readyForPlayback; | |||||
| uint32_t delay; | |||||
| float *emptySamples; | |||||
| float density; | |||||
| float scatter; | |||||
| float gain; | |||||
| uint32_t SRT; | |||||
| class CLPF | |||||
| { | |||||
| private: | |||||
| float r; // reso - 0.1 - 1.4 | |||||
| float f; // freq in Hz | |||||
| float a1, a2, a3, b1, b2; | |||||
| float in, in1, in2; | |||||
| float out, out1, out2; | |||||
| float c; | |||||
| float sampleRate; | |||||
| public: | |||||
| CLPF() { | |||||
| r = 1.0f; | |||||
| f = 0.0f; | |||||
| a1=a2=a3=b1=b2=0.0f; | |||||
| in=in1=in2=out=out1=out2=0.0f; | |||||
| } | |||||
| void compute() { | |||||
| c = 1.0 / tan(M_PI * f / sampleRate); | |||||
| a1 = 1.0 / (1.0 + r*c + c*c); | |||||
| a2 = 2 * a1; | |||||
| a3 = a1; | |||||
| b1 = 2.0 * (1.0 - c*c) * a1; | |||||
| b2 = (1.0 - r*c + c*c) * a1; | |||||
| } | |||||
| void setFreq(float nFreq) { | |||||
| f = nFreq; | |||||
| if (f==0) { | |||||
| f=20; | |||||
| } | |||||
| } | |||||
| void setReso(float nReso) { | |||||
| r = nReso; | |||||
| if (r==0) { | |||||
| r = 0.1f; | |||||
| } | |||||
| r = 1.0f; | |||||
| f = 0.0f; | |||||
| a1=a2=a3=b1=b2=0.0f; | |||||
| in=in1=in2=out=out1=out2=0.0f; | |||||
| } | |||||
| void setSampleRate(float nSampleRate) { | |||||
| sampleRate = nSampleRate; | |||||
| } | |||||
| float process(float sample) { | |||||
| in = sample; | |||||
| out = a1 * in + a2 * in1 + a3 * in2 - b1*out1 - b2*out2; | |||||
| in2=in1; | |||||
| in1=in; | |||||
| out2=out1; | |||||
| out1 = out; | |||||
| return out; | |||||
| } | |||||
| }; | |||||
| class CHPF | |||||
| { | |||||
| private: | |||||
| float r; // reso - 0.1 - 1.4 | |||||
| float f; // freq in Hz | |||||
| float a1, a2, a3, b1, b2; | |||||
| float in, in1, in2; | |||||
| float out, out1, out2; | |||||
| float c; | |||||
| float sampleRate; | |||||
| public: | |||||
| CHPF() { | |||||
| r = 1.0f; | |||||
| f = 0.0f; | |||||
| a1=a2=a3=b1=b2=0.0f; | |||||
| in=in1=in2=out=out1=out2=0.0f; | |||||
| } | |||||
| void compute() { | |||||
| c = tan(M_PI * f / sampleRate); | |||||
| a1 = 1.0 / (1.0 + r*c + c*c); | |||||
| a2 = -2*a1; | |||||
| a3 = a1; | |||||
| b1 = 2.0 * (c*c - 1.0) * a1; | |||||
| b2 = (1.0 - r*c + c*c) * a1; | |||||
| } | |||||
| void setFreq(float nFreq) { | |||||
| f = nFreq; | |||||
| if (f==0) { | |||||
| f=20; | |||||
| } | |||||
| } | |||||
| void setReso(float nReso) { | |||||
| r = nReso; | |||||
| if (r==0) { | |||||
| r = 0.1f; | |||||
| } | |||||
| } | |||||
| void setSampleRate(float nSampleRate) { | |||||
| sampleRate = nSampleRate; | |||||
| } | |||||
| float process(float sample) { | |||||
| //compute(); | |||||
| in = sample; | |||||
| out = a1 * in + a2 * in1 + a3 * in2 - b1*out1 - b2*out2; | |||||
| in2=in1; | |||||
| in1=in; | |||||
| out2=out1; | |||||
| out1 = out; | |||||
| return out; | |||||
| } | |||||
| }; | |||||
| CHPF highPass[2]; | |||||
| CLPF lowPass[2]; | |||||
| }; | |||||
| std::vector<CGrain*> grains; | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DISTRHO | |||||
| #endif // GrainJUICE_HPP_INCLUDED | |||||
| @@ -0,0 +1,283 @@ | |||||
| /* | |||||
| * Grain Juice Plugin | |||||
| * Copyright (C) 2014 Andre Sklenar <andre.sklenar@gmail.com>, www.juicelab.cz | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License as | |||||
| * published by the Free Software Foundation; either version 2 of | |||||
| * the License, or any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
| */ | |||||
| #include "GrainJuicePlugin.hpp" | |||||
| #include "GrainJuiceUI.hpp" | |||||
| START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------- | |||||
| GrainJuiceUI::GrainJuiceUI() | |||||
| : UI(), | |||||
| fAboutWindow(this) { | |||||
| setSize(GrainJuiceArtwork::backgroundWidth, GrainJuiceArtwork::backgroundHeight); | |||||
| // background | |||||
| fImgBackground = Image(GrainJuiceArtwork::backgroundData, GrainJuiceArtwork::backgroundWidth, GrainJuiceArtwork::backgroundHeight, GL_BGR); | |||||
| // about | |||||
| Image aboutImage(GrainJuiceArtwork::aboutData, GrainJuiceArtwork::aboutWidth, GrainJuiceArtwork::aboutHeight, GL_BGR); | |||||
| fAboutWindow.setImage(aboutImage); | |||||
| // knobs | |||||
| Image knobImage(GrainJuiceArtwork::knobData, GrainJuiceArtwork::knobWidth, GrainJuiceArtwork::knobHeight); | |||||
| #define PX 56 //position top X | |||||
| #define PY 98 //position top Y | |||||
| #define SX 70 //spacing X | |||||
| #define SY 86 //spacing Y | |||||
| // knob Size | |||||
| fKnobSize = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobSize->setId(GrainJuicePlugin::paramSize); | |||||
| fKnobSize->setAbsolutePos(PX, PY); | |||||
| fKnobSize->setRotationAngle(270); | |||||
| fKnobSize->setRange(0.0f, 1.0f); | |||||
| fKnobSize->setDefault(0.5f); | |||||
| fKnobSize->setStep(0.01f); | |||||
| fKnobSize->setCallback(this); | |||||
| // knob Scatter | |||||
| fKnobScatter = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobScatter->setId(GrainJuicePlugin::paramScatter); | |||||
| fKnobScatter->setAbsolutePos(PX+SX, PY); | |||||
| fKnobScatter->setRotationAngle(270); | |||||
| fKnobScatter->setRange(0.0f, 1.0f); | |||||
| fKnobScatter->setDefault(0.5f); | |||||
| fKnobScatter->setStep(0.01f); | |||||
| fKnobScatter->setCallback(this); | |||||
| // knob Gain | |||||
| fKnobGain = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobGain->setId(GrainJuicePlugin::paramGain); | |||||
| fKnobGain->setAbsolutePos(PX+SX*2, PY); | |||||
| fKnobGain->setRotationAngle(270); | |||||
| fKnobGain->setRange(0.0f, 1.0f); | |||||
| fKnobGain->setDefault(0.5f); | |||||
| fKnobGain->setStep(0.01f); | |||||
| fKnobGain->setCallback(this); | |||||
| // knob Density | |||||
| fKnobDensity = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobDensity->setId(GrainJuicePlugin::paramDensity); | |||||
| fKnobDensity->setAbsolutePos(PX+SX*3, PY); | |||||
| fKnobDensity->setRotationAngle(270); | |||||
| fKnobDensity->setRange(0.0f, 1.0f); | |||||
| fKnobDensity->setDefault(0.5f); | |||||
| fKnobDensity->setStep(0.01f); | |||||
| fKnobDensity->setCallback(this); | |||||
| // knob LPF | |||||
| fKnobLPF = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobLPF->setId(GrainJuicePlugin::paramLPF); | |||||
| fKnobLPF->setAbsolutePos(PX+SX*4, PY); | |||||
| fKnobLPF->setRotationAngle(270); | |||||
| fKnobLPF->setRange(0.0f, 1.0f); | |||||
| fKnobLPF->setDefault(0.5f); | |||||
| fKnobLPF->setStep(0.01f); | |||||
| fKnobLPF->setCallback(this); | |||||
| // knob HPF | |||||
| fKnobHPF = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobHPF->setId(GrainJuicePlugin::paramHPF); | |||||
| fKnobHPF->setAbsolutePos(PX+SX*5, PY); | |||||
| fKnobHPF->setRotationAngle(270); | |||||
| fKnobHPF->setRange(0.0f, 1.0f); | |||||
| fKnobHPF->setDefault(0.5f); | |||||
| fKnobHPF->setStep(0.01f); | |||||
| fKnobHPF->setCallback(this); | |||||
| //////////// RANDOMIZE KNOBS | |||||
| // knob Size | |||||
| fKnobSizeR = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobSizeR->setId(GrainJuicePlugin::paramSizeR); | |||||
| fKnobSizeR->setAbsolutePos(PX, PY+SY); | |||||
| fKnobSizeR->setRotationAngle(270); | |||||
| fKnobSizeR->setRange(0.0f, 1.0f); | |||||
| fKnobSizeR->setDefault(0.5f); | |||||
| fKnobSizeR->setStep(0.01f); | |||||
| fKnobSizeR->setCallback(this); | |||||
| // knob Scatter | |||||
| fKnobScatterR = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobScatterR->setId(GrainJuicePlugin::paramScatterR); | |||||
| fKnobScatterR->setAbsolutePos(PX+SX, PY+SY); | |||||
| fKnobScatterR->setRotationAngle(270); | |||||
| fKnobScatterR->setRange(0.0f, 1.0f); | |||||
| fKnobScatterR->setDefault(0.5f); | |||||
| fKnobScatterR->setStep(0.01f); | |||||
| fKnobScatterR->setCallback(this); | |||||
| // knob Gain | |||||
| fKnobGainR = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobGainR->setId(GrainJuicePlugin::paramGainR); | |||||
| fKnobGainR->setAbsolutePos(PX+SX*2, PY+SY); | |||||
| fKnobGainR->setRotationAngle(270); | |||||
| fKnobGainR->setRange(0.0f, 1.0f); | |||||
| fKnobGainR->setDefault(0.5f); | |||||
| fKnobGainR->setStep(0.01f); | |||||
| fKnobGainR->setCallback(this); | |||||
| // knob Density | |||||
| fKnobDensityR = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobDensityR->setId(GrainJuicePlugin::paramDensityR); | |||||
| fKnobDensityR->setAbsolutePos(PX+SX*3, PY+SY); | |||||
| fKnobDensityR->setRotationAngle(270); | |||||
| fKnobDensityR->setRange(0.0f, 1.0f); | |||||
| fKnobDensityR->setDefault(0.5f); | |||||
| fKnobDensityR->setStep(0.01f); | |||||
| fKnobDensityR->setCallback(this); | |||||
| // knob LPF | |||||
| fKnobLPFR = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobLPFR->setId(GrainJuicePlugin::paramLPFR); | |||||
| fKnobLPFR->setAbsolutePos(PX+SX*4, PY+SY); | |||||
| fKnobLPFR->setRotationAngle(270); | |||||
| fKnobLPFR->setRange(0.0f, 1.0f); | |||||
| fKnobLPFR->setDefault(0.5f); | |||||
| fKnobLPFR->setStep(0.01f); | |||||
| fKnobLPFR->setCallback(this); | |||||
| // knob HPF | |||||
| fKnobHPFR = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||||
| fKnobHPFR->setId(GrainJuicePlugin::paramHPFR); | |||||
| fKnobHPFR->setAbsolutePos(PX+SX*5, PY+SY); | |||||
| fKnobHPFR->setRotationAngle(270); | |||||
| fKnobHPFR->setRange(0.0f, 1.0f); | |||||
| fKnobHPFR->setDefault(0.5f); | |||||
| fKnobHPFR->setStep(0.01f); | |||||
| fKnobHPFR->setCallback(this); | |||||
| // about button | |||||
| Image aboutImageNormal(GrainJuiceArtwork::aboutButtonNormalData, GrainJuiceArtwork::aboutButtonNormalWidth, GrainJuiceArtwork::aboutButtonNormalHeight); | |||||
| Image aboutImageHover(GrainJuiceArtwork::aboutButtonHoverData, GrainJuiceArtwork::aboutButtonHoverWidth, GrainJuiceArtwork::aboutButtonHoverHeight); | |||||
| fButtonAbout = new ImageButton(this, aboutImageNormal, aboutImageHover, aboutImageHover); | |||||
| fButtonAbout->setAbsolutePos(390, 20); | |||||
| fButtonAbout->setCallback(this); | |||||
| // set default values | |||||
| d_programChanged(0); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| // DSP Callbacks | |||||
| void GrainJuiceUI::d_parameterChanged(uint32_t index, float value) { | |||||
| switch (index) { | |||||
| case GrainJuicePlugin::paramSize: | |||||
| fKnobSize->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramScatter: | |||||
| fKnobScatter->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramGain: | |||||
| fKnobGain->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramDensity: | |||||
| fKnobDensity->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramLPF: | |||||
| fKnobLPF->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramHPF: | |||||
| fKnobHPF->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramSizeR: | |||||
| fKnobSizeR->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramScatterR: | |||||
| fKnobScatterR->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramGainR: | |||||
| fKnobGainR->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramDensityR: | |||||
| fKnobDensityR->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramLPFR: | |||||
| fKnobLPFR->setValue(value); | |||||
| break; | |||||
| case GrainJuicePlugin::paramHPFR: | |||||
| fKnobHPFR->setValue(value); | |||||
| break; | |||||
| } | |||||
| } | |||||
| void GrainJuiceUI::d_programChanged(uint32_t index) { | |||||
| if (index != 0) | |||||
| return; | |||||
| // Default values | |||||
| fKnobSize->setValue(0.5f); | |||||
| fKnobScatter->setValue(0.5f); | |||||
| fKnobGain->setValue(0.5f); | |||||
| fKnobDensity->setValue(0.5f); | |||||
| fKnobLPF->setValue(0.5f); | |||||
| fKnobHPF->setValue(0.5f); | |||||
| fKnobSizeR->setValue(0.5f); | |||||
| fKnobScatterR->setValue(0.5f); | |||||
| fKnobGainR->setValue(0.5f); | |||||
| fKnobDensityR->setValue(0.5f); | |||||
| fKnobLPFR->setValue(0.5f); | |||||
| fKnobHPFR->setValue(0.5f); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| // Widget Callbacks | |||||
| void GrainJuiceUI::imageButtonClicked(ImageButton* button, int) { | |||||
| if (button != fButtonAbout) | |||||
| return; | |||||
| fAboutWindow.exec(); | |||||
| } | |||||
| void GrainJuiceUI::imageKnobDragStarted(ImageKnob* knob) { | |||||
| d_editParameter(knob->getId(), true); | |||||
| } | |||||
| void GrainJuiceUI::imageKnobDragFinished(ImageKnob* knob) { | |||||
| d_editParameter(knob->getId(), false); | |||||
| } | |||||
| void GrainJuiceUI::imageKnobValueChanged(ImageKnob* knob, float value) { | |||||
| d_setParameterValue(knob->getId(), value); | |||||
| } | |||||
| void GrainJuiceUI::onDisplay() { | |||||
| fImgBackground.draw(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| UI* createUI() { | |||||
| return new GrainJuiceUI(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DISTRHO | |||||
| @@ -0,0 +1,80 @@ | |||||
| /* | |||||
| * Grain Juice Plugin | |||||
| * Copyright (C) 2014 Andre Sklenar <andre.sklenar@gmail.com>, www.juicelab.cz | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License as | |||||
| * published by the Free Software Foundation; either version 2 of | |||||
| * the License, or any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
| */ | |||||
| #ifndef GrainJUICEUI_HPP_INCLUDED | |||||
| #define GrainJUICEUI_HPP_INCLUDED | |||||
| #include "DistrhoUI.hpp" | |||||
| #include "ImageAboutWindow.hpp" | |||||
| #include "ImageButton.hpp" | |||||
| #include "ImageKnob.hpp" | |||||
| #include "GrainJuiceArtwork.hpp" | |||||
| using DGL::Image; | |||||
| using DGL::ImageAboutWindow; | |||||
| using DGL::ImageButton; | |||||
| using DGL::ImageKnob; | |||||
| START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------- | |||||
| class GrainJuiceUI : public UI, | |||||
| public ImageButton::Callback, | |||||
| public ImageKnob::Callback { | |||||
| public: | |||||
| GrainJuiceUI(); | |||||
| protected: | |||||
| // ------------------------------------------------------------------- | |||||
| // DSP Callbacks | |||||
| void d_parameterChanged(uint32_t index, float value) override; | |||||
| void d_programChanged(uint32_t index) override; | |||||
| // ------------------------------------------------------------------- | |||||
| // Widget Callbacks | |||||
| void imageButtonClicked(ImageButton* button, int) override; | |||||
| void imageKnobDragStarted(ImageKnob* knob) override; | |||||
| void imageKnobDragFinished(ImageKnob* knob) override; | |||||
| void imageKnobValueChanged(ImageKnob* knob, float value) override; | |||||
| void onDisplay() override; | |||||
| private: | |||||
| Image fImgBackground; | |||||
| ImageAboutWindow fAboutWindow; | |||||
| ScopedPointer<ImageButton> fButtonAbout; | |||||
| ScopedPointer<ImageKnob> fKnobSize, fKnobScatter, fKnobGain; | |||||
| ScopedPointer<ImageKnob> fKnobDensity, fKnobLPF, fKnobHPF; | |||||
| ScopedPointer<ImageKnob> fKnobSizeR, fKnobScatterR, fKnobGainR; | |||||
| ScopedPointer<ImageKnob> fKnobDensityR, fKnobLPFR, fKnobHPFR; | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(GrainJuiceUI) | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DISTRHO | |||||
| #endif // GrainJUICEUI_HPP_INCLUDED | |||||
| @@ -0,0 +1,37 @@ | |||||
| #!/usr/bin/make -f | |||||
| # Makefile for DISTRHO Plugins # | |||||
| # ---------------------------- # | |||||
| # Created by falkTX | |||||
| # | |||||
| # -------------------------------------------------------------- | |||||
| # Project name, used for binaries | |||||
| NAME = GrainJuice | |||||
| # -------------------------------------------------------------- | |||||
| # Files to build | |||||
| OBJS_DSP = \ | |||||
| GrainJuicePlugin.cpp.o | |||||
| OBJS_UI = \ | |||||
| GrainJuiceArtwork.cpp.o \ | |||||
| GrainJuiceUI.cpp.o | |||||
| # -------------------------------------------------------------- | |||||
| # Do some magic | |||||
| include ../Makefile.mk | |||||
| # -------------------------------------------------------------- | |||||
| # Enable all possible plugin types | |||||
| ifeq ($(LINUX),true) | |||||
| all: jack | |||||
| #lv2_sep vst | |||||
| else | |||||
| all: lv2_sep vst | |||||
| endif | |||||
| # -------------------------------------------------------------- | |||||