@@ -42,7 +42,7 @@ extern void carla_register_native_plugin_nekobi(); | |||
extern void carla_register_native_plugin_pingpongpan(); | |||
extern void carla_register_native_plugin_stereoenhancer(); | |||
//extern void carla_register_native_plugin_powerjuice(); | |||
extern void carla_register_native_plugin_powerjuice(); | |||
extern void carla_register_native_plugin_segmentjuice(); | |||
extern void carla_register_native_plugin_vectorjuice(); | |||
extern void carla_register_native_plugin_wobblejuice(); | |||
@@ -105,7 +105,7 @@ void carla_register_all_plugins() | |||
carla_register_native_plugin_pingpongpan(); | |||
//carla_register_native_plugin_stereoenhancer(); | |||
//carla_register_native_plugin_powerjuice(); | |||
carla_register_native_plugin_powerjuice(); | |||
carla_register_native_plugin_segmentjuice(); | |||
carla_register_native_plugin_vectorjuice(); | |||
carla_register_native_plugin_wobblejuice(); | |||
@@ -28,9 +28,12 @@ | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
#define DISTRHO_PLUGIN_WANT_STATE 1 | |||
#define DISTRHO_PLUGIN_WANT_STATE 0 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
// needed for spectrum | |||
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 | |||
#define DISTRHO_PLUGIN_URI "urn:distrho:PowerJuice" | |||
#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED |
@@ -29,17 +29,14 @@ PowerJuicePlugin::PowerJuicePlugin() | |||
// set default values | |||
d_setProgram(0); | |||
// init shm vars | |||
carla_shm_init(shm); | |||
shmData = nullptr; | |||
// reset | |||
d_deactivate(); | |||
} | |||
PowerJuicePlugin::~PowerJuicePlugin() | |||
{ | |||
closeShm(); | |||
free(lookaheadStack.data); | |||
free(RMSStack.data); | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -115,16 +112,6 @@ void PowerJuicePlugin::d_initProgramName(uint32_t index, d_string& programName) | |||
programName = "Default"; | |||
} | |||
void PowerJuicePlugin::d_initStateKey(uint32_t /*index*/, d_string& /*key*/) | |||
{ | |||
/* | |||
if (index != 0) | |||
return; | |||
key = "shmKey"; | |||
*/ | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Internal data | |||
@@ -155,9 +142,11 @@ void PowerJuicePlugin::d_setParameterValue(uint32_t index, float value) | |||
{ | |||
case paramAttack: | |||
attack = value; | |||
attackSamples = d_getSampleRate()*(attack/1000.0f); | |||
break; | |||
case paramRelease: | |||
release = value; | |||
releaseSamples = d_getSampleRate()*(release/1000.0f); | |||
break; | |||
case paramThreshold: | |||
threshold = value; | |||
@@ -167,6 +156,7 @@ void PowerJuicePlugin::d_setParameterValue(uint32_t index, float value) | |||
break; | |||
case paramMakeup: | |||
makeup = value; | |||
makeupFloat = fromDB(makeup); | |||
break; | |||
case paramMix: | |||
mix = value; | |||
@@ -187,34 +177,72 @@ void PowerJuicePlugin::d_setProgram(uint32_t index) | |||
makeup = 0.0f; | |||
mix = 1.0f; | |||
makeupFloat = fromDB(makeup); | |||
attackSamples = d_getSampleRate()*(attack/1000.0f); | |||
releaseSamples = d_getSampleRate()*(release/1000.0f); | |||
w = 563; //waveform plane size, size of the plane in pixels; | |||
w2 = 1126; //wavefowm array | |||
h = 121; //waveform plane height | |||
x = 27; //waveform plane positions | |||
y = 53; | |||
dc = 113; //0DC line y position | |||
/* Default variable values */ | |||
averageCounter = 0; | |||
inputMin = 0.0f; | |||
inputMax = 0.0f; | |||
balancer = 1.0f; | |||
GR = 1.0f; | |||
newRepaint = false; | |||
input.start = 0; | |||
output.start = 0; | |||
rms.start = 0; | |||
gainReduction.start = 0; | |||
std::memset(input.data, 0, sizeof(float)*kFloatStackCount); | |||
std::memset(output.data, 0, sizeof(float)*kFloatStackCount); | |||
RMSStack.start = 0; | |||
lookaheadStack.start = 0; | |||
repaintSkip = 0; | |||
kFloatRMSStackCount = 400.0f/44100.0f*d_getSampleRate(); | |||
RMSStack.data = (float*) calloc(kFloatRMSStackCount, sizeof(float)); | |||
kFloatLookaheadStackCount = 800.0f/44100.0f*d_getSampleRate(); | |||
lookaheadStack.data = (float*) calloc(kFloatLookaheadStackCount, sizeof(float)); | |||
refreshSkip= 300.0f/44100.0f*d_getSampleRate(); | |||
std::memset(rms.data, 0, sizeof(float)*kFloatStackCount); | |||
std::memset(gainReduction.data, 0, sizeof(float)*kFloatStackCount); | |||
std::memset(RMSStack.data, 0, sizeof(float)*kFloatRMSStackCount); | |||
std::memset(lookaheadStack.data, 0, sizeof(float)*kFloatLookaheadStackCount); | |||
for (int j=0; j < kFloatStackCount; ++j) | |||
history.rms[j] = h +y; | |||
for (int j=0; j < kFloatStackCount; ++j) | |||
history.gainReduction[j] = h +y; | |||
d_activate(); | |||
} | |||
void PowerJuicePlugin::d_setState(const char* key, const char* value) | |||
{ | |||
if (std::strcmp(key, "shmKey") != 0) | |||
return; | |||
float PowerJuicePlugin::getRMSHistory(int n) { | |||
return history.rms[n]; | |||
} | |||
if (value[0] == '\0') | |||
{ | |||
carla_stdout("Shm closed"); | |||
return closeShm(); | |||
} | |||
bool PowerJuicePlugin::repaintNeeded() { | |||
return newRepaint; | |||
} | |||
carla_stdout("Got shmKey => %s", value); | |||
initShm(value); | |||
float PowerJuicePlugin::getGainReductionHistory(int n) { | |||
if (n == kFloatStackCount-1) { | |||
newRepaint = false; | |||
//printf("falsing!\n"); | |||
} | |||
return history.gainReduction[n]; | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -229,71 +257,114 @@ void PowerJuicePlugin::d_deactivate() | |||
// all values to zero | |||
} | |||
void PowerJuicePlugin::d_run(float** inputs, float** /*outputs*/, uint32_t frames) | |||
void PowerJuicePlugin::d_run(float** inputs, float** outputs, uint32_t frames) | |||
{ | |||
float* in = inputs[0]; | |||
//float* out = outputs[0]; | |||
float* out = outputs[0]; | |||
float sum; | |||
float data; | |||
float difference; | |||
for (uint32_t i=0; i < frames; i++) { | |||
//for every sample | |||
//printf("av"); | |||
//averageInputs[averageCounter] = in[i]; | |||
if (in[i]<inputMin) { | |||
inputMin = in[i]; | |||
} | |||
if (in[i]>inputMax) { | |||
inputMax = in[i]; | |||
sum = 0.0f; | |||
data = 0.0f; | |||
difference = 0; | |||
sanitizeDenormal(in[i]); | |||
/* compute last RMS */ | |||
//store audio samples in an RMS buffer line | |||
RMSStack.data[RMSStack.start++] = in[i]; | |||
if (RMSStack.start == kFloatRMSStackCount) | |||
RMSStack.start = 0; | |||
//compute RMS over last kFloatRMSStackCount samples | |||
for (int j=0; j < kFloatRMSStackCount; ++j) { | |||
data = RMSStack.data[(RMSStack.start+j) % kFloatRMSStackCount]; | |||
sum += data * data; | |||
} | |||
if (++averageCounter == 300) { | |||
//output waveform parameter | |||
input.data[input.start++] = inputMin; | |||
input.data[input.start++] = inputMax; | |||
if (input.start == kFloatStackCount) | |||
input.start = 0; | |||
if (shmData != nullptr) | |||
{ | |||
for (int j=0; j < kFloatStackCount; ++j) | |||
shmData->input[j] = input.data[(input.start+j) % kFloatStackCount]; | |||
//root mean SQUARE | |||
float RMS = sqrt(sum / kFloatRMSStackCount); | |||
sanitizeDenormal(RMS); | |||
/* compute gain reduction if needed */ | |||
float RMSDB = toDB(RMS); | |||
if (RMSDB>threshold) { | |||
//attack stage | |||
float difference = (RMSDB-threshold); | |||
//sanitizeDenormal(difference); | |||
targetGR = difference - difference/ratio; | |||
if (targetGR>difference/(ratio/4.0f)) { | |||
targetGR = difference - difference/(ratio*1.5f); | |||
//more power! | |||
} | |||
// | |||
if (GR<targetGR) { | |||
//approach targetGR at attackSamples rate | |||
GR -= (GR-targetGR)/(attackSamples); | |||
} else { | |||
//approach targetGR at releaseSamples rate | |||
GR -= (GR-targetGR)/releaseSamples; | |||
} | |||
sanitizeDenormal(GR); | |||
} else { | |||
//release stage | |||
//approach targetGR at releaseSamples rate, targetGR = 0.0f | |||
GR -= GR/releaseSamples; | |||
} | |||
//store audio in lookahead buffer | |||
lookaheadStack.data[lookaheadStack.start++] = in[i]; | |||
//printf("rms\n"); | |||
if (lookaheadStack.start == kFloatLookaheadStackCount) | |||
lookaheadStack.start = 0; | |||
if (++averageCounter >= refreshSkip) { | |||
//add relevant values to the shared memory | |||
rms.data[rms.start++] = RMSDB; | |||
gainReduction.data[gainReduction.start++] = GR; | |||
//rewind stack reading heads if needed | |||
if (rms.start == kFloatStackCount) | |||
rms.start = 0; | |||
if (gainReduction.start == kFloatStackCount) | |||
gainReduction.start = 0; | |||
//saving in gfx format, for speed | |||
//share memory | |||
for (int j=0; j < kFloatStackCount; ++j) | |||
history.rms[j] = -toIEC(rms.data[(rms.start+j) % kFloatStackCount])/200*h +h +y; | |||
for (int j=0; j < kFloatStackCount; ++j) { | |||
history.gainReduction[j] = -toIEC(-gainReduction.data[(gainReduction.start+j) % kFloatStackCount])/200*h +h +y; | |||
} | |||
repaintSkip++; | |||
if (repaintSkip>5) { | |||
repaintSkip = 0; | |||
newRepaint = true; | |||
} | |||
averageCounter = 0; | |||
inputMin = 0.0f; | |||
inputMax = 0.0f; | |||
} | |||
} | |||
} | |||
void PowerJuicePlugin::initShm(const char* shmKey) | |||
{ | |||
shm = carla_shm_attach(shmKey); | |||
if (! carla_is_shm_valid(shm)) | |||
{ | |||
carla_stderr2("Failed to created shared memory!"); | |||
return; | |||
/* compress, mix, done. */ | |||
float compressedSignal = in[i]*fromDB(-GR); | |||
out[i] = (compressedSignal*makeupFloat*mix)+in[i]*(1-mix); | |||
} | |||
if (! carla_shm_map<SharedMemData>(shm, shmData)) | |||
{ | |||
carla_stderr2("Failed to map shared memory!"); | |||
return; | |||
} | |||
} | |||
void PowerJuicePlugin::closeShm() | |||
{ | |||
if (! carla_is_shm_valid(shm)) | |||
return; | |||
if (shmData != nullptr) | |||
{ | |||
carla_shm_unmap<SharedMemData>(shm, shmData); | |||
shmData = nullptr; | |||
} | |||
carla_shm_close(shm); | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -19,18 +19,29 @@ | |||
#define POWERJUICEPLUGIN_HPP_INCLUDED | |||
#include "DistrhoPlugin.hpp" | |||
#include "CarlaShmUtils.hpp" | |||
static const int kFloatStackCount = 1126; | |||
#include <cmath> | |||
struct FloatStack { | |||
static const int kFloatStackCount = 563; | |||
struct FloatStack { //history for GUI! | |||
int32_t start; | |||
float data[kFloatStackCount]; | |||
}; | |||
struct SharedMemData { | |||
float input[kFloatStackCount]; | |||
float output[kFloatStackCount]; | |||
struct FloatRMSStack { //rms, sr-dependent | |||
int32_t start; | |||
float* data; | |||
}; | |||
struct LookaheadStack { //lookahead buffer, sr-dependent | |||
int32_t start; | |||
float* data; | |||
}; | |||
struct SharedMemData { //history for the GUI ! | |||
float rms[kFloatStackCount]; | |||
float gainReduction[kFloatStackCount]; | |||
}; | |||
@@ -49,9 +60,6 @@ public: | |||
paramRatio, | |||
paramMakeup, | |||
paramMix, | |||
paramInput, | |||
paramOutput, | |||
paramGainReduction, | |||
paramCount | |||
}; | |||
@@ -92,7 +100,6 @@ protected: | |||
void d_initParameter(uint32_t index, Parameter& parameter) override; | |||
void d_initProgramName(uint32_t index, d_string& programName) override; | |||
void d_initStateKey(uint32_t, d_string&) override; | |||
// ------------------------------------------------------------------- | |||
// Internal data | |||
@@ -100,7 +107,6 @@ protected: | |||
float d_getParameterValue(uint32_t index) const override; | |||
void d_setParameterValue(uint32_t index, float value) override; | |||
void d_setProgram(uint32_t index) override; | |||
void d_setState(const char* key, const char* value) override; | |||
// ------------------------------------------------------------------- | |||
// Process | |||
@@ -114,20 +120,89 @@ protected: | |||
private: | |||
// params | |||
float attack, release, threshold, ratio, makeup, mix; | |||
float attackSamples, releaseSamples, makeupFloat; | |||
float balancer; | |||
float targetGR; | |||
float GR; | |||
SharedMemData history; | |||
float sum; | |||
float data; | |||
float difference; | |||
int w; //waveform plane size, size of the plane in pixels; | |||
int w2; //wavefowm array | |||
int h; //waveform plane height | |||
int x; //waveform plane positions | |||
int y; | |||
int dc; //0DC line y position | |||
int kFloatRMSStackCount; | |||
int kFloatLookaheadStackCount; | |||
float refreshSkip; | |||
int averageCounter; | |||
float inputMin, inputMax; | |||
float inputMax; | |||
FloatStack input, rms, gainReduction; | |||
struct FloatRMSStack RMSStack; | |||
struct LookaheadStack lookaheadStack; | |||
bool newRepaint; | |||
int repaintSkip; | |||
float fromDB(float gdb) { | |||
return (std::exp(gdb/20.f*std::log(10.f))); | |||
}; | |||
// this was unused | |||
// float averageInputs[150]; | |||
float toDB(float g) { | |||
return (20.f*std::log10(g)); | |||
} | |||
FloatStack input, output, gainReduction; | |||
float toIEC(float db) { | |||
float def = 0.0f; /* Meter deflection %age */ | |||
if (db < -70.0f) { | |||
def = 0.0f; | |||
} else if (db < -60.0f) { | |||
def = (db + 70.0f) * 0.25f; | |||
} else if (db < -50.0f) { | |||
def = (db + 60.0f) * 0.5f + 5.0f; | |||
} else if (db < -40.0f) { | |||
def = (db + 50.0f) * 0.75f + 7.5; | |||
} else if (db < -30.0f) { | |||
def = (db + 40.0f) * 1.5f + 15.0f; | |||
} else if (db < -20.0f) { | |||
def = (db + 30.0f) * 2.0f + 30.0f; | |||
} else if (db < 0.0f) { | |||
def = (db + 20.0f) * 2.5f + 50.0f; | |||
} else { | |||
def = 100.0f; | |||
} | |||
return (def * 2.0f); | |||
} | |||
shm_t shm; | |||
SharedMemData* shmData; | |||
bool isNan(float& value ) { | |||
if (((*(uint32_t *) &value) & 0x7fffffff) > 0x7f800000) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
void initShm(const char* shmKey); | |||
void closeShm(); | |||
void sanitizeDenormal(float& value) { | |||
if (isNan(value)) { | |||
//std::printf("Booo!\n"); | |||
value = 0.f; | |||
} | |||
} | |||
public: | |||
//methods | |||
float getRMSHistory(int n); | |||
float getGainReductionHistory(int n); | |||
bool repaintNeeded(); | |||
}; | |||
// ----------------------------------------------------------------------- | |||
@@ -28,8 +28,7 @@ START_NAMESPACE_DISTRHO | |||
PowerJuiceUI::PowerJuiceUI() | |||
: UI(), | |||
fAboutWindow(this), | |||
shmData(nullptr) | |||
fAboutWindow(this) | |||
{ | |||
// background | |||
fImgBackground = Image(PowerJuiceArtwork::backgroundData, PowerJuiceArtwork::backgroundWidth, PowerJuiceArtwork::backgroundHeight, GL_BGR); | |||
@@ -97,11 +96,7 @@ PowerJuiceUI::PowerJuiceUI() | |||
fButtonAbout->setPos(502, 17); | |||
fButtonAbout->setCallback(this); | |||
// init shm vars | |||
carla_shm_init(shm); | |||
shmData = nullptr; | |||
fFirstDisplay = true; | |||
} | |||
PowerJuiceUI::~PowerJuiceUI() | |||
@@ -113,8 +108,6 @@ PowerJuiceUI::~PowerJuiceUI() | |||
delete fKnobMakeup; | |||
delete fKnobMix; | |||
delete fButtonAbout; | |||
closeShm(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -159,10 +152,6 @@ void PowerJuiceUI::d_programChanged(uint32_t index) | |||
fKnobMix->setValue(1.0f); | |||
} | |||
void PowerJuiceUI::d_stateChanged(const char*, const char*) | |||
{ | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Widget Callbacks | |||
@@ -208,7 +197,7 @@ void PowerJuiceUI::imageKnobDragFinished(ImageKnob* knob) | |||
void PowerJuiceUI::imageKnobValueChanged(ImageKnob* knob, float value) | |||
{ | |||
if (knob == fKnobAttack) | |||
if (knob == fKnobAttack) | |||
d_setParameterValue(PowerJuicePlugin::paramAttack, value); | |||
else if (knob == fKnobRelease) | |||
d_setParameterValue(PowerJuicePlugin::paramRelease, value); | |||
@@ -224,106 +213,97 @@ void PowerJuiceUI::imageKnobValueChanged(ImageKnob* knob, float value) | |||
} | |||
void PowerJuiceUI::d_uiIdle() { | |||
repaint(); | |||
dsp = (PowerJuicePlugin*)d_getPluginInstancePointer(); | |||
if (dsp -> repaintNeeded()) { | |||
repaint(); | |||
} else { | |||
} | |||
} | |||
void PowerJuiceUI::onDisplay() | |||
{ | |||
if (fFirstDisplay) | |||
{ | |||
initShm(); | |||
fFirstDisplay = false; | |||
} | |||
fImgBackground.draw(); | |||
if (shmData == nullptr) | |||
//dsp side connection | |||
dsp = (PowerJuicePlugin*)d_getPluginInstancePointer(); | |||
if (dsp == nullptr) | |||
return; | |||
int w = 563; //waveform plane size, size of the plane in pixels; | |||
int w2 = 1126; //wavefowm array | |||
int h = 60; //waveform plane height | |||
int x = 28; //waveform plane positions | |||
int y = 51; | |||
int h = 121; //waveform plane height | |||
int x = 27; //waveform plane positions | |||
int y = 53; | |||
int dc = 113; //0DC line y position | |||
//draw waveform | |||
for (int i=0; i<w2; i+=2) { | |||
//glEnable(GL_BLEND); | |||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
//glEnable(GL_LINE_SMOOTH); | |||
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); | |||
glColor4f(0.0f, 1.0f, 0.0f, 1.0f); | |||
glLineWidth(1.0f); | |||
glBegin(GL_LINES); | |||
glVertex2i(x+(i/2), shmData->input[i]*h+dc); | |||
glVertex2i(x+(i/2), shmData->input[i+1]*h+dc); | |||
glEnd(); | |||
// reset color | |||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||
} | |||
//draw shits | |||
} | |||
glEnable(GL_BLEND); | |||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
glEnable(GL_LINE_SMOOTH); | |||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); | |||
void PowerJuiceUI::onClose() | |||
{ | |||
// tell DSP to stop sending SHM data | |||
d_setState("shmKey", ""); | |||
} | |||
void PowerJuiceUI::initShm() | |||
{ | |||
// generate a random key | |||
static const char charSet[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |||
static const int charSetLen = sizeof(charSet) - 1; // -1 to avoid trailing '\0' | |||
char shmKey[24+1]; | |||
shmKey[24] = '\0'; | |||
std::srand(std::time(nullptr)); | |||
float thresholdPosition = (-toIEC(fKnobThreshold->getValue()))/200*h+h+y; | |||
for (int i=0; i<24; ++i) | |||
shmKey[i] = charSet[std::rand() % charSetLen]; | |||
// create shared memory | |||
shm = carla_shm_create(shmKey); | |||
//draw waveform | |||
/* | |||
glColor4f(0.0f, 1.0f, 0.0f, 0.4f); | |||
glLineWidth(1.2f); | |||
for (int i=0; i<w; i++) { | |||
if (! carla_is_shm_valid(shm)) | |||
{ | |||
carla_stderr2("Failed to created shared memory!"); | |||
return; | |||
glBegin(GL_LINES); | |||
glVertex2i(x+i, -toIEC(shmData->input[i])/200*h+h+y); | |||
glVertex2i(x+i, y+h); | |||
glEnd(); | |||
} | |||
if (! carla_shm_map<SharedMemData>(shm, shmData)) | |||
{ | |||
carla_stderr2("Failed to map shared memory!"); | |||
return; | |||
*/ | |||
//draw RMS | |||
glColor4f(0.0f, 0.0f, 1.0f, 1.0f); | |||
glLineWidth(2.0f); | |||
glBegin(GL_LINE_STRIP); | |||
for (int i=2; i<w; i++) { | |||
float value = dsp->getRMSHistory(i); | |||
if (value<thresholdPosition) { | |||
glColor4f(0.0f, 0.5f, 0.0f, 1.0f); | |||
} else { | |||
glColor4f(0.0f, 0.5f, 0.2f, 1.0f); | |||
} | |||
glVertex2i(x+i, value); | |||
} | |||
std::memset(shmData, 0, sizeof(SharedMemData)); | |||
// tell DSP to use this key for SHM | |||
carla_stdout("Sending shmKey %s", shmKey); | |||
d_setState("shmKey", shmKey); | |||
} | |||
void PowerJuiceUI::closeShm() | |||
{ | |||
fFirstDisplay = true; | |||
if (! carla_is_shm_valid(shm)) | |||
return; | |||
if (shmData != nullptr) | |||
{ | |||
carla_shm_unmap<SharedMemData>(shm, shmData); | |||
shmData = nullptr; | |||
glEnd(); | |||
//draw gain reduction | |||
glColor4f(1.0f, 1.0f, 1.0f, 0.3f); | |||
glLineWidth(3.0f); | |||
glBegin(GL_LINES); | |||
for (int i=2; i<w; i++) { | |||
glColor4f(1.0f, 1.0f, 1.0f, 0.3f); | |||
float value = dsp->getGainReductionHistory(i); | |||
glVertex2i(x+i, value); | |||
glVertex2i(x+i, y); | |||
value = dsp->getRMSHistory(i); | |||
glColor4f(0.0f, 0.5f, 0.2f, 0.1f); | |||
glVertex2i(x+i, value); | |||
glVertex2i(x+i, y+h); | |||
} | |||
carla_shm_close(shm); | |||
glEnd(); | |||
//draw Threshold | |||
glLineWidth(2.0f); | |||
glColor4f(0.4f, 0.4f, 1.0f, 0.8f); | |||
//float thresholdPosition = ((60-fKnobThreshold->getValue())/60); | |||
glBegin(GL_LINES); | |||
glVertex2i(x, thresholdPosition); | |||
glVertex2i(x+w, thresholdPosition); | |||
glEnd(); | |||
// reset color | |||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -28,6 +28,8 @@ | |||
#include "PowerJuiceArtwork.hpp" | |||
#include "PowerJuicePlugin.hpp" | |||
#include <cmath> | |||
using DGL::Image; | |||
using DGL::ImageAboutWindow; | |||
using DGL::ImageButton; | |||
@@ -64,7 +66,6 @@ protected: | |||
void d_parameterChanged(uint32_t index, float value) override; | |||
void d_programChanged(uint32_t index) override; | |||
void d_stateChanged(const char*, const char*) override; | |||
// ------------------------------------------------------------------- | |||
// UI Callbacks | |||
@@ -79,7 +80,6 @@ protected: | |||
void imageKnobDragFinished(ImageKnob* knob) override; | |||
void imageKnobValueChanged(ImageKnob* knob, float value) override; | |||
void onDisplay() override; | |||
void onClose() override; | |||
private: | |||
Image fImgBackground; | |||
@@ -93,12 +93,39 @@ private: | |||
ImageKnob* fKnobMix; | |||
ImageButton* fButtonAbout; | |||
shm_t shm; | |||
SharedMemData* shmData; | |||
PowerJuicePlugin* dsp; | |||
float fromDB(float gdb) { | |||
return (std::exp(gdb/20.f*std::log(10.f))); | |||
}; | |||
bool fFirstDisplay; | |||
void initShm(); | |||
void closeShm(); | |||
float toDB(float g) { | |||
return (20.f*std::log10(g)); | |||
} | |||
float toIEC(float db) { | |||
float def = 0.0f; /* Meter deflection %age */ | |||
if (db < -70.0f) { | |||
def = 0.0f; | |||
} else if (db < -60.0f) { | |||
def = (db + 70.0f) * 0.25f; | |||
} else if (db < -50.0f) { | |||
def = (db + 60.0f) * 0.5f + 5.0f; | |||
} else if (db < -40.0f) { | |||
def = (db + 50.0f) * 0.75f + 7.5; | |||
} else if (db < -30.0f) { | |||
def = (db + 40.0f) * 1.5f + 15.0f; | |||
} else if (db < -20.0f) { | |||
def = (db + 30.0f) * 2.0f + 30.0f; | |||
} else if (db < 0.0f) { | |||
def = (db + 20.0f) * 2.5f + 50.0f; | |||
} else { | |||
def = 100.0f; | |||
} | |||
return (def * 2.0f); | |||
} | |||
}; | |||
// ----------------------------------------------------------------------- | |||