Browse Source

Update: Adds new params to Kars, fixes ProM build

tags/v1.2
falkTX 6 years ago
parent
commit
3adff28961
12 changed files with 252 additions and 63 deletions
  1. +3
    -0
      dpf/dgl/ImageWidgets.hpp
  2. +25
    -0
      dpf/dgl/Widget.hpp
  3. +4
    -0
      dpf/dgl/Window.hpp
  4. +17
    -0
      dpf/dgl/src/ImageWidgets.cpp
  5. +12
    -10
      dpf/dgl/src/Widget.cpp
  6. +3
    -1
      dpf/dgl/src/Window.cpp
  7. +4
    -0
      dpf/dgl/src/pugl/pugl_win.cpp
  8. +4
    -3
      dpf/distrho/src/DistrhoPluginCarla.cpp
  9. +4
    -1
      dpf/distrho/src/DistrhoPluginVST.cpp
  10. +159
    -41
      plugins/Kars/DistrhoPluginKars.cpp
  11. +11
    -7
      plugins/Kars/DistrhoPluginKars.hpp
  12. +6
    -0
      plugins/ProM/Makefile

+ 3
- 0
dpf/dgl/ImageWidgets.hpp View File

@@ -180,6 +180,7 @@ public:

float getValue() const noexcept;
void setValue(float value, bool sendCallback = false) noexcept;
void setDefault(float def) noexcept;

void setStartPos(const Point<int>& startPos) noexcept;
void setStartPos(int x, int y) noexcept;
@@ -203,7 +204,9 @@ private:
float fMaximum;
float fStep;
float fValue;
float fValueDef;
float fValueTmp;
bool fUsingDefault;

bool fDragging;
bool fInverted;


+ 25
- 0
dpf/dgl/Widget.hpp View File

@@ -24,9 +24,11 @@
// -----------------------------------------------------------------------
// Forward class names

#ifdef DISTRHO_DEFINES_H_INCLUDED
START_NAMESPACE_DISTRHO
class UI;
END_NAMESPACE_DISTRHO
#endif

START_NAMESPACE_DGL

@@ -175,6 +177,22 @@ public:
oldSize(0, 0) {}
};

/**
Widget position changed event.
@a pos The new absolute position of the widget.
@a oldPos The previous absolute position of the widget.
@see onPositionChanged
*/
struct PositionChangedEvent {
Point<int> pos;
Point<int> oldPos;

/** Constuctor */
PositionChangedEvent() noexcept
: pos(0, 0),
oldPos(0, 0) {}
};

/**
Constructor.
*/
@@ -362,6 +380,11 @@ protected:
*/
virtual void onResize(const ResizeEvent&);

/**
A function called when the widget's absolute position is changed.
*/
virtual void onPositionChanged(const PositionChangedEvent&);

private:
struct PrivateData;
PrivateData* const pData;
@@ -373,7 +396,9 @@ private:
friend class NanoWidget;
friend class Window;
friend class StandaloneWindow;
#ifdef DISTRHO_DEFINES_H_INCLUDED
friend class DISTRHO_NAMESPACE::UI;
#endif

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget)
};


+ 4
- 0
dpf/dgl/Window.hpp View File

@@ -19,9 +19,11 @@

#include "Geometry.hpp"

#ifdef DISTRHO_DEFINES_H_INCLUDED
START_NAMESPACE_DISTRHO
class UIExporter;
END_NAMESPACE_DISTRHO
#endif

START_NAMESPACE_DGL

@@ -129,7 +131,9 @@ private:
friend class Application;
friend class Widget;
friend class StandaloneWindow;
#ifdef DISTRHO_DEFINES_H_INCLUDED
friend class DISTRHO_NAMESPACE::UIExporter;
#endif

virtual void _addWidget(Widget* const widget);
virtual void _removeWidget(Widget* const widget);


+ 17
- 0
dpf/dgl/src/ImageWidgets.cpp View File

@@ -649,7 +649,9 @@ ImageSlider::ImageSlider(Window& parent, const Image& image) noexcept
fMaximum(1.0f),
fStep(0.0f),
fValue(0.5f),
fValueDef(fValue),
fValueTmp(fValue),
fUsingDefault(false),
fDragging(false),
fInverted(false),
fValueIsSet(false),
@@ -670,7 +672,9 @@ ImageSlider::ImageSlider(Widget* widget, const Image& image) noexcept
fMaximum(1.0f),
fStep(0.0f),
fValue(0.5f),
fValueDef(fValue),
fValueTmp(fValue),
fUsingDefault(false),
fDragging(false),
fInverted(false),
fValueIsSet(false),
@@ -743,6 +747,12 @@ void ImageSlider::setInverted(bool inverted) noexcept
repaint();
}

void ImageSlider::setDefault(float value) noexcept
{
fValueDef = value;
fUsingDefault = true;
}

void ImageSlider::setRange(float min, float max) noexcept
{
fMinimum = min;
@@ -830,6 +840,13 @@ bool ImageSlider::onMouse(const MouseEvent& ev)
if (! fSliderArea.contains(ev.pos))
return false;

if ((ev.mod & kModifierShift) != 0 && fUsingDefault)
{
setValue(fValueDef, true);
fValueTmp = fValue;
return true;
}

float vper;
const int x = ev.pos.getX();
const int y = ev.pos.getY();


+ 12
- 10
dpf/dgl/src/Widget.cpp View File

@@ -151,20 +151,12 @@ const Point<int>& Widget::getAbsolutePos() const noexcept

void Widget::setAbsoluteX(int x) noexcept
{
if (pData->absolutePos.getX() == x)
return;

pData->absolutePos.setX(x);
pData->parent.repaint();
setAbsolutePos(Point<int>(x, getAbsoluteY()));
}

void Widget::setAbsoluteY(int y) noexcept
{
if (pData->absolutePos.getY() == y)
return;

pData->absolutePos.setY(y);
pData->parent.repaint();
setAbsolutePos(Point<int>(getAbsoluteX(), y));
}

void Widget::setAbsolutePos(int x, int y) noexcept
@@ -177,7 +169,13 @@ void Widget::setAbsolutePos(const Point<int>& pos) noexcept
if (pData->absolutePos == pos)
return;

PositionChangedEvent ev;
ev.oldPos = pData->absolutePos;
ev.pos = pos;

pData->absolutePos = pos;
onPositionChanged(ev);

pData->parent.repaint();
}

@@ -245,6 +243,10 @@ void Widget::onResize(const ResizeEvent&)
{
}

void Widget::onPositionChanged(const PositionChangedEvent&)
{
}

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

END_NAMESPACE_DGL

+ 3
- 1
dpf/dgl/src/Window.cpp View File

@@ -32,6 +32,8 @@

#if defined(DISTRHO_OS_WINDOWS)
# include "pugl/pugl_win.cpp"
# undef max
# undef min
#elif defined(DISTRHO_OS_MAC)
# define PuglWindow DISTRHO_JOIN_MACRO(PuglWindow, DGL_NAMESPACE)
# define PuglOpenGLView DISTRHO_JOIN_MACRO(PuglOpenGLView, DGL_NAMESPACE)
@@ -573,7 +575,7 @@ struct Window::PrivateData {

#if defined(DISTRHO_OS_WINDOWS)
const int winFlags = WS_POPUPWINDOW | WS_CAPTION | (fResizable ? WS_SIZEBOX : 0x0);
RECT wr = { 0, 0, static_cast<long>(width), static_cast<long>(height) };
RECT wr = { 0, 0, static_cast<LONG>(width), static_cast<LONG>(height) };
AdjustWindowRectEx(&wr, fUsingEmbed ? WS_CHILD : winFlags, FALSE, WS_EX_TOPMOST);

SetWindowPos(hwnd, 0, 0, 0, wr.right-wr.left, wr.bottom-wr.top,


+ 4
- 0
dpf/dgl/src/pugl/pugl_win.cpp View File

@@ -111,7 +111,11 @@ puglCreateWindow(PuglView* view, const char* title)
static int wc_count = 0;
char classNameBuf[256];
std::srand((std::time(NULL)));
#ifdef __WINE__
std::snprintf(classNameBuf, sizeof(classNameBuf), "%s_%d-%d", title, std::rand(), ++wc_count);
#else
_snprintf(classNameBuf, sizeof(classNameBuf), "%s_%d-%d", title, std::rand(), ++wc_count);
#endif
classNameBuf[sizeof(classNameBuf)-1] = '\0';

impl->wc.style = CS_OWNDC;


+ 4
- 3
dpf/distrho/src/DistrhoPluginCarla.cpp View File

@@ -26,13 +26,14 @@

START_NAMESPACE_DISTRHO

#if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
static const writeMidiFunc writeMidiCallback = nullptr;
#endif

#if DISTRHO_PLUGIN_HAS_UI
// -----------------------------------------------------------------------
// Carla UI

#if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
static const writeMidiFunc writeMidiCallback = nullptr;
#endif
#if ! DISTRHO_PLUGIN_WANT_STATE
static const setStateFunc setStateCallback = nullptr;
#endif


+ 4
- 1
dpf/distrho/src/DistrhoPluginVST.cpp View File

@@ -71,18 +71,21 @@ static const writeMidiFunc writeMidiCallback = nullptr;

void strncpy(char* const dst, const char* const src, const size_t size)
{
std::strncpy(dst, src, size-1);
DISTRHO_SAFE_ASSERT_RETURN(size > 0,);
std::memcpy(dst, src, std::min(std::strlen(src), size-1));
dst[size-1] = '\0';
}

void snprintf_param(char* const dst, const float value, const size_t size)
{
DISTRHO_SAFE_ASSERT_RETURN(size > 0,);
std::snprintf(dst, size-1, "%f", value);
dst[size-1] = '\0';
}

void snprintf_iparam(char* const dst, const int32_t value, const size_t size)
{
DISTRHO_SAFE_ASSERT_RETURN(size > 0,);
std::snprintf(dst, size-1, "%d", value);
dst[size-1] = '\0';
}


+ 159
- 41
plugins/Kars/DistrhoPluginKars.cpp View File

@@ -23,12 +23,14 @@ START_NAMESPACE_DISTRHO
DistrhoPluginKars::DistrhoPluginKars()
: Plugin(paramCount, 0, 0), // 0 programs, 0 states
fSustain(false),
fRelease(0.01),
fVolume(75.0f),
fSampleRate(getSampleRate()),
fBlockStart(0)
{
for (int i=kMaxNotes; --i >= 0;)
{
fNotes[i].index = i;
fNotes[i].voice = i;
fNotes[i].setSampleRate(fSampleRate);
}
}
@@ -38,15 +40,35 @@ DistrhoPluginKars::DistrhoPluginKars()
void DistrhoPluginKars::initParameter(uint32_t index, Parameter& parameter)
{
if (index != 0)
return;
parameter.hints = kParameterIsAutomable|kParameterIsBoolean;
parameter.name = "Sustain";
parameter.symbol = "sustain";
parameter.ranges.def = 0.0f;
parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f;
switch (index)
{
case paramSustain:
parameter.hints = kParameterIsAutomable|kParameterIsBoolean;
parameter.name = "Sustain";
parameter.symbol = "sustain";
parameter.ranges.def = 0.0f;
parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f;
break;
case paramRelease:
parameter.hints = kParameterIsAutomable;
parameter.name = "Release";
parameter.symbol = "release";
parameter.unit = "s";
parameter.ranges.def = 0.01f;
parameter.ranges.min = 0.0f;
parameter.ranges.max = 5.0f;
break;
case paramVolume:
parameter.hints = kParameterIsAutomable;
parameter.name = "Volume";
parameter.symbol = "volume";
parameter.unit = "%";
parameter.ranges.def = 75.0f;
parameter.ranges.min = 0.0f;
parameter.ranges.max = 100.0f;
break;
}
}
// -----------------------------------------------------------------------
@@ -54,18 +76,30 @@ void DistrhoPluginKars::initParameter(uint32_t index, Parameter& parameter)
float DistrhoPluginKars::getParameterValue(uint32_t index) const
{
if (index != 0)
return 0.0f;
switch (index)
{
case paramSustain: return fSustain ? 1.0f : 0.0f;
case paramRelease: return fRelease;
case paramVolume: return fVolume;
}
return fSustain ? 1.0f : 0.0f;
return 0.0f;
}
void DistrhoPluginKars::setParameterValue(uint32_t index, float value)
{
if (index != 0)
return;
fSustain = value > 0.5f;
switch (index)
{
case paramSustain:
fSustain = value > 0.5f;
break;
case paramRelease:
fRelease = value;
break;
case paramVolume:
fVolume = value;
break;
}
}
// -----------------------------------------------------------------------
@@ -83,19 +117,112 @@ void DistrhoPluginKars::activate()
}
}
/**
Handy class to help keep audio buffer in sync with incoming MIDI events.
To use it, create a local variable (on the stack) and call nextEvent() until it returns false.
@code
for (AudioMidiSyncHelper amsh(outputs, frames, midiEvents, midiEventCount); amsh.nextEvent();)
{
float* const outL = amsh.outputs[0];
float* const outR = amsh.outputs[1];
for (uint32_t i=0; i<amsh.midiEventCount; ++i)
{
const MidiEvent& ev(amsh.midiEvents[i]);
// ... do something with the midi event
}
renderSynth(outL, outR, amsh.frames);
}
@endcode
Some important notes when using this class:
1. MidiEvent::frame retains its original value, but it is useless, do not use it.
2. The class variables names are be the same as the default ones in the run function.
Keep that in mind and try to avoid typos. :)
*/
class AudioMidiSyncHelper {
public:
/** Parameters from the run function, adjusted for event sync */
float** outputs;
uint32_t frames;
const MidiEvent* midiEvents;
uint32_t midiEventCount;
/**
Constructor, using values from the run function.
*/
AudioMidiSyncHelper(float** const o, uint32_t f, const MidiEvent* m, uint32_t mc)
: outputs(o),
frames(0),
midiEvents(m),
midiEventCount(0),
remainingFrames(f),
remainingMidiEventCount(mc) {}
/**
Process a batch of events untill no more are available.
You must not read any more values from this class after this function returns false.
*/
bool nextEvent()
{
if (remainingMidiEventCount == 0)
{
if (remainingFrames == 0)
return false;
for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
outputs[i] += frames;
if (midiEventCount != 0)
midiEvents += midiEventCount;
frames = remainingFrames;
midiEvents = nullptr;
midiEventCount = 0;
remainingFrames = 0;
return true;
}
const uint32_t eventFrame = midiEvents[0].frame;
DISTRHO_SAFE_ASSERT_RETURN(eventFrame < remainingFrames, false);
midiEventCount = 1;
for (uint32_t i=1; i<remainingMidiEventCount; ++i)
{
if (midiEvents[i].frame != eventFrame)
{
midiEventCount = i;
break;
}
}
frames = remainingFrames - eventFrame;
remainingFrames -= frames;
remainingMidiEventCount -= midiEventCount;
return true;
}
private:
/** @internal */
uint32_t remainingFrames;
uint32_t remainingMidiEventCount;
};
void DistrhoPluginKars::run(const float**, float** outputs, uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount)
{
uint8_t note, velo;
float* out = outputs[0];
std::memset(outputs[0], 0, sizeof(float)*frames);
for (uint32_t count, pos=0, curEventIndex=0; pos<frames;)
for (AudioMidiSyncHelper amsh(outputs, frames, midiEvents, midiEventCount); amsh.nextEvent();)
{
for (;curEventIndex < midiEventCount && pos >= midiEvents[curEventIndex].frame; ++curEventIndex)
for (uint32_t i=0; i<amsh.midiEventCount; ++i)
{
if (midiEvents[curEventIndex].size > MidiEvent::kDataSize)
if (amsh.midiEvents[i].size > MidiEvent::kDataSize)
continue;
const uint8_t* data = midiEvents[curEventIndex].data;
const uint8_t* data = amsh.midiEvents[i].data;
const uint8_t status = data[0] & 0xF0;
switch (status)
@@ -106,7 +233,7 @@ void DistrhoPluginKars::run(const float**, float** outputs, uint32_t frames, con
DISTRHO_SAFE_ASSERT_BREAK(note < 128); // kMaxNotes
if (velo > 0)
{
fNotes[note].on = fBlockStart + midiEvents[curEventIndex].frame;
fNotes[note].on = fBlockStart + amsh.midiEvents[i].frame;
fNotes[note].off = kNoteNull;
fNotes[note].velocity = velo;
break;
@@ -115,35 +242,26 @@ void DistrhoPluginKars::run(const float**, float** outputs, uint32_t frames, con
case 0x80:
note = data[1];
DISTRHO_SAFE_ASSERT_BREAK(note < 128); // kMaxNotes
fNotes[note].off = fBlockStart + midiEvents[curEventIndex].frame;
fNotes[note].off = fBlockStart + amsh.midiEvents[i].frame;
break;
}
}
if (curEventIndex < midiEventCount && midiEvents[curEventIndex].frame < frames)
count = midiEvents[curEventIndex].frame - pos;
else
count = frames - pos;
std::memset(out+pos, 0, sizeof(float)*count);
//for (uint32_t i=0; i<count; ++i)
// out[pos + i] = 0.0f;
float* const out = amsh.outputs[0];
for (int i=kMaxNotes; --i >= 0;)
{
if (fNotes[i].on != kNoteNull)
addSamples(out, i, pos, count);
addSamples(out, i, amsh.frames);
}
pos += count;
}
fBlockStart += frames;
}
void DistrhoPluginKars::addSamples(float* out, int voice, uint32_t offset, uint32_t count)
void DistrhoPluginKars::addSamples(float* out, int voice, uint32_t frames)
{
const uint32_t start = fBlockStart + offset;
const uint32_t start = fBlockStart;
Note& note(fNotes[voice]);
@@ -162,7 +280,7 @@ void DistrhoPluginKars::addSamples(float* out, int voice, uint32_t offset, uint3
float gain, sample;
uint32_t index, size;
for (uint32_t i=0, s=start-note.on; i<count; ++i, ++s)
for (uint32_t i=0, s=start-note.on; i<frames; ++i, ++s)
{
gain = vgain;
@@ -170,8 +288,8 @@ void DistrhoPluginKars::addSamples(float* out, int voice, uint32_t offset, uint3
{
// reuse index and size to save some performance.
// actual values are release and dist
index = 1 + uint32_t(0.01 * fSampleRate); // release, not index
size = i + start - note.off; // dist, not size
index = 1 + uint32_t(fRelease * fSampleRate); // release, not index
size = i + start - note.off; // dist, not size
if (size > index)
{
@@ -198,7 +316,7 @@ void DistrhoPluginKars::addSamples(float* out, int voice, uint32_t offset, uint3
note.wavetable[index] = sample/2;
}
out[offset+i] += gain * sample;
out[i] += gain * sample * (fVolume / 100.0f);
}
}


+ 11
- 7
plugins/Kars/DistrhoPluginKars.hpp View File

@@ -32,6 +32,8 @@ public:
enum Parameters
{
paramSustain = 0,
paramRelease,
paramVolume,
paramCount
};
@@ -97,6 +99,8 @@ protected:
private:
bool fSustain;
float fRelease;
float fVolume;
double fSampleRate;
uint32_t fBlockStart;
@@ -104,16 +108,16 @@ private:
uint32_t on;
uint32_t off;
uint8_t velocity;
float index;
float size;
int sizei;
float* wavetable;
float voice;
float size;
int sizei;
float* wavetable;
Note() noexcept
: on(kNoteNull),
off(kNoteNull),
velocity(0),
index(0.0f),
voice(0.0f),
size(0.0f),
wavetable(nullptr) {}
@@ -131,7 +135,7 @@ private:
if (wavetable != nullptr)
delete[] wavetable;
const float frequency = 440.0f * std::pow(2.0f, (index - 69.0f) / 12.0f);
const float frequency = 440.0f * std::pow(2.0f, (voice - 69.0f) / 12.0f);
size = sampleRate / frequency;
sizei = int(size)+1;
wavetable = new float[sizei];
@@ -140,7 +144,7 @@ private:
} fNotes[kMaxNotes];
void addSamples(float* out, int voice, uint32_t offset, uint32_t count);
void addSamples(float* out, int voice, uint32_t frames);
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DistrhoPluginKars)
};


+ 6
- 0
plugins/ProM/Makefile View File

@@ -23,6 +23,12 @@ FILES_UI = \

include ../../dpf/Makefile.plugins.mk

# --------------------------------------------------------------
# Extra flags

BASE_FLAGS += $(shell pkg-config --cflags libprojectM)
LINK_FLAGS += $(shell pkg-config --libs libprojectM) -lpthread

# --------------------------------------------------------------
# Enable all possible plugin types



Loading…
Cancel
Save