Browse Source

Update PowerJuice plugin

tags/1.9.4
falkTX 10 years ago
parent
commit
6451395560
7 changed files with 3577 additions and 3421 deletions
  1. +2
    -2
      source/modules/native-plugins/_all.c
  2. +4
    -1
      source/modules/native-plugins/powerjuice/DistrhoPluginInfo.h
  3. +3214
    -3214
      source/modules/native-plugins/powerjuice/PowerJuiceArtwork.cpp
  4. +155
    -84
      source/modules/native-plugins/powerjuice/PowerJuicePlugin.cpp
  5. +94
    -19
      source/modules/native-plugins/powerjuice/PowerJuicePlugin.hpp
  6. +74
    -94
      source/modules/native-plugins/powerjuice/PowerJuiceUI.cpp
  7. +34
    -7
      source/modules/native-plugins/powerjuice/PowerJuiceUI.hpp

+ 2
- 2
source/modules/native-plugins/_all.c View File

@@ -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();


+ 4
- 1
source/modules/native-plugins/powerjuice/DistrhoPluginInfo.h View File

@@ -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

+ 3214
- 3214
source/modules/native-plugins/powerjuice/PowerJuiceArtwork.cpp
File diff suppressed because it is too large
View File


+ 155
- 84
source/modules/native-plugins/powerjuice/PowerJuicePlugin.cpp View File

@@ -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);
}
// -----------------------------------------------------------------------


+ 94
- 19
source/modules/native-plugins/powerjuice/PowerJuicePlugin.hpp View File

@@ -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();
};
// -----------------------------------------------------------------------


+ 74
- 94
source/modules/native-plugins/powerjuice/PowerJuiceUI.cpp View File

@@ -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);
}

// -----------------------------------------------------------------------


+ 34
- 7
source/modules/native-plugins/powerjuice/PowerJuiceUI.hpp View File

@@ -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);
}
};

// -----------------------------------------------------------------------


Loading…
Cancel
Save