@@ -70,6 +70,12 @@ OBJS += $(OBJDIR)/distrho-prom.cpp.o | |||
endif | |||
endif | |||
# ---------------------------------------------------------------------------------------------------------------------------- | |||
# DISTRHO plugins (Juice) | |||
OBJS += \ | |||
$(OBJDIR)/distrho-wobblejuice.cpp.o | |||
# ---------------------------------------------------------------------------------------------------------------------------- | |||
# ZynAddSubFX | |||
@@ -209,6 +215,13 @@ $(OBJDIR)/distrho-prom.cpp.o: distrho-prom.cpp | |||
# ---------------------------------------------------------------------------------------------------------------------------- | |||
$(OBJDIR)/distrho-wobblejuice.cpp.o: distrho-wobblejuice.cpp | |||
-@mkdir -p $(OBJDIR) | |||
@echo "Compiling $<" | |||
@$(CXX) $< $(BUILD_CXX_FLAGS) -DDISTRHO_NAMESPACE=DISTRHO_WobbleJuice -Idistrho-wobblejuice -I$(CWD)/modules/dgl -Wno-effc++ -c -o $@ | |||
# ---------------------------------------------------------------------------------------------------------------------------- | |||
$(OBJDIR)/zynaddsubfx-fx.cpp.o: zynaddsubfx-fx.cpp $(ZYN_UI_FILES_H) | |||
-@mkdir -p $(OBJDIR) | |||
@echo "Compiling $<" | |||
@@ -47,6 +47,9 @@ extern void carla_register_native_plugin_distrho_nekobi(void); | |||
extern void carla_register_native_plugin_distrho_pingpongpan(void); | |||
extern void carla_register_native_plugin_distrho_prom(void); | |||
// DISTRHO plugins (Juice) | |||
extern void carla_register_native_plugin_distrho_wobblejuice(void); | |||
// External-UI plugins | |||
extern void carla_register_native_plugin_bigmeter(void); | |||
extern void carla_register_native_plugin_notes(void); | |||
@@ -99,6 +102,9 @@ void carla_register_all_native_plugins(void) | |||
#endif | |||
#endif | |||
// DISTRHO plugins (Juice) | |||
carla_register_native_plugin_distrho_wobblejuice(); | |||
#ifndef CARLA_OS_WIN | |||
// External-UI plugins | |||
carla_register_native_plugin_bigmeter(); | |||
@@ -471,6 +471,35 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||
#endif // HAVE_PROJECTM | |||
#endif // HAVE_DGL | |||
// ----------------------------------------------------------------------- | |||
// DISTRHO plugins (Juice) | |||
{ | |||
/* category */ NATIVE_PLUGIN_CATEGORY_DYNAMICS, | |||
#ifdef HAVE_DGL | |||
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE | |||
|NATIVE_PLUGIN_HAS_UI | |||
|NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD | |||
|NATIVE_PLUGIN_USES_PARENT_ID | |||
|NATIVE_PLUGIN_USES_TIME), | |||
#else | |||
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE | |||
|NATIVE_PLUGIN_USES_TIME), | |||
#endif | |||
/* supports */ static_cast<NativePluginSupports>(0x0), | |||
/* audioIns */ 2, | |||
/* audioOuts */ 2, | |||
/* midiIns */ 0, | |||
/* midiOuts */ 0, | |||
/* paramIns */ 6, | |||
/* paramOuts */ 0, | |||
/* name */ "WobbleJuice", | |||
/* label */ "wobblejuice", | |||
/* maker */ "Andre Sklenar", | |||
/* copyright */ "GPL v2+", | |||
DESCFUNCS | |||
}, | |||
// ----------------------------------------------------------------------- | |||
// External-UI plugins | |||
@@ -0,0 +1,84 @@ | |||
/* | |||
* Carla Native Plugins | |||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* 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. | |||
*/ | |||
// config fix | |||
#include "distrho-wobblejuice/DistrhoPluginInfo.h" | |||
#if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||
# undef DISTRHO_PLUGIN_HAS_UI | |||
# define DISTRHO_PLUGIN_HAS_UI 0 | |||
#endif | |||
// Plugin Code | |||
#include "distrho-wobblejuice/WobbleJuiceArtwork.cpp" | |||
#include "distrho-wobblejuice/WobbleJuicePlugin.cpp" | |||
#ifdef HAVE_DGL | |||
#include "distrho-wobblejuice/WobbleJuiceUI.cpp" | |||
#endif | |||
// DISTRHO Code | |||
#define DISTRHO_PLUGIN_TARGET_CARLA | |||
#include "DistrhoPluginMain.cpp" | |||
#ifdef HAVE_DGL | |||
#include "DistrhoUIMain.cpp" | |||
#endif | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
static const NativePluginDescriptor wobblejuiceDesc = { | |||
/* category */ NATIVE_PLUGIN_CATEGORY_DYNAMICS, | |||
#ifdef HAVE_DGL | |||
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE | |||
|NATIVE_PLUGIN_HAS_UI | |||
|NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD | |||
|NATIVE_PLUGIN_USES_PARENT_ID | |||
|NATIVE_PLUGIN_USES_TIME), | |||
#else | |||
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE | |||
|NATIVE_PLUGIN_USES_TIME), | |||
#endif | |||
/* supports */ static_cast<NativePluginSupports>(0x0), | |||
/* audioIns */ DISTRHO_PLUGIN_NUM_INPUTS, | |||
/* audioOuts */ DISTRHO_PLUGIN_NUM_OUTPUTS, | |||
/* midiIns */ 0, | |||
/* midiOuts */ 0, | |||
/* paramIns */ WobbleJuicePlugin::paramCount, | |||
/* paramOuts */ 0, | |||
/* name */ DISTRHO_PLUGIN_NAME, | |||
/* label */ "wobblejuice", | |||
/* maker */ "Andre Sklenar", | |||
/* copyright */ "GPL v2+", | |||
PluginDescriptorFILL(PluginCarla) | |||
}; | |||
END_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
CARLA_EXPORT | |||
void carla_register_native_plugin_distrho_wobblejuice(); | |||
CARLA_EXPORT | |||
void carla_register_native_plugin_distrho_wobblejuice() | |||
{ | |||
USE_NAMESPACE_DISTRHO | |||
carla_register_native_plugin(&wobblejuiceDesc); | |||
} | |||
// ----------------------------------------------------------------------- |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Wobble 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 "WobbleJuice" | |||
#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 1 | |||
#define DISTRHO_PLUGIN_URI "urn:distrho:WobbleJuice" | |||
#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED |
@@ -0,0 +1,35 @@ | |||
/* (Auto-generated binary data file). */ | |||
#ifndef BINARY_WOBBLEJUICEARTWORK_HPP | |||
#define BINARY_WOBBLEJUICEARTWORK_HPP | |||
namespace WobbleJuiceArtwork | |||
{ | |||
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 = 12544; | |||
const unsigned int knobWidth = 56; | |||
const unsigned int knobHeight = 56; | |||
} | |||
#endif // BINARY_WOBBLEJUICEARTWORK_HPP | |||
@@ -0,0 +1,243 @@ | |||
/* | |||
* Wobble 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 "WobbleJuicePlugin.hpp" | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
WobbleJuicePlugin::WobbleJuicePlugin() | |||
: Plugin(paramCount, 1, 0) // 1 program, 0 states | |||
{ | |||
// set default values | |||
d_setProgram(0); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Init | |||
void WobbleJuicePlugin::d_initParameter(uint32_t index, Parameter& parameter) | |||
{ | |||
switch (index) | |||
{ | |||
case paramDivision: | |||
parameter.hints = kParameterIsAutomable|kParameterIsInteger; | |||
parameter.name = "Division"; | |||
parameter.symbol = "div"; | |||
parameter.unit = "x"; | |||
parameter.ranges.def = 4.0f; | |||
parameter.ranges.min = 1.0f; | |||
parameter.ranges.max = 16.0f; | |||
break; | |||
case paramReso: | |||
parameter.hints = kParameterIsAutomable; | |||
parameter.name = "Resonance"; | |||
parameter.symbol = "reso"; | |||
parameter.unit = ""; | |||
parameter.ranges.def = 0.1f; | |||
parameter.ranges.min = 0.0f; | |||
parameter.ranges.max = 0.2f; | |||
break; | |||
case paramRange: | |||
parameter.hints = kParameterIsAutomable; | |||
parameter.name = "Range"; | |||
parameter.symbol = "rng"; | |||
parameter.unit = "Hz"; | |||
parameter.ranges.def = 16000.0f; | |||
parameter.ranges.min = 500.0f; | |||
parameter.ranges.max = 16000.0f; | |||
break; | |||
case paramPhase: | |||
parameter.hints = kParameterIsAutomable; | |||
parameter.name = "Phase"; | |||
parameter.symbol = "phs"; | |||
parameter.unit = "Deg"; | |||
parameter.ranges.def = 0.0f; | |||
parameter.ranges.min = -1.0f; | |||
parameter.ranges.max = 1.0f; | |||
break; | |||
case paramWave: | |||
parameter.hints = kParameterIsAutomable; | |||
parameter.name = "Wave"; | |||
parameter.symbol = "wav"; | |||
parameter.unit = ""; | |||
parameter.ranges.def = 2.0f; | |||
parameter.ranges.min = 1.0f; | |||
parameter.ranges.max = 4.0f; | |||
break; | |||
case paramDrive: | |||
parameter.hints = kParameterIsAutomable; | |||
parameter.name = "Drive"; | |||
parameter.symbol = "drv"; | |||
parameter.unit = ""; | |||
parameter.ranges.def = 0.5f; | |||
parameter.ranges.min = 0.0f; | |||
parameter.ranges.max = 1.0f; | |||
break; | |||
} | |||
} | |||
void WobbleJuicePlugin::d_initProgramName(uint32_t index, d_string& programName) | |||
{ | |||
if (index != 0) | |||
return; | |||
programName = "Default"; | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Internal data | |||
float WobbleJuicePlugin::d_getParameterValue(uint32_t index) const | |||
{ | |||
switch (index) | |||
{ | |||
case paramDivision: | |||
return division; | |||
case paramReso: | |||
return reso; | |||
case paramRange: | |||
return range; | |||
case paramPhase: | |||
return phase; | |||
case paramWave: | |||
return wave; | |||
case paramDrive: | |||
return drive; | |||
default: | |||
return 0.0f; | |||
} | |||
} | |||
void WobbleJuicePlugin::d_setParameterValue(uint32_t index, float value) | |||
{ | |||
switch (index) | |||
{ | |||
case paramDivision: | |||
division = value; | |||
break; | |||
case paramReso: | |||
reso = value; | |||
break; | |||
case paramRange: | |||
range = value; | |||
break; | |||
case paramPhase: | |||
phase = value; | |||
break; | |||
case paramWave: | |||
wave = value; | |||
break; | |||
case paramDrive: | |||
drive = value; | |||
break; | |||
} | |||
} | |||
void WobbleJuicePlugin::d_setProgram(uint32_t index) | |||
{ | |||
if (index != 0) | |||
return; | |||
/* Default parameter values */ | |||
division = 4.0f; | |||
reso = 0.1f; | |||
range = 16000.0f; | |||
phase = 0.0f; | |||
wave = 2.0f; | |||
drive = 0.5f; | |||
/* Default variable values */ | |||
bar=tick=tickOffset=percentage=phaseOffset=currentPhaseL=0.0f; | |||
currentPhaseR=posL=posR=cutoffL=cutoffR=0.0f; | |||
waveType=2.0f; | |||
/* reset filter values */ | |||
d_activate(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Process | |||
void WobbleJuicePlugin::d_activate() | |||
{ | |||
sinePos = 0.0; | |||
} | |||
void WobbleJuicePlugin::d_run(const float** inputs, float** outputs, uint32_t frames) | |||
{ | |||
//fetch the timepos struct from host; | |||
const TimePosition& time(d_getTimePosition()); | |||
/* sample count for one bar */ | |||
bar = ((120.0/(time.bbt.valid ? time.bbt.beatsPerMinute : 120.0))*(d_getSampleRate())); //ONE, two, three, four | |||
tick = bar/(std::round(division)); //size of one target wob | |||
phaseOffset = phase*M_PI; //2pi = 1 whole cycle | |||
/* if rolling then sync to timepos */ | |||
if (time.playing) | |||
{ | |||
tickOffset = time.frame-std::floor(time.frame/tick)*tick; //how much after last tick | |||
if (tickOffset!=0) { | |||
//TODO: why do we need this?? | |||
percentage = tickOffset/tick; | |||
} else { | |||
percentage = 0; | |||
} | |||
sinePos = (M_PI*2)*percentage; | |||
if (sinePos>2*M_PI) { | |||
//TODO: can this ever happen?? | |||
sinePos = 0; | |||
} | |||
} | |||
/* else just keep on wobblin' */ | |||
else | |||
{ | |||
sinePos += (M_PI)/(tick/2000); //wtf, but works | |||
if (sinePos>2*M_PI) { | |||
sinePos = 0; | |||
} | |||
} | |||
/* phase of 0..1 filter = 500..16k */ | |||
currentPhaseL = getBlendedPhase(sinePos+phaseOffset, wave); | |||
currentPhaseR = getBlendedPhase(sinePos-phaseOffset, wave); | |||
/* logarithmic */ | |||
cutoffL = std::exp((std::log(range)-std::log(500))*currentPhaseL+std::log(500)); | |||
cutoffR = std::exp((std::log(range)-std::log(500))*currentPhaseR+std::log(500)); | |||
//output filtered signal | |||
filterL.recalc(cutoffL, reso*4, d_getSampleRate(), drive); | |||
filterR.recalc(cutoffR, reso*4, d_getSampleRate(), drive); | |||
filterL.process(frames, inputs[0], outputs[0]); | |||
filterR.process(frames, inputs[1], outputs[1]); | |||
} | |||
// ----------------------------------------------------------------------- | |||
Plugin* createPlugin() | |||
{ | |||
return new WobbleJuicePlugin(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DISTRHO |
@@ -0,0 +1,142 @@ | |||
/* | |||
* Wobble 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 WOBBLEJUICEPLUGIN_HPP_INCLUDED | |||
#define WOBBLEJUICEPLUGIN_HPP_INCLUDED | |||
#include "DistrhoPlugin.hpp" | |||
#include "moogVCF.hxx" | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
class WobbleJuicePlugin : public Plugin | |||
{ | |||
public: | |||
enum Parameters | |||
{ | |||
paramDivision = 0, | |||
paramReso, | |||
paramRange, | |||
paramPhase, | |||
paramWave, | |||
paramDrive, | |||
paramCount | |||
}; | |||
float getSinePhase(float x) { | |||
return ((-std::cos(x)+1)/2); | |||
} | |||
float getSawPhase(float x) { | |||
return (-((2/M_PI * std::atan(1/std::tan(x/2)))-1)/2); | |||
} | |||
float getRevSawPhase(float x) { | |||
return (((2/M_PI * std::atan(1/std::tan(x/2)))+1)/2); | |||
} | |||
float getSquarePhase(float x) { | |||
return (std::round((std::sin(x)+1)/2)); | |||
} | |||
//saw, sqr, sin, revSaw | |||
float getBlendedPhase(float x, float wave) | |||
{ | |||
//wave = 2; | |||
if (wave>=1 && wave<2) { | |||
/* saw vs sqr */ | |||
waveBlend = wave-1; | |||
return (getSawPhase(x)*(1-waveBlend) + getSquarePhase(x)*waveBlend); | |||
} else if (wave>=2 && wave<3) { | |||
/* sqr vs sin */ | |||
waveBlend = wave-2; | |||
return (getSquarePhase(x)*(1-waveBlend) + getSinePhase(x)*waveBlend); | |||
} else if (wave>=3 && wave<=4) { | |||
/* sin vs revSaw */ | |||
waveBlend = wave-3; | |||
return (getSinePhase(x)*(1-waveBlend) + getRevSawPhase(x)*waveBlend); | |||
} else { | |||
return 0.0f; | |||
} | |||
} | |||
WobbleJuicePlugin(); | |||
protected: | |||
// ------------------------------------------------------------------- | |||
// Information | |||
const char* d_getLabel() const noexcept override | |||
{ | |||
return "WobbleJuice"; | |||
} | |||
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('W', 'b', 'l', '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: | |||
MoogVCF filterL, filterR; | |||
float division, reso, range, phase, wave, drive; //parameters | |||
float bar, tick, tickOffset, percentage, phaseOffset, currentPhaseL, currentPhaseR, posL, posR, cutoffL, cutoffR; | |||
double sinePos; | |||
float waveType, waveBlend; | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(WobbleJuicePlugin) | |||
}; | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DISTRHO | |||
#endif // WOBBLEJUICE_HPP_INCLUDED |
@@ -0,0 +1,189 @@ | |||
/* | |||
* Wobble 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 "WobbleJuicePlugin.hpp" | |||
#include "WobbleJuiceUI.hpp" | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
WobbleJuiceUI::WobbleJuiceUI() | |||
: UI(), | |||
fAboutWindow(this) | |||
{ | |||
setSize(WobbleJuiceArtwork::backgroundWidth, WobbleJuiceArtwork::backgroundHeight); | |||
// background | |||
fImgBackground = Image(WobbleJuiceArtwork::backgroundData, WobbleJuiceArtwork::backgroundWidth, WobbleJuiceArtwork::backgroundHeight, GL_BGR); | |||
// about | |||
Image aboutImage(WobbleJuiceArtwork::aboutData, WobbleJuiceArtwork::aboutWidth, WobbleJuiceArtwork::aboutHeight, GL_BGR); | |||
fAboutWindow.setImage(aboutImage); | |||
// knobs | |||
Image knobImage(WobbleJuiceArtwork::knobData, WobbleJuiceArtwork::knobWidth, WobbleJuiceArtwork::knobHeight); | |||
// knob Division | |||
fKnobDivision = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||
fKnobDivision->setId(WobbleJuicePlugin::paramDivision); | |||
fKnobDivision->setAbsolutePos(222, 74); | |||
fKnobDivision->setRotationAngle(270); | |||
fKnobDivision->setRange(1.0f, 16.0f); | |||
fKnobDivision->setDefault(4.0f); | |||
fKnobDivision->setStep(1.0f); | |||
fKnobDivision->setCallback(this); | |||
// knob Resonance | |||
fKnobResonance = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||
fKnobResonance->setId(WobbleJuicePlugin::paramReso); | |||
fKnobResonance->setAbsolutePos(222, 199); | |||
fKnobResonance->setRotationAngle(270); | |||
fKnobResonance->setRange(0.0f, 0.2f); | |||
fKnobResonance->setDefault(0.1f); | |||
fKnobResonance->setCallback(this); | |||
// knob Range | |||
fKnobRange = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||
fKnobRange->setId(WobbleJuicePlugin::paramRange); | |||
fKnobRange->setAbsolutePos(77, 199); | |||
fKnobRange->setRotationAngle(270); | |||
fKnobRange->setRange(500.0f, 16000.0f); | |||
fKnobRange->setDefault(16000.0f); | |||
fKnobRange->setCallback(this); | |||
// knob Phase | |||
fKnobPhase = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||
fKnobPhase->setId(WobbleJuicePlugin::paramPhase); | |||
fKnobPhase->setAbsolutePos(362, 74); | |||
fKnobPhase->setRotationAngle(270); | |||
fKnobPhase->setRange(-1.0f, 1.0f); | |||
fKnobPhase->setDefault(0.0f); | |||
fKnobPhase->setCallback(this); | |||
// knob Wave | |||
fKnobWave = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||
fKnobWave->setId(WobbleJuicePlugin::paramWave); | |||
fKnobWave->setAbsolutePos(77, 74); | |||
fKnobWave->setRotationAngle(270); | |||
fKnobWave->setRange(1.0f, 4.0f); | |||
fKnobWave->setDefault(2.0f); | |||
fKnobWave->setCallback(this); | |||
// knob Drive | |||
fKnobDrive = new ImageKnob(this, knobImage, ImageKnob::Vertical); | |||
fKnobDrive->setId(WobbleJuicePlugin::paramDrive); | |||
fKnobDrive->setAbsolutePos(362, 199); | |||
fKnobDrive->setRotationAngle(270); | |||
fKnobDrive->setRange(0.0f, 1.0f); | |||
fKnobDrive->setDefault(0.5f); | |||
fKnobDrive->setCallback(this); | |||
// about button | |||
Image aboutImageNormal(WobbleJuiceArtwork::aboutButtonNormalData, WobbleJuiceArtwork::aboutButtonNormalWidth, WobbleJuiceArtwork::aboutButtonNormalHeight); | |||
Image aboutImageHover(WobbleJuiceArtwork::aboutButtonHoverData, WobbleJuiceArtwork::aboutButtonHoverWidth, WobbleJuiceArtwork::aboutButtonHoverHeight); | |||
fButtonAbout = new ImageButton(this, aboutImageNormal, aboutImageHover, aboutImageHover); | |||
fButtonAbout->setAbsolutePos(390, 20); | |||
fButtonAbout->setCallback(this); | |||
// set default values | |||
d_programChanged(0); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// DSP Callbacks | |||
void WobbleJuiceUI::d_parameterChanged(uint32_t index, float value) | |||
{ | |||
switch (index) | |||
{ | |||
case WobbleJuicePlugin::paramDivision: | |||
fKnobDivision->setValue(value); | |||
break; | |||
case WobbleJuicePlugin::paramReso: | |||
fKnobResonance->setValue(value); | |||
break; | |||
case WobbleJuicePlugin::paramRange: | |||
fKnobRange->setValue(value); | |||
break; | |||
case WobbleJuicePlugin::paramPhase: | |||
fKnobPhase->setValue(value); | |||
break; | |||
case WobbleJuicePlugin::paramWave: | |||
fKnobWave->setValue(value); | |||
break; | |||
case WobbleJuicePlugin::paramDrive: | |||
fKnobDrive->setValue(value); | |||
break; | |||
} | |||
} | |||
void WobbleJuiceUI::d_programChanged(uint32_t index) | |||
{ | |||
if (index != 0) | |||
return; | |||
// Default values | |||
fKnobDivision->setValue(4.0f); | |||
fKnobResonance->setValue(0.1f); | |||
fKnobRange->setValue(16000.0f); | |||
fKnobPhase->setValue(0.0f); | |||
fKnobWave->setValue(2.0f); | |||
fKnobDrive->setValue(0.5f); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Widget Callbacks | |||
void WobbleJuiceUI::imageButtonClicked(ImageButton* button, int) | |||
{ | |||
if (button != fButtonAbout) | |||
return; | |||
fAboutWindow.exec(); | |||
} | |||
void WobbleJuiceUI::imageKnobDragStarted(ImageKnob* knob) | |||
{ | |||
d_editParameter(knob->getId(), true); | |||
} | |||
void WobbleJuiceUI::imageKnobDragFinished(ImageKnob* knob) | |||
{ | |||
d_editParameter(knob->getId(), false); | |||
} | |||
void WobbleJuiceUI::imageKnobValueChanged(ImageKnob* knob, float value) | |||
{ | |||
d_setParameterValue(knob->getId(), value); | |||
} | |||
void WobbleJuiceUI::onDisplay() | |||
{ | |||
fImgBackground.draw(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
UI* createUI() | |||
{ | |||
return new WobbleJuiceUI(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DISTRHO |
@@ -0,0 +1,77 @@ | |||
/* | |||
* Wobble 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 WOBBLEJUICEUI_HPP_INCLUDED | |||
#define WOBBLEJUICEUI_HPP_INCLUDED | |||
#include "DistrhoUI.hpp" | |||
#include "ImageAboutWindow.hpp" | |||
#include "ImageButton.hpp" | |||
#include "ImageKnob.hpp" | |||
#include "WobbleJuiceArtwork.hpp" | |||
using DGL::Image; | |||
using DGL::ImageAboutWindow; | |||
using DGL::ImageButton; | |||
using DGL::ImageKnob; | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
class WobbleJuiceUI : public UI, | |||
public ImageButton::Callback, | |||
public ImageKnob::Callback | |||
{ | |||
public: | |||
WobbleJuiceUI(); | |||
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> fKnobDivision, fKnobResonance, fKnobRange; | |||
ScopedPointer<ImageKnob> fKnobPhase, fKnobWave, fKnobDrive; | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(WobbleJuiceUI) | |||
}; | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DISTRHO | |||
#endif // WOBBLEJUICEUI_HPP_INCLUDED |
@@ -0,0 +1,76 @@ | |||
/* | |||
* Moog-like resonant LPF | |||
* Implemented by Andre Sklenar <andre.sklenar@gmail.com>, www.juicelab.cz . | |||
* | |||
* Filter design from http://www.musicdsp.com . | |||
*/ | |||
#ifndef MOOG_VCF_HXX_INCLUDED | |||
#define MOOG_VCF_HXX_INCLUDED | |||
#include <cmath> | |||
#include <cstdlib> | |||
class MoogVCF | |||
{ | |||
public: | |||
MoogVCF() | |||
{ | |||
cutoff = 16000; | |||
res = 0.5; | |||
f=k=p=scale=r=0; | |||
y1=y2=y3=y4=oldIn=oldY1=oldY2=oldY3=0; | |||
in=oldIn=0; | |||
pureInput=drivenInput=processedInput=0; | |||
} | |||
void recalc(float cutoff, float reso, int sr, float nDrive) | |||
{ | |||
f = 2*cutoff/sr; | |||
k=2*std::sin(f*M_PI/2)-1; | |||
p = (k+1)*0.5; | |||
scale = std::pow(2.71828, (1-p)*1.386249); | |||
r = reso*scale; | |||
drive = nDrive; | |||
} | |||
void process (long frames, const float* inputs, float* outputs) | |||
{ | |||
//run the shit | |||
for (long i=0; i<frames; i++) | |||
{ | |||
pureInput = inputs[i]; //clean signal | |||
drivenInput = std::tanh(pureInput*(drive*15+1)) * (drive); //a touch of waveshaping | |||
processedInput = pureInput*(1-drive) + drivenInput; // combine | |||
processedInput*=1-drive/3; //reduce gain a little | |||
/* filter */ | |||
in = processedInput-r*y4; | |||
y1 = in*p + oldIn*p - k*y1; | |||
y2 = y1*p + oldY1*p - k*y2; | |||
y3 = y2*p + oldY2*p - k*y3; | |||
y4 = y3*p + oldY3*p - k*y4; | |||
oldIn = in; | |||
oldY1 = y1; | |||
oldY2 = y2; | |||
oldY3 = y3; | |||
/* output */ | |||
outputs[i] = y4; | |||
} | |||
} | |||
private: | |||
/* vcf filter */ | |||
float cutoff; //freq in Hz | |||
float res; //resonance 0..1 | |||
float drive; //drive 1...2; | |||
float f, k, p, scale, r; | |||
float y1, y2, y3, y4, oldY1, oldY2, oldY3; | |||
float in, oldIn; | |||
/* waveshaping vars */ | |||
float pureInput, drivenInput, processedInput; | |||
}; | |||
#endif // MOOG_VCF_HXX_INCLUDED |
@@ -72,7 +72,8 @@ struct PluginListManager { | |||
std::strcmp(desc->label, "nekobi" ) == 0 || | |||
std::strcmp(desc->label, "pingpongpan" ) == 0 || | |||
std::strcmp(desc->label, "prom" ) == 0 || | |||
std::strcmp(desc->label, "vexsynth" ) == 0) | |||
std::strstr(desc->label, "Juice" ) != nullptr || | |||
std::strstr(desc->label, "Zam" ) != nullptr) | |||
{ | |||
continue; | |||
} | |||