@@ -533,7 +533,7 @@ public: | |||
// found, set value | |||
stateValue = &state[i+1]; | |||
setSharedState(stateKey, stateValue); | |||
setStateFromUi(stateKey, stateValue); | |||
if (fVstUi != nullptr) | |||
fVstUi->setStateFromPlugin(stateKey, stateValue); | |||
@@ -91,6 +91,7 @@ OBJS += \ | |||
# distrho-stereoenhancer.cpp.o | |||
OBJS += \ | |||
distrho-powerjuice.cpp.o \ | |||
distrho-segmentjuice.cpp.o \ | |||
distrho-vectorjuice.cpp.o \ | |||
distrho-wobblejuice.cpp.o | |||
@@ -233,6 +234,9 @@ distrho-pingpongpan.cpp.o: distrho-pingpongpan.cpp pingpongpan/*.cpp pingpongpan | |||
distrho-stereoenhancer.cpp.o: distrho-stereoenhancer.cpp stereoenhancer/*.cpp stereoenhancer/*.h stereoenhancer/*.hpp ../distrho/* $(CXXDEPS) | |||
$(CXX) $< $(BUILD_CXX_FLAGS) -I../dgl -Istereoenhancer -DDISTRHO_NAMESPACE=DISTRHO_StereoEnhancer -c -o $@ | |||
distrho-powerjuice.cpp.o: distrho-powerjuice.cpp powerjuice/*.cpp powerjuice/*.h powerjuice/*.hpp ../distrho/* $(CXXDEPS) | |||
$(CXX) $< $(BUILD_CXX_FLAGS) -I../dgl -Ipowerjuice -DDISTRHO_NAMESPACE=DISTRHO_PowerJuice -c -o $@ | |||
distrho-segmentjuice.cpp.o: distrho-segmentjuice.cpp segmentjuice/*.cpp segmentjuice/*.h segmentjuice/*.hpp segmentjuice/*.hxx ../distrho/* $(CXXDEPS) | |||
$(CXX) $< $(BUILD_CXX_FLAGS) -I../dgl -Isegmentjuice -DDISTRHO_NAMESPACE=DISTRHO_SegmentJuice -c -o $@ | |||
@@ -42,6 +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_segmentjuice(); | |||
extern void carla_register_native_plugin_vectorjuice(); | |||
extern void carla_register_native_plugin_wobblejuice(); | |||
@@ -99,6 +100,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_segmentjuice(); | |||
carla_register_native_plugin_vectorjuice(); | |||
carla_register_native_plugin_wobblejuice(); | |||
@@ -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 "PowerJuice" | |||
#define DISTRHO_PLUGIN_HAS_UI 1 | |||
#define DISTRHO_PLUGIN_IS_SYNTH 0 | |||
#define DISTRHO_PLUGIN_NUM_INPUTS 1 | |||
#define DISTRHO_PLUGIN_NUM_OUTPUTS 1 | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
#define DISTRHO_PLUGIN_WANT_STATE 1 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
#define DISTRHO_PLUGIN_URI "urn:distrho:PowerJuice" | |||
#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED |
@@ -0,0 +1,35 @@ | |||
/* (Auto-generated binary data file). */ | |||
#ifndef BINARY_POWERJUICEARTWORK_HPP | |||
#define BINARY_POWERJUICEARTWORK_HPP | |||
namespace PowerJuiceArtwork | |||
{ | |||
extern const char* aboutData; | |||
const unsigned int aboutDataSize = 240000; | |||
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 = 571956; | |||
const unsigned int backgroundWidth = 619; | |||
const unsigned int backgroundHeight = 308; | |||
extern const char* knobData; | |||
const unsigned int knobDataSize = 10404; | |||
const unsigned int knobWidth = 51; | |||
const unsigned int knobHeight = 51; | |||
} | |||
#endif // BINARY_POWERJUICEARTWORK_HPP | |||
@@ -0,0 +1,308 @@ | |||
/* | |||
* Power 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 "PowerJuicePlugin.hpp" | |||
//#include <cstring> | |||
#include <cstdlib> | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
PowerJuicePlugin::PowerJuicePlugin() | |||
: Plugin(paramCount, 1, 0) // 1 program, 0 states | |||
{ | |||
// set default values | |||
d_setProgram(0); | |||
// init shm vars | |||
carla_shm_init(shm); | |||
shmData = nullptr; | |||
// reset | |||
d_deactivate(); | |||
} | |||
PowerJuicePlugin::~PowerJuicePlugin() | |||
{ | |||
closeShm(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Init | |||
void PowerJuicePlugin::d_initParameter(uint32_t index, Parameter& parameter) | |||
{ | |||
switch (index) | |||
{ | |||
case paramAttack: | |||
parameter.hints = PARAMETER_IS_AUTOMABLE; | |||
parameter.name = "Attack"; | |||
parameter.symbol = "att"; | |||
parameter.unit = "ms"; | |||
parameter.ranges.def = 20.0f; | |||
parameter.ranges.min = 0.1f; | |||
parameter.ranges.max = 1000.0f; | |||
break; | |||
case paramRelease: | |||
parameter.hints = PARAMETER_IS_AUTOMABLE; | |||
parameter.name = "Release"; | |||
parameter.symbol = "rel"; | |||
parameter.unit = "ms"; | |||
parameter.ranges.def = 200.0f; | |||
parameter.ranges.min = 0.1f; | |||
parameter.ranges.max = 1000.0f; | |||
break; | |||
case paramThreshold: | |||
parameter.hints = PARAMETER_IS_AUTOMABLE; | |||
parameter.name = "Threshold"; | |||
parameter.symbol = "thr"; | |||
parameter.unit = "dB"; | |||
parameter.ranges.def = 0.0f; | |||
parameter.ranges.min = -60.0f; | |||
parameter.ranges.max = 0.0f; | |||
break; | |||
case paramRatio: | |||
parameter.hints = PARAMETER_IS_AUTOMABLE; | |||
parameter.name = "Ratio"; | |||
parameter.symbol = "rat"; | |||
parameter.unit = ""; | |||
parameter.ranges.def = 1.0f; | |||
parameter.ranges.min = 1.0f; | |||
parameter.ranges.max = 10.0f; | |||
break; | |||
case paramMakeup: | |||
parameter.hints = PARAMETER_IS_AUTOMABLE; | |||
parameter.name = "Make-Up"; | |||
parameter.symbol = "mak"; | |||
parameter.unit = ""; | |||
parameter.ranges.def = 0.0f; | |||
parameter.ranges.min = 0.0f; | |||
parameter.ranges.max = 20.0f; | |||
break; | |||
case paramMix: | |||
parameter.hints = PARAMETER_IS_AUTOMABLE; | |||
parameter.name = "Mix"; | |||
parameter.symbol = "Mix"; | |||
parameter.unit = ""; | |||
parameter.ranges.def = 1.0f; | |||
parameter.ranges.min = 0.0f; | |||
parameter.ranges.max = 1.0f; | |||
break; | |||
} | |||
} | |||
void PowerJuicePlugin::d_initProgramName(uint32_t index, d_string& programName) | |||
{ | |||
if (index != 0) | |||
return; | |||
programName = "Default"; | |||
} | |||
void PowerJuicePlugin::d_initStateKey(uint32_t /*index*/, d_string& /*key*/) | |||
{ | |||
/* | |||
if (index != 0) | |||
return; | |||
key = "shmKey"; | |||
*/ | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Internal data | |||
float PowerJuicePlugin::d_getParameterValue(uint32_t index) const | |||
{ | |||
switch (index) | |||
{ | |||
case paramAttack: | |||
return attack; | |||
case paramRelease: | |||
return release; | |||
case paramThreshold: | |||
return threshold; | |||
case paramRatio: | |||
return ratio; | |||
case paramMakeup: | |||
return makeup; | |||
case paramMix: | |||
return mix; | |||
default: | |||
return 0.0f; | |||
} | |||
} | |||
void PowerJuicePlugin::d_setParameterValue(uint32_t index, float value) | |||
{ | |||
switch (index) | |||
{ | |||
case paramAttack: | |||
attack = value; | |||
break; | |||
case paramRelease: | |||
release = value; | |||
break; | |||
case paramThreshold: | |||
threshold = value; | |||
break; | |||
case paramRatio: | |||
ratio = value; | |||
break; | |||
case paramMakeup: | |||
makeup = value; | |||
break; | |||
case paramMix: | |||
mix = value; | |||
break; | |||
} | |||
} | |||
void PowerJuicePlugin::d_setProgram(uint32_t index) | |||
{ | |||
if (index != 0) | |||
return; | |||
/* Default parameter values */ | |||
attack = 20.0f; | |||
release = 200.0f; | |||
threshold = 0.0f; | |||
ratio = 1.0f; | |||
makeup = 0.0f; | |||
mix = 1.0f; | |||
/* Default variable values */ | |||
averageCounter = 0; | |||
inputMin = 0.0f; | |||
inputMax = 0.0f; | |||
input.start = 0; | |||
output.start = 0; | |||
gainReduction.start = 0; | |||
std::memset(input.data, 0, sizeof(float)*kFloatStackCount); | |||
std::memset(output.data, 0, sizeof(float)*kFloatStackCount); | |||
std::memset(gainReduction.data, 0, sizeof(float)*kFloatStackCount); | |||
d_activate(); | |||
} | |||
void PowerJuicePlugin::d_setState(const char* key, const char* value) | |||
{ | |||
if (std::strcmp(key, "shmKey") != 0) | |||
return; | |||
if (value[0] == '\0') | |||
{ | |||
carla_stdout("Shm closed"); | |||
return closeShm(); | |||
} | |||
carla_stdout("Got shmKey => %s", value); | |||
initShm(value); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Process | |||
void PowerJuicePlugin::d_activate() | |||
{ | |||
} | |||
void PowerJuicePlugin::d_deactivate() | |||
{ | |||
// all values to zero | |||
} | |||
void PowerJuicePlugin::d_run(float** inputs, float** /*outputs*/, uint32_t frames) | |||
{ | |||
float* in = inputs[0]; | |||
//float* out = outputs[0]; | |||
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]; | |||
} | |||
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]; | |||
} | |||
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; | |||
} | |||
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); | |||
} | |||
// ----------------------------------------------------------------------- | |||
Plugin* createPlugin() | |||
{ | |||
return new PowerJuicePlugin(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DISTRHO |
@@ -0,0 +1,137 @@ | |||
/* | |||
* Power 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 POWERJUICEPLUGIN_HPP_INCLUDED | |||
#define POWERJUICEPLUGIN_HPP_INCLUDED | |||
#include "DistrhoPlugin.hpp" | |||
#include "carla/CarlaShmUtils.hpp" | |||
static const int kFloatStackCount = 1126; | |||
struct FloatStack { | |||
int32_t start; | |||
float data[kFloatStackCount]; | |||
}; | |||
struct SharedMemData { | |||
float input[kFloatStackCount]; | |||
float output[kFloatStackCount]; | |||
float gainReduction[kFloatStackCount]; | |||
}; | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
class PowerJuicePlugin : public Plugin | |||
{ | |||
public: | |||
enum Parameters | |||
{ | |||
paramAttack = 0, | |||
paramRelease, | |||
paramThreshold, | |||
paramRatio, | |||
paramMakeup, | |||
paramMix, | |||
paramInput, | |||
paramOutput, | |||
paramGainReduction, | |||
paramCount | |||
}; | |||
PowerJuicePlugin(); | |||
~PowerJuicePlugin() override; | |||
protected: | |||
// ------------------------------------------------------------------- | |||
// Information | |||
const char* d_getLabel() const noexcept override | |||
{ | |||
return "PowerJuice"; | |||
} | |||
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('P', 'w', 'r', 'J'); | |||
} | |||
// ------------------------------------------------------------------- | |||
// Init | |||
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 | |||
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 | |||
void d_activate() override; | |||
void d_deactivate() override; | |||
void d_run(float** inputs, float** outputs, uint32_t frames) override; | |||
// ------------------------------------------------------------------- | |||
private: | |||
// params | |||
float attack, release, threshold, ratio, makeup, mix; | |||
int averageCounter; | |||
float inputMin, inputMax; | |||
// this was unused | |||
// float averageInputs[150]; | |||
FloatStack input, output, gainReduction; | |||
shm_t shm; | |||
SharedMemData* shmData; | |||
void initShm(const char* shmKey); | |||
void closeShm(); | |||
}; | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DISTRHO | |||
#endif // POWERJUICE_HPP_INCLUDED |
@@ -0,0 +1,338 @@ | |||
/* | |||
* Power 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 "PowerJuiceUI.hpp" | |||
#include <cstdlib> | |||
#include <ctime> | |||
using DGL::Point; | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
PowerJuiceUI::PowerJuiceUI() | |||
: UI(), | |||
fAboutWindow(this), | |||
shmData(nullptr) | |||
{ | |||
// background | |||
fImgBackground = Image(PowerJuiceArtwork::backgroundData, PowerJuiceArtwork::backgroundWidth, PowerJuiceArtwork::backgroundHeight, GL_BGR); | |||
// about | |||
Image imageAbout(PowerJuiceArtwork::aboutData, PowerJuiceArtwork::aboutWidth, PowerJuiceArtwork::aboutHeight, GL_BGR); | |||
fAboutWindow.setImage(imageAbout); | |||
// knobs | |||
Image knobImage(PowerJuiceArtwork::knobData, PowerJuiceArtwork::knobWidth, PowerJuiceArtwork::knobHeight); | |||
// knob Attack | |||
fKnobAttack = new ImageKnob(this, knobImage); | |||
fKnobAttack->setPos(37, 213); | |||
fKnobAttack->setRange(0.1f, 1000.0f); | |||
fKnobAttack->setStep(0.1f); | |||
fKnobAttack->setValue(20.0f); | |||
fKnobAttack->setRotationAngle(270); | |||
fKnobAttack->setCallback(this); | |||
// knob Release | |||
fKnobRelease = new ImageKnob(this, knobImage); | |||
fKnobRelease->setPos(136, 213); | |||
fKnobRelease->setRange(0.1f, 1000.0f); | |||
fKnobRelease->setValue(0.1f); | |||
fKnobRelease->setRotationAngle(270); | |||
fKnobRelease->setCallback(this); | |||
// knob Threshold | |||
fKnobThreshold = new ImageKnob(this, knobImage); | |||
fKnobThreshold->setPos(235, 213); | |||
fKnobThreshold->setRange(-60.0f, 0.0f); | |||
fKnobThreshold->setValue(0.0f); | |||
fKnobThreshold->setRotationAngle(270); | |||
fKnobThreshold->setCallback(this); | |||
// knob Ratio | |||
fKnobRatio = new ImageKnob(this, knobImage); | |||
fKnobRatio->setPos(334, 213); | |||
fKnobRatio->setRange(1.0f, 10.0f); | |||
fKnobRatio->setValue(1.0f); | |||
fKnobRatio->setRotationAngle(270); | |||
fKnobRatio->setCallback(this); | |||
// knob Make-Up | |||
fKnobMakeup = new ImageKnob(this, knobImage); | |||
fKnobMakeup->setPos(433, 213); | |||
fKnobMakeup->setRange(0.0f, 20.0f); | |||
fKnobMakeup->setValue(0.0f); | |||
fKnobMakeup->setRotationAngle(270); | |||
fKnobMakeup->setCallback(this); | |||
// knob Mix | |||
fKnobMix = new ImageKnob(this, knobImage); | |||
fKnobMix->setPos(532, 213); | |||
fKnobMix->setRange(0.0f, 1.0f); | |||
fKnobMix->setValue(1.0f); | |||
fKnobMix->setRotationAngle(270); | |||
fKnobMix->setCallback(this); | |||
// about button | |||
Image aboutImageNormal(PowerJuiceArtwork::aboutButtonNormalData, PowerJuiceArtwork::aboutButtonNormalWidth, PowerJuiceArtwork::aboutButtonNormalHeight); | |||
Image aboutImageHover(PowerJuiceArtwork::aboutButtonHoverData, PowerJuiceArtwork::aboutButtonHoverWidth, PowerJuiceArtwork::aboutButtonHoverHeight); | |||
fButtonAbout = new ImageButton(this, aboutImageNormal, aboutImageHover, aboutImageHover); | |||
fButtonAbout->setPos(502, 17); | |||
fButtonAbout->setCallback(this); | |||
// init shm vars | |||
carla_shm_init(shm); | |||
shmData = nullptr; | |||
fFirstDisplay = true; | |||
} | |||
PowerJuiceUI::~PowerJuiceUI() | |||
{ | |||
delete fKnobAttack; | |||
delete fKnobRelease; | |||
delete fKnobThreshold; | |||
delete fKnobRatio; | |||
delete fKnobMakeup; | |||
delete fKnobMix; | |||
delete fButtonAbout; | |||
closeShm(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// DSP Callbacks | |||
void PowerJuiceUI::d_parameterChanged(uint32_t index, float value) | |||
{ | |||
switch (index) | |||
{ | |||
case PowerJuicePlugin::paramAttack: | |||
fKnobAttack->setValue(value); | |||
break; | |||
case PowerJuicePlugin::paramRelease: | |||
fKnobRelease->setValue(value); | |||
break; | |||
case PowerJuicePlugin::paramThreshold: | |||
fKnobThreshold->setValue(value); | |||
break; | |||
case PowerJuicePlugin::paramRatio: | |||
fKnobRatio->setValue(value); | |||
break; | |||
case PowerJuicePlugin::paramMakeup: | |||
fKnobMakeup->setValue(value); | |||
break; | |||
case PowerJuicePlugin::paramMix: | |||
fKnobMix->setValue(value); | |||
break; | |||
} | |||
} | |||
void PowerJuiceUI::d_programChanged(uint32_t index) | |||
{ | |||
if (index != 0) | |||
return; | |||
// Default values | |||
fKnobAttack->setValue(20.0f); | |||
fKnobRelease->setValue(200.0f); | |||
fKnobThreshold->setValue(0.0f); | |||
fKnobRatio->setValue(1.0f); | |||
fKnobMakeup->setValue(0.0f); | |||
fKnobMix->setValue(1.0f); | |||
} | |||
void PowerJuiceUI::d_stateChanged(const char*, const char*) | |||
{ | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Widget Callbacks | |||
void PowerJuiceUI::imageButtonClicked(ImageButton* button, int) | |||
{ | |||
if (button != fButtonAbout) | |||
return; | |||
fAboutWindow.exec(); | |||
} | |||
void PowerJuiceUI::imageKnobDragStarted(ImageKnob* knob) | |||
{ | |||
if (knob == fKnobAttack) | |||
d_editParameter(PowerJuicePlugin::paramAttack, true); | |||
else if (knob == fKnobRelease) | |||
d_editParameter(PowerJuicePlugin::paramRelease, true); | |||
else if (knob == fKnobThreshold) | |||
d_editParameter(PowerJuicePlugin::paramThreshold, true); | |||
else if (knob == fKnobRatio) | |||
d_editParameter(PowerJuicePlugin::paramRatio, true); | |||
else if (knob == fKnobMakeup) | |||
d_editParameter(PowerJuicePlugin::paramMakeup, true); | |||
else if (knob == fKnobMix) | |||
d_editParameter(PowerJuicePlugin::paramMix, true); | |||
} | |||
void PowerJuiceUI::imageKnobDragFinished(ImageKnob* knob) | |||
{ | |||
if (knob == fKnobAttack) | |||
d_editParameter(PowerJuicePlugin::paramAttack, false); | |||
else if (knob == fKnobRelease) | |||
d_editParameter(PowerJuicePlugin::paramRelease, false); | |||
else if (knob == fKnobThreshold) | |||
d_editParameter(PowerJuicePlugin::paramThreshold, false); | |||
else if (knob == fKnobRatio) | |||
d_editParameter(PowerJuicePlugin::paramRatio, false); | |||
else if (knob == fKnobMakeup) | |||
d_editParameter(PowerJuicePlugin::paramMakeup, false); | |||
else if (knob == fKnobMix) | |||
d_editParameter(PowerJuicePlugin::paramMix, false); | |||
} | |||
void PowerJuiceUI::imageKnobValueChanged(ImageKnob* knob, float value) | |||
{ | |||
if (knob == fKnobAttack) | |||
d_setParameterValue(PowerJuicePlugin::paramAttack, value); | |||
else if (knob == fKnobRelease) | |||
d_setParameterValue(PowerJuicePlugin::paramRelease, value); | |||
else if (knob == fKnobThreshold) | |||
d_setParameterValue(PowerJuicePlugin::paramThreshold, value); | |||
else if (knob == fKnobRatio) | |||
d_setParameterValue(PowerJuicePlugin::paramRatio, value); | |||
else if (knob == fKnobMakeup) | |||
d_setParameterValue(PowerJuicePlugin::paramMakeup, value); | |||
else if (knob == fKnobMix) | |||
d_setParameterValue(PowerJuicePlugin::paramMix, value); | |||
} | |||
void PowerJuiceUI::d_uiIdle() { | |||
repaint(); | |||
} | |||
void PowerJuiceUI::onDisplay() | |||
{ | |||
if (fFirstDisplay) | |||
{ | |||
initShm(); | |||
fFirstDisplay = false; | |||
} | |||
fImgBackground.draw(); | |||
if (shmData == 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 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 | |||
} | |||
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)); | |||
for (int i=0; i<24; ++i) | |||
shmKey[i] = charSet[std::rand() % charSetLen]; | |||
// create shared memory | |||
shm = carla_shm_create(shmKey); | |||
if (! carla_is_shm_valid(shm)) | |||
{ | |||
carla_stderr2("Failed to created shared memory!"); | |||
return; | |||
} | |||
if (! carla_shm_map<SharedMemData>(shm, shmData)) | |||
{ | |||
carla_stderr2("Failed to map shared memory!"); | |||
return; | |||
} | |||
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; | |||
} | |||
carla_shm_close(shm); | |||
} | |||
// ----------------------------------------------------------------------- | |||
UI* createUI() | |||
{ | |||
return new PowerJuiceUI(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DISTRHO |
@@ -0,0 +1,108 @@ | |||
/* | |||
* Power 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 POWERJUICEUI_HPP_INCLUDED | |||
#define POWERJUICEUI_HPP_INCLUDED | |||
#include "DistrhoUI.hpp" | |||
#include "ImageAboutWindow.hpp" | |||
#include "ImageButton.hpp" | |||
#include "ImageKnob.hpp" | |||
#include "ImageSlider.hpp" | |||
#include "PowerJuiceArtwork.hpp" | |||
#include "PowerJuicePlugin.hpp" | |||
using DGL::Image; | |||
using DGL::ImageAboutWindow; | |||
using DGL::ImageButton; | |||
using DGL::ImageKnob; | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
class PowerJuiceUI : public UI, | |||
public ImageButton::Callback, | |||
public ImageKnob::Callback | |||
{ | |||
public: | |||
PowerJuiceUI(); | |||
~PowerJuiceUI() override; | |||
protected: | |||
// ------------------------------------------------------------------- | |||
// Information | |||
unsigned int d_getWidth() const noexcept override | |||
{ | |||
return PowerJuiceArtwork::backgroundWidth; | |||
} | |||
unsigned int d_getHeight() const noexcept override | |||
{ | |||
return PowerJuiceArtwork::backgroundHeight; | |||
} | |||
// ------------------------------------------------------------------- | |||
// DSP Callbacks | |||
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 | |||
void d_uiIdle() 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; | |||
void onClose() override; | |||
private: | |||
Image fImgBackground; | |||
ImageAboutWindow fAboutWindow; | |||
ImageKnob* fKnobAttack; | |||
ImageKnob* fKnobRelease; | |||
ImageKnob* fKnobThreshold; | |||
ImageKnob* fKnobRatio; | |||
ImageKnob* fKnobMakeup; | |||
ImageKnob* fKnobMix; | |||
ImageButton* fButtonAbout; | |||
shm_t shm; | |||
SharedMemData* shmData; | |||
bool fFirstDisplay; | |||
void initShm(); | |||
void closeShm(); | |||
}; | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DISTRHO | |||
#endif // POWERJUICEUI_HPP_INCLUDED |
@@ -0,0 +1,144 @@ | |||
/* | |||
* Carla common defines | |||
* Copyright (C) 2011-2014 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. | |||
*/ | |||
#ifndef CARLA_DEFINES_HPP_INCLUDED | |||
#define CARLA_DEFINES_HPP_INCLUDED | |||
/* Set Version */ | |||
#define CARLA_VERSION_HEX 0x01093 | |||
#define CARLA_VERSION_STRING "1.9.3 (2.0-beta1)" | |||
/* Define various string format types */ | |||
#if defined(CARLA_OS_WIN64) | |||
# define P_INT64 "%I64i" | |||
# define P_INTPTR "%I64i" | |||
# define P_UINTPTR "%I64x" | |||
# define P_SIZE "%I64u" | |||
#elif defined(CARLA_OS_WIN32) | |||
# define P_INT64 "%I64i" | |||
# define P_INTPTR "%i" | |||
# define P_UINTPTR "%x" | |||
# define P_SIZE "%u" | |||
#elif defined(__WORDSIZE) && __WORDSIZE == 64 | |||
# define P_INT64 "%li" | |||
# define P_INTPTR "%li" | |||
# define P_UINTPTR "%lx" | |||
# define P_SIZE "%lu" | |||
#else | |||
# define P_INT64 "%lli" | |||
# define P_INTPTR "%i" | |||
# define P_UINTPTR "%x" | |||
# define P_SIZE "%u" | |||
#endif | |||
/* Define BINARY_NATIVE */ | |||
#if defined(CARLA_OS_HAIKU) || defined(CARLA_OS_UNIX) | |||
# if defined (__LP64__) || defined (_LP64) | |||
# define BINARY_NATIVE BINARY_POSIX64 | |||
# else | |||
# define BINARY_NATIVE BINARY_POSIX32 | |||
# endif | |||
#elif defined(CARLA_OS_WIN) | |||
# ifdef CARLA_OS_WIN64 | |||
# define BINARY_NATIVE BINARY_WIN64 | |||
# else | |||
# define BINARY_NATIVE BINARY_WIN32 | |||
# endif | |||
#else | |||
# warning Unknown binary native | |||
# define BINARY_NATIVE BINARY_OTHER | |||
#endif | |||
/* Define CARLA_ASSERT* */ | |||
#if defined(CARLA_NO_ASSERTS) | |||
# define CARLA_ASSERT(cond) | |||
# define CARLA_ASSERT_INT(cond, value) | |||
# define CARLA_ASSERT_INT2(cond, v1, v2) | |||
#elif defined(NDEBUG) | |||
# define CARLA_ASSERT CARLA_SAFE_ASSERT | |||
# define CARLA_ASSERT_INT CARLA_SAFE_ASSERT_INT | |||
# define CARLA_ASSERT_INT2 CARLA_SAFE_ASSERT_INT2 | |||
#else | |||
# define CARLA_ASSERT(cond) assert(cond) | |||
# define CARLA_ASSERT_INT(cond, value) assert(cond) | |||
# define CARLA_ASSERT_INT2(cond, v1, v2) assert(cond) | |||
#endif | |||
/* Define CARLA_SAFE_EXCEPTION */ | |||
#define CARLA_SAFE_EXCEPTION(msg) catch(...) { carla_safe_exception(msg, __FILE__, __LINE__); } | |||
#define CARLA_SAFE_EXCEPTION_BREAK(msg) catch(...) { carla_safe_exception(msg, __FILE__, __LINE__); break; } | |||
#define CARLA_SAFE_EXCEPTION_CONTINUE(msg) catch(...) { carla_safe_exception(msg, __FILE__, __LINE__); continue; } | |||
#define CARLA_SAFE_EXCEPTION_RETURN(msg, ret) catch(...) { carla_safe_exception(msg, __FILE__, __LINE__); return ret; } | |||
/* Define CARLA_DECLARE_NON_COPY_CLASS */ | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# define CARLA_DECLARE_NON_COPY_CLASS(ClassName) \ | |||
private: \ | |||
ClassName(ClassName&) = delete; \ | |||
ClassName(const ClassName&) = delete; \ | |||
ClassName& operator=(ClassName&) = delete; \ | |||
ClassName& operator=(const ClassName&) = delete; | |||
#else | |||
# define CARLA_DECLARE_NON_COPY_CLASS(ClassName) \ | |||
private: \ | |||
ClassName(ClassName&); \ | |||
ClassName(const ClassName&); \ | |||
ClassName& operator=(ClassName&); \ | |||
ClassName& operator=(const ClassName&); | |||
#endif | |||
/* Define CARLA_DECLARE_NON_COPY_STRUCT */ | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# define CARLA_DECLARE_NON_COPY_STRUCT(StructName) \ | |||
StructName(StructName&) = delete; \ | |||
StructName(const StructName&) = delete; \ | |||
StructName& operator=(StructName&) = delete; \ | |||
StructName& operator=(const StructName&) = delete; | |||
#else | |||
# define CARLA_DECLARE_NON_COPY_STRUCT(StructName) | |||
#endif | |||
/* Define CARLA_PREVENT_HEAP_ALLOCATION */ | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# define CARLA_PREVENT_HEAP_ALLOCATION \ | |||
private: \ | |||
static void* operator new(size_t) = delete; \ | |||
static void operator delete(void*) = delete; | |||
#else | |||
# define CARLA_PREVENT_HEAP_ALLOCATION \ | |||
private: \ | |||
static void* operator new(size_t); \ | |||
static void operator delete(void*); | |||
#endif | |||
/* Define OS_SEP */ | |||
#ifdef CARLA_OS_WIN | |||
# define OS_SEP '\\' | |||
# define OS_SEP_STR "\\" | |||
#else | |||
# define OS_SEP '/' | |||
# define OS_SEP_STR "/" | |||
#endif | |||
/* Useful typedefs */ | |||
typedef unsigned char uchar; | |||
typedef unsigned long int ulong; | |||
typedef unsigned short int ushort; | |||
typedef unsigned int uint; | |||
#endif /* CARLA_DEFINES_HPP_INCLUDED */ |
@@ -0,0 +1,198 @@ | |||
/* | |||
* Carla shared memory utils | |||
* Copyright (C) 2013-2014 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. | |||
*/ | |||
#ifndef CARLA_SHM_UTILS_HPP_INCLUDED | |||
#define CARLA_SHM_UTILS_HPP_INCLUDED | |||
#include "CarlaUtils.hpp" | |||
#ifdef CARLA_OS_WIN | |||
struct shm_t { HANDLE shm; HANDLE map; }; | |||
#else | |||
# include <fcntl.h> | |||
# include <sys/mman.h> | |||
typedef int shm_t; | |||
#endif | |||
#ifdef CARLA_OS_WIN | |||
static shm_t gNullCarlaShm = { nullptr, nullptr }; | |||
#else | |||
static shm_t gNullCarlaShm = -1; | |||
#endif | |||
// ----------------------------------------------------------------------- | |||
// shared memory calls | |||
static inline | |||
bool carla_is_shm_valid(const shm_t& shm) noexcept | |||
{ | |||
#ifdef CARLA_OS_WIN | |||
return (shm.shm != nullptr && shm.shm != INVALID_HANDLE_VALUE); | |||
#else | |||
return (shm >= 0); | |||
#endif | |||
} | |||
static inline | |||
void carla_shm_init(shm_t& shm) noexcept | |||
{ | |||
#ifdef CARLA_OS_WIN | |||
shm.shm = nullptr; | |||
shm.map = nullptr; | |||
#else | |||
shm = -1; | |||
#endif | |||
} | |||
#ifdef CARLA_OS_WIN | |||
static inline | |||
shm_t carla_shm_create(const char* const name) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm); | |||
shm_t ret; | |||
ret.shm = nullptr; // TODO | |||
ret.map = nullptr; | |||
return ret; | |||
} | |||
static inline | |||
shm_t carla_shm_attach(const char* const name) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm); | |||
shm_t ret; | |||
ret.shm = CreateFileA(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); | |||
ret.map = nullptr; | |||
return ret; | |||
} | |||
#else | |||
static inline | |||
shm_t carla_shm_create(const char* const name) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm); | |||
return shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600); | |||
} | |||
static inline | |||
shm_t carla_shm_attach(const char* const name) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm); | |||
return shm_open(name, O_RDWR, 0); | |||
} | |||
#endif | |||
static inline | |||
void carla_shm_close(shm_t& shm) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm),); | |||
#ifdef CARLA_OS_WIN | |||
CARLA_SAFE_ASSERT(shm.map == nullptr); | |||
CloseHandle(shm.shm); | |||
shm.shm = nullptr; | |||
#else | |||
close(shm); | |||
shm = -1; | |||
#endif | |||
} | |||
static inline | |||
void* carla_shm_map(shm_t& shm, const size_t size) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm), nullptr); | |||
CARLA_SAFE_ASSERT_RETURN(size > 0, nullptr); | |||
#ifdef CARLA_OS_WIN | |||
CARLA_SAFE_ASSERT_RETURN(shm.map == nullptr, nullptr); | |||
HANDLE map = CreateFileMapping(shm.shm, NULL, PAGE_READWRITE, size, size, NULL); | |||
CARLA_SAFE_ASSERT_RETURN(map != nullptr, nullptr); | |||
HANDLE ptr = MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size); | |||
if (ptr == nullptr) | |||
{ | |||
CloseHandle(map); | |||
return nullptr; | |||
} | |||
shm.map = map; | |||
return ptr; | |||
#else | |||
if (ftruncate(shm, static_cast<off_t>(size)) != 0) | |||
return nullptr; | |||
return mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0); | |||
#endif | |||
} | |||
static inline | |||
void carla_shm_unmap(shm_t& shm, void* const ptr, const size_t size) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm),); | |||
CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,); | |||
CARLA_SAFE_ASSERT_RETURN(size > 0,); | |||
#ifdef CARLA_OS_WIN | |||
CARLA_SAFE_ASSERT_RETURN(shm.map != nullptr,); | |||
UnmapViewOfFile(ptr); | |||
CloseHandle(shm.map); | |||
shm.map = nullptr; | |||
return; | |||
// unused | |||
(void)size; | |||
#else | |||
munmap(ptr, size); | |||
return; | |||
// unused | |||
(void)shm; | |||
#endif | |||
} | |||
// ----------------------------------------------------------------------- | |||
// shared memory, templated calls | |||
template<typename T> | |||
static inline | |||
bool carla_shm_map(shm_t& shm, T*& value) | |||
{ | |||
value = (T*)carla_shm_map(shm, sizeof(T)); | |||
return (value != nullptr); | |||
} | |||
template<typename T> | |||
static inline | |||
void carla_shm_unmap(shm_t& shm, T*& value) | |||
{ | |||
carla_shm_unmap(shm, value, sizeof(T)); | |||
value = nullptr; | |||
} | |||
// ----------------------------------------------------------------------- | |||
#endif // CARLA_SHM_UTILS_HPP_INCLUDED |
@@ -0,0 +1,223 @@ | |||
/* | |||
* Carla common utils | |||
* Copyright (C) 2011-2014 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. | |||
*/ | |||
#ifndef CARLA_UTILS_HPP_INCLUDED | |||
#define CARLA_UTILS_HPP_INCLUDED | |||
// ----------------------------------------------------------------------- | |||
// defines | |||
/* Compatibility with non-clang compilers */ | |||
#ifndef __has_feature | |||
# define __has_feature(x) 0 | |||
#endif | |||
#ifndef __has_extension | |||
# define __has_extension __has_feature | |||
#endif | |||
/* Check OS */ | |||
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__) | |||
# define CARLA_OS_WIN64 | |||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) | |||
# define CARLA_OS_WIN32 | |||
#elif defined(__APPLE__) | |||
# define CARLA_OS_MAC | |||
#elif defined(__HAIKU__) | |||
# define CARLA_OS_HAIKU | |||
#elif defined(__linux__) || defined(__linux) | |||
# define CARLA_OS_LINUX | |||
#else | |||
# warning Unsupported platform! | |||
#endif | |||
#if defined(CARLA_OS_WIN32) || defined(CARLA_OS_WIN64) | |||
# define CARLA_OS_WIN | |||
#elif ! defined(CARLA_OS_HAIKU) | |||
# define CARLA_OS_UNIX | |||
#endif | |||
/* Check for C++11 support */ | |||
#if defined(HAVE_CPP11_SUPPORT) | |||
# define CARLA_PROPER_CPP11_SUPPORT | |||
#elif defined(__cplusplus) | |||
# if __cplusplus >= 201103L || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) || __has_extension(cxx_noexcept) | |||
# define CARLA_PROPER_CPP11_SUPPORT | |||
# if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) || ! __has_extension(cxx_override_control) | |||
# define override // gcc4.7+ only | |||
# define final // gcc4.7+ only | |||
# endif | |||
# endif | |||
#endif | |||
#if defined(__cplusplus) && !defined(CARLA_PROPER_CPP11_SUPPORT) | |||
# define noexcept throw() | |||
# define override | |||
# define final | |||
# define nullptr (0) | |||
#endif | |||
/* Common includes */ | |||
#ifdef __cplusplus | |||
# include <cstddef> | |||
#else | |||
# include <stdbool.h> | |||
# include <stddef.h> | |||
#endif | |||
/* Define CARLA_SAFE_ASSERT* */ | |||
#define CARLA_SAFE_ASSERT(cond) if (cond) pass(); else carla_safe_assert (#cond, __FILE__, __LINE__); | |||
#define CARLA_SAFE_ASSERT_INT(cond, value) if (cond) pass(); else carla_safe_assert_int (#cond, __FILE__, __LINE__, static_cast<int>(value)); | |||
#define CARLA_SAFE_ASSERT_INT2(cond, v1, v2) if (cond) pass(); else carla_safe_assert_int2 (#cond, __FILE__, __LINE__, static_cast<int>(v1), static_cast<int>(v2)); | |||
#define CARLA_SAFE_ASSERT_UINT(cond, value) if (cond) pass(); else carla_safe_assert_uint (#cond, __FILE__, __LINE__, static_cast<uint>(value)); | |||
#define CARLA_SAFE_ASSERT_UINT2(cond, v1, v2) if (cond) pass(); else carla_safe_assert_uint2(#cond, __FILE__, __LINE__, static_cast<uint>(v1), static_cast<uint>(v2)); | |||
#define CARLA_SAFE_ASSERT_BREAK(cond) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); break; } | |||
#define CARLA_SAFE_ASSERT_CONTINUE(cond) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); continue; } | |||
#define CARLA_SAFE_ASSERT_RETURN(cond, ret) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); return ret; } | |||
// ----------------------------------------------------------------------- | |||
// utils | |||
#include <cstdarg> | |||
#include <cstdio> | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# include <cstdint> | |||
#else | |||
# include <stdint.h> | |||
#endif | |||
#ifdef CARLA_OS_WIN | |||
# include <winsock2.h> | |||
# include <windows.h> | |||
#else | |||
# include <unistd.h> | |||
#endif | |||
// ----------------------------------------------------------------------- | |||
// string print functions | |||
/* | |||
* Print a string to stdout with newline (gray color). | |||
* Does nothing if DEBUG is not defined. | |||
*/ | |||
#ifndef DEBUG | |||
# define carla_debug(...) | |||
#else | |||
static inline | |||
void carla_debug(const char* const fmt, ...) noexcept | |||
{ | |||
try { | |||
::va_list args; | |||
::va_start(args, fmt); | |||
std::fprintf(stdout, "\x1b[30;1m"); | |||
std::vfprintf(stdout, fmt, args); | |||
std::fprintf(stdout, "\x1b[0m\n"); | |||
::va_end(args); | |||
} catch (...) {} | |||
} | |||
#endif | |||
/* | |||
* Print a string to stdout with newline. | |||
*/ | |||
static inline | |||
void carla_stdout(const char* const fmt, ...) noexcept | |||
{ | |||
try { | |||
::va_list args; | |||
::va_start(args, fmt); | |||
std::vfprintf(stdout, fmt, args); | |||
std::fprintf(stdout, "\n"); | |||
::va_end(args); | |||
} catch (...) {} | |||
} | |||
/* | |||
* Print a string to stderr with newline. | |||
*/ | |||
static inline | |||
void carla_stderr(const char* const fmt, ...) noexcept | |||
{ | |||
try { | |||
::va_list args; | |||
::va_start(args, fmt); | |||
std::vfprintf(stderr, fmt, args); | |||
std::fprintf(stderr, "\n"); | |||
::va_end(args); | |||
} catch (...) {} | |||
} | |||
/* | |||
* Print a string to stderr with newline (red color). | |||
*/ | |||
static inline | |||
void carla_stderr2(const char* const fmt, ...) noexcept | |||
{ | |||
try { | |||
::va_list args; | |||
::va_start(args, fmt); | |||
std::fprintf(stderr, "\x1b[31m"); | |||
std::vfprintf(stderr, fmt, args); | |||
std::fprintf(stderr, "\x1b[0m\n"); | |||
::va_end(args); | |||
} catch (...) {} | |||
} | |||
// ----------------------------------------------------------------------- | |||
// carla_safe_assert* | |||
/* | |||
* Print a safe assertion error message. | |||
*/ | |||
static inline | |||
void carla_safe_assert(const char* const assertion, const char* const file, const int line) noexcept | |||
{ | |||
carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line); | |||
} | |||
/* | |||
* Print a safe assertion error message, with 1 extra integer value. | |||
*/ | |||
static inline | |||
void carla_safe_assert_int(const char* const assertion, const char* const file, const int line, const int value) noexcept | |||
{ | |||
carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value); | |||
} | |||
static inline | |||
void carla_safe_assert_uint(const char* const assertion, const char* const file, const int line, const uint value) noexcept | |||
{ | |||
carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %u", assertion, file, line, value); | |||
} | |||
/* | |||
* Print a safe assertion error message, with 2 extra integer values. | |||
*/ | |||
static inline | |||
void carla_safe_assert_int2(const char* const assertion, const char* const file, const int line, const int v1, const int v2) noexcept | |||
{ | |||
carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2); | |||
} | |||
static inline | |||
void carla_safe_assert_uint2(const char* const assertion, const char* const file, const int line, const uint v1, const uint v2) noexcept | |||
{ | |||
carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %u, v2 %u", assertion, file, line, v1, v2); | |||
} | |||
// ----------------------------------------------------------------------- | |||
#endif // CARLA_UTILS_HPP_INCLUDED |