Browse Source

Update DPF and Nekobi

tags/v1.1
falkTX 8 years ago
parent
commit
fe9e89e260
10 changed files with 231 additions and 51 deletions
  1. +4
    -4
      dpf/dgl/NanoVG.hpp
  2. +1
    -1
      dpf/dgl/Widget.hpp
  3. +56
    -2
      dpf/distrho/DistrhoPlugin.hpp
  4. +7
    -0
      dpf/distrho/src/DistrhoPluginInternal.hpp
  5. +97
    -28
      dpf/distrho/src/DistrhoPluginJack.cpp
  6. +11
    -10
      dpf/distrho/src/DistrhoPluginLV2.cpp
  7. +33
    -4
      dpf/distrho/src/DistrhoPluginLV2export.cpp
  8. +1
    -1
      dpf/distrho/src/DistrhoUILV2.cpp
  9. +18
    -0
      plugins/Nekobi/DistrhoPluginNekobi.cpp
  10. +3
    -1
      plugins/Nekobi/DistrhoPluginNekobi.hpp

+ 4
- 4
dpf/dgl/NanoVG.hpp View File

@@ -192,10 +192,10 @@ private:


@code @code
const char* txt = "Text me up."; const char* txt = "Text me up.";
textBounds(vg, x,y, txt, NULL, bounds);
beginPath(vg);
roundedRect(vg, bounds[0], bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]);
fill(vg);
vg.textBounds(x,y, txt, NULL, bounds);
vg.beginPath();
vg.roundedRect(bounds[0], bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]);
vg.fill();
@endcode @endcode


Note: currently only solid color fill is supported for text. Note: currently only solid color fill is supported for text.


+ 1
- 1
dpf/dgl/Widget.hpp View File

@@ -111,7 +111,7 @@ public:
/** /**
Mouse event. Mouse event.
@a button The button number (1 = left, 2 = middle, 3 = right). @a button The button number (1 = left, 2 = middle, 3 = right).
@a press True if the key was pressed, false if released.
@a press True if the button was pressed, false if released.
@a pos The widget-relative coordinates of the pointer. @a pos The widget-relative coordinates of the pointer.
@see onMouse @see onMouse
*/ */


+ 56
- 2
dpf/distrho/DistrhoPlugin.hpp View File

@@ -133,6 +133,29 @@ struct AudioPort {
symbol() {} symbol() {}
}; };


/**
Parameter designation.@n
Allows a parameter to be specially designated for a task, like bypass.

Each designation is unique, there must be only one parameter that uses it.@n
The use of designated parameters is completely optional.

@note Designated parameters have strict ranges.
@see ParameterRanges::adjustForDesignation()
*/
enum ParameterDesignation {
/**
Null or unset designation.
*/
kParameterDesignationNull = 0,

/**
Bypass designation.@n
When on (> 0.5f), it means the plugin must run in a bypassed state.
*/
kParameterDesignationBypass = 1
};

/** /**
Parameter ranges.@n Parameter ranges.@n
This is used to set the default, minimum and maximum values of a parameter. This is used to set the default, minimum and maximum values of a parameter.
@@ -289,6 +312,11 @@ struct Parameter {
*/ */
ParameterRanges ranges; ParameterRanges ranges;


/**
Designation for this parameter.
*/
ParameterDesignation designation;

/** /**
MIDI CC to use by default on this parameter.@n MIDI CC to use by default on this parameter.@n
A value of 0 or 32 (bank change) is considered invalid.@n A value of 0 or 32 (bank change) is considered invalid.@n
@@ -306,6 +334,7 @@ struct Parameter {
symbol(), symbol(),
unit(), unit(),
ranges(), ranges(),
designation(kParameterDesignationNull),
midiCC(0) {} midiCC(0) {}


/** /**
@@ -317,7 +346,32 @@ struct Parameter {
symbol(s), symbol(s),
unit(u), unit(u),
ranges(def, min, max), ranges(def, min, max),
designation(kParameterDesignationNull),
midiCC(0) {} midiCC(0) {}

/**
Initialize a parameter for a specific designation.
*/
void initDesignation(ParameterDesignation d) noexcept
{
designation = d;

switch (d)
{
case kParameterDesignationNull:
break;
case kParameterDesignationBypass:
hints = kParameterIsAutomable|kParameterIsBoolean|kParameterIsInteger;
name = "Bypass";
symbol = "dpf_bypass";
unit = "";
midiCC = 0;
ranges.def = 0.0f;
ranges.min = 0.0f;
ranges.max = 1.0f;
break;
}
}
}; };


/** /**
@@ -541,7 +595,7 @@ public:
Returns false when the host buffer is full, in which case do not call this again until the next run(). Returns false when the host buffer is full, in which case do not call this again until the next run().
@note This function is not implemented yet!@n @note This function is not implemented yet!@n
It's here so that developers can prepare MIDI plugins in advance.@n It's here so that developers can prepare MIDI plugins in advance.@n
If you plan to use this, please report to DPF authos so it can be implemented.
If you plan to use this, please report to DPF authors so it can be implemented.
*/ */
bool writeMidiEvent(const MidiEvent& midiEvent) noexcept; bool writeMidiEvent(const MidiEvent& midiEvent) noexcept;
#endif #endif
@@ -661,7 +715,7 @@ protected:
/** /**
Get the value of an internal state.@n Get the value of an internal state.@n
The host may call this function from any non-realtime context.@n The host may call this function from any non-realtime context.@n
Must be implemented by your plugin class if DISTRHO_PLUGIN_WANT_PROGRAMS or DISTRHO_PLUGIN_WANT_FULL_STATE is enabled.
Must be implemented by your plugin class if DISTRHO_PLUGIN_WANT_FULL_STATE is enabled.
@note The use of this function breaks compatibility with the DSSI format. @note The use of this function breaks compatibility with the DSSI format.
*/ */
virtual String getState(const char* key) const = 0; virtual String getState(const char* key) const = 0;


+ 7
- 0
dpf/distrho/src/DistrhoPluginInternal.hpp View File

@@ -290,6 +290,13 @@ public:
return fData->parameters[index].hints; return fData->parameters[index].hints;
} }


ParameterDesignation getParameterDesignation(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, kParameterDesignationNull);

return fData->parameters[index].designation;
}

bool isParameterOutput(const uint32_t index) const noexcept bool isParameterOutput(const uint32_t index) const noexcept
{ {
return (getParameterHints(index) & kParameterIsOutput); return (getParameterHints(index) & kParameterIsOutput);


+ 97
- 28
dpf/distrho/src/DistrhoPluginJack.cpp View File

@@ -97,28 +97,27 @@ public:
#endif #endif
fClient(client) fClient(client)
{ {
#if DISTRHO_PLUGIN_NUM_INPUTS > 0 || DISTRHO_PLUGIN_NUM_OUTPUTS > 0
char strBuf[0xff+1]; char strBuf[0xff+1];
strBuf[0xff] = '\0'; strBuf[0xff] = '\0';


#if DISTRHO_PLUGIN_NUM_INPUTS > 0
# if DISTRHO_PLUGIN_NUM_INPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i)
{ {
std::snprintf(strBuf, 0xff, "in%i", i+1); std::snprintf(strBuf, 0xff, "in%i", i+1);
fPortAudioIns[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); fPortAudioIns[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
} }
#endif

#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
# endif
# if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
{ {
std::snprintf(strBuf, 0xff, "out%i", i+1); std::snprintf(strBuf, 0xff, "out%i", i+1);
fPortAudioOuts[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); fPortAudioOuts[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
} }
# endif
#endif #endif


#if DISTRHO_PLUGIN_IS_SYNTH
fPortMidiIn = jack_port_register(fClient, "midi-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
#endif
fPortEventsIn = jack_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);


#if DISTRHO_PLUGIN_WANT_PROGRAMS #if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fPlugin.getProgramCount() > 0) if (fPlugin.getProgramCount() > 0)
@@ -128,11 +127,18 @@ public:
fUI.programLoaded(0); fUI.programLoaded(0);
# endif # endif
} }
# if DISTRHO_PLUGIN_HAS_UI
fProgramChanged = -1;
# endif
#endif #endif


if (const uint32_t count = fPlugin.getParameterCount()) if (const uint32_t count = fPlugin.getParameterCount())
{ {
fLastOutputValues = new float[count]; fLastOutputValues = new float[count];
#if DISTRHO_PLUGIN_HAS_UI
fParametersChanged = new bool[count];
std::memset(fParametersChanged, 0, sizeof(bool)*count);
#endif


for (uint32_t i=0; i < count; ++i) for (uint32_t i=0; i < count; ++i)
{ {
@@ -143,15 +149,18 @@ public:
else else
{ {
fLastOutputValues[i] = 0.0f; fLastOutputValues[i] = 0.0f;
# if DISTRHO_PLUGIN_HAS_UI
#if DISTRHO_PLUGIN_HAS_UI
fUI.parameterChanged(i, fPlugin.getParameterValue(i)); fUI.parameterChanged(i, fPlugin.getParameterValue(i));
# endif
#endif
} }
} }
} }
else else
{ {
fLastOutputValues = nullptr; fLastOutputValues = nullptr;
#if DISTRHO_PLUGIN_HAS_UI
fParametersChanged = nullptr;
#endif
} }


jack_set_buffer_size_callback(fClient, jackBufferSizeCallback, this); jack_set_buffer_size_callback(fClient, jackBufferSizeCallback, this);
@@ -192,10 +201,8 @@ public:
if (fClient == nullptr) if (fClient == nullptr)
return; return;


#if DISTRHO_PLUGIN_IS_SYNTH
jack_port_unregister(fClient, fPortMidiIn);
fPortMidiIn = nullptr;
#endif
jack_port_unregister(fClient, fPortEventsIn);
fPortEventsIn = nullptr;


#if DISTRHO_PLUGIN_NUM_INPUTS > 0 #if DISTRHO_PLUGIN_NUM_INPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i)
@@ -225,20 +232,31 @@ protected:
if (gCloseSignalReceived) if (gCloseSignalReceived)
return fUI.quit(); return fUI.quit();


float value;
# if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fProgramChanged >= 0)
{
fUI.programLoaded(fProgramChanged);
fProgramChanged = -1;
}
# endif


for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i) for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{ {
if (! fPlugin.isParameterOutput(i))
continue;

value = fPlugin.getParameterValue(i);
if (fPlugin.isParameterOutput(i))
{
const float value = fPlugin.getParameterValue(i);


if (fLastOutputValues[i] == value)
continue;
if (d_isEqual(fLastOutputValues[i], value))
continue;


fLastOutputValues[i] = value;
fUI.parameterChanged(i, value);
fLastOutputValues[i] = value;
fUI.parameterChanged(i, value);
}
else if (fParametersChanged[i])
{
fParametersChanged[i] = false;
fUI.parameterChanged(i, fPlugin.getParameterValue(i));
}
} }


fUI.exec_idle(); fUI.exec_idle();
@@ -310,14 +328,14 @@ protected:
fPlugin.setTimePosition(fTimePosition); fPlugin.setTimePosition(fTimePosition);
#endif #endif


#if DISTRHO_PLUGIN_IS_SYNTH
void* const midiBuf = jack_port_get_buffer(fPortMidiIn, nframes);
void* const midiBuf = jack_port_get_buffer(fPortEventsIn, nframes);


if (const uint32_t eventCount = jack_midi_get_event_count(midiBuf)) if (const uint32_t eventCount = jack_midi_get_event_count(midiBuf))
{ {
#if DISTRHO_PLUGIN_IS_SYNTH
uint32_t midiEventCount = 0; uint32_t midiEventCount = 0;
MidiEvent midiEvents[eventCount]; MidiEvent midiEvents[eventCount];
#endif
jack_midi_event_t jevent; jack_midi_event_t jevent;


for (uint32_t i=0; i < eventCount; ++i) for (uint32_t i=0; i < eventCount; ++i)
@@ -325,6 +343,47 @@ protected:
if (jack_midi_event_get(&jevent, midiBuf, i) != 0) if (jack_midi_event_get(&jevent, midiBuf, i) != 0)
break; break;


// Check if message is control change on channel 1
if (jevent.buffer[0] == 0xB0 && jevent.size == 3)
{
const uint8_t control = jevent.buffer[1];
const uint8_t value = jevent.buffer[2];

/* NOTE: This is not optimal, we're iterating all parameters on every CC message.
Since the JACK standalone is more of a test tool, this will do for now. */
for (uint32_t j=0, paramCount=fPlugin.getParameterCount(); j < paramCount; ++j)
{
if (fPlugin.isParameterOutput(j))
continue;
if (fPlugin.getParameterMidiCC(j) != control)
continue;

const float scaled = static_cast<float>(value)/127.0f;
const float fvalue = fPlugin.getParameterRanges(j).getUnnormalizedValue(scaled);
fPlugin.setParameterValue(j, fvalue);
#if DISTRHO_PLUGIN_HAS_UI
fParametersChanged[j] = true;
#endif
break;
}
}
#if DISTRHO_PLUGIN_WANT_PROGRAMS
// Check if message is program change on channel 1
else if (jevent.buffer[0] == 0xC0 && jevent.size == 2)
{
const uint8_t program = jevent.buffer[1];

if (program < fPlugin.getProgramCount())
{
fPlugin.loadProgram(program);
# if DISTRHO_PLUGIN_HAS_UI
fProgramChanged = program;
# endif
}
}
#endif

#if DISTRHO_PLUGIN_IS_SYNTH
MidiEvent& midiEvent(midiEvents[midiEventCount++]); MidiEvent& midiEvent(midiEvents[midiEventCount++]);


midiEvent.frame = jevent.time; midiEvent.frame = jevent.time;
@@ -334,10 +393,14 @@ protected:
midiEvent.dataExt = jevent.buffer; midiEvent.dataExt = jevent.buffer;
else else
std::memcpy(midiEvent.data, jevent.buffer, midiEvent.size); std::memcpy(midiEvent.data, jevent.buffer, midiEvent.size);
#endif
} }


#if DISTRHO_PLUGIN_IS_SYNTH
fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount); fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount);
#endif
} }
#if DISTRHO_PLUGIN_IS_SYNTH
else else
{ {
fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0); fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0);
@@ -393,9 +456,7 @@ private:
#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 #if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
jack_port_t* fPortAudioOuts[DISTRHO_PLUGIN_NUM_OUTPUTS]; jack_port_t* fPortAudioOuts[DISTRHO_PLUGIN_NUM_OUTPUTS];
#endif #endif
#if DISTRHO_PLUGIN_IS_SYNTH
jack_port_t* fPortMidiIn;
#endif
jack_port_t* fPortEventsIn;
#if DISTRHO_PLUGIN_WANT_TIMEPOS #if DISTRHO_PLUGIN_WANT_TIMEPOS
TimePosition fTimePosition; TimePosition fTimePosition;
#endif #endif
@@ -403,6 +464,14 @@ private:
// Temporary data // Temporary data
float* fLastOutputValues; float* fLastOutputValues;


#if DISTRHO_PLUGIN_HAS_UI
// Store DSP changes to send to UI
bool* fParametersChanged;
# if DISTRHO_PLUGIN_WANT_PROGRAMS
int fProgramChanged;
# endif
#endif

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Callbacks // Callbacks




+ 11
- 10
dpf/distrho/src/DistrhoPluginLV2.cpp View File

@@ -512,6 +512,12 @@ public:
if (fLastControlValues[i] != curValue && ! fPlugin.isParameterOutput(i)) if (fLastControlValues[i] != curValue && ! fPlugin.isParameterOutput(i))
{ {
fLastControlValues[i] = curValue; fLastControlValues[i] = curValue;

if (fPlugin.getParameterDesignation(i) == kParameterDesignationBypass)
{
curValue = 1.0f - curValue;
}

fPlugin.setParameterValue(i, curValue); fPlugin.setParameterValue(i, curValue);
} }
} }
@@ -589,10 +595,14 @@ public:
#if DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI
const uint32_t capacity = fPortEventsOut->atom.size; const uint32_t capacity = fPortEventsOut->atom.size;


bool needsInit = true;
uint32_t size, offset = 0; uint32_t size, offset = 0;
LV2_Atom_Event* aev; LV2_Atom_Event* aev;


fPortEventsOut->atom.size = sizeof(LV2_Atom_Sequence_Body);
fPortEventsOut->atom.type = fURIDs.atomSequence;
fPortEventsOut->body.unit = 0;
fPortEventsOut->body.pad = 0;

// TODO - MIDI Output // TODO - MIDI Output


for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i) for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i)
@@ -617,15 +627,6 @@ public:
if (sizeof(LV2_Atom_Event) + msgSize > capacity - offset) if (sizeof(LV2_Atom_Event) + msgSize > capacity - offset)
break; break;


if (needsInit)
{
fPortEventsOut->atom.size = 0;
fPortEventsOut->atom.type = fURIDs.atomSequence;
fPortEventsOut->body.unit = 0;
fPortEventsOut->body.pad = 0;
needsInit = false;
}

// reserve msg space // reserve msg space
char msgBuf[msgSize]; char msgBuf[msgSize];
std::memset(msgBuf, 0, msgSize); std::memset(msgBuf, 0, msgSize);


+ 33
- 4
dpf/distrho/src/DistrhoPluginLV2export.cpp View File

@@ -377,10 +377,34 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " a lv2:InputPort, lv2:ControlPort ;\n"; pluginString += " a lv2:InputPort, lv2:ControlPort ;\n";


pluginString += " lv2:index " + String(portIndex) + " ;\n"; pluginString += " lv2:index " + String(portIndex) + " ;\n";
pluginString += " lv2:name \"" + plugin.getParameterName(i) + "\" ;\n";


// symbol
bool designated = false;

// designation
if (! plugin.isParameterOutput(i))
{ {
switch (plugin.getParameterDesignation(i))
{
case kParameterDesignationNull:
break;
case kParameterDesignationBypass:
designated = true;
pluginString += " lv2:name \"Enabled\" ;\n";
pluginString += " lv2:symbol \"lv2_enabled\" ;\n";
pluginString += " lv2:default 1 ;\n";
pluginString += " lv2:minimum 0 ;\n";
pluginString += " lv2:maximum 1 ;\n";
pluginString += " lv2:portProperty lv2:toggled , lv2:integer ;\n";
pluginString += " lv2:designation lv2:enabled ;\n";
break;
}
}

// name and symbol
if (! designated)
{
pluginString += " lv2:name \"" + plugin.getParameterName(i) + "\" ;\n";

String symbol(plugin.getParameterSymbol(i)); String symbol(plugin.getParameterSymbol(i));


if (symbol.isEmpty()) if (symbol.isEmpty())
@@ -390,24 +414,28 @@ void lv2_generate_ttl(const char* const basename)
} }


// ranges // ranges
if (! designated)
{ {
const ParameterRanges& ranges(plugin.getParameterRanges(i)); const ParameterRanges& ranges(plugin.getParameterRanges(i));


if (plugin.getParameterHints(i) & kParameterIsInteger) if (plugin.getParameterHints(i) & kParameterIsInteger)
{ {
pluginString += " lv2:default " + String(int(plugin.getParameterValue(i))) + " ;\n";
if (! plugin.isParameterOutput(i))
pluginString += " lv2:default " + String(int(plugin.getParameterValue(i))) + " ;\n";
pluginString += " lv2:minimum " + String(int(ranges.min)) + " ;\n"; pluginString += " lv2:minimum " + String(int(ranges.min)) + " ;\n";
pluginString += " lv2:maximum " + String(int(ranges.max)) + " ;\n"; pluginString += " lv2:maximum " + String(int(ranges.max)) + " ;\n";
} }
else else
{ {
pluginString += " lv2:default " + String(plugin.getParameterValue(i)) + " ;\n";
if (! plugin.isParameterOutput(i))
pluginString += " lv2:default " + String(plugin.getParameterValue(i)) + " ;\n";
pluginString += " lv2:minimum " + String(ranges.min) + " ;\n"; pluginString += " lv2:minimum " + String(ranges.min) + " ;\n";
pluginString += " lv2:maximum " + String(ranges.max) + " ;\n"; pluginString += " lv2:maximum " + String(ranges.max) + " ;\n";
} }
} }


// unit // unit
if (! designated)
{ {
const String& unit(plugin.getParameterUnit(i)); const String& unit(plugin.getParameterUnit(i));


@@ -453,6 +481,7 @@ void lv2_generate_ttl(const char* const basename)
} }


// hints // hints
if (! designated)
{ {
const uint32_t hints(plugin.getParameterHints(i)); const uint32_t hints(plugin.getParameterHints(i));




+ 1
- 1
dpf/distrho/src/DistrhoUILV2.cpp View File

@@ -239,7 +239,7 @@ protected:
const size_t msgSize(tmpStr.length()+1); const size_t msgSize(tmpStr.length()+1);


// reserve atom space // reserve atom space
const size_t atomSize(lv2_atom_pad_size(sizeof(LV2_Atom) + msgSize));
const size_t atomSize(sizeof(LV2_Atom) + msgSize);
char atomBuf[atomSize]; char atomBuf[atomSize];
std::memset(atomBuf, 0, atomSize); std::memset(atomBuf, 0, atomSize);




+ 18
- 0
plugins/Nekobi/DistrhoPluginNekobi.cpp View File

@@ -135,6 +135,7 @@ DistrhoPluginNekobi::DistrhoPluginNekobi()
fParams.decay = 75.0f; fParams.decay = 75.0f;
fParams.accent = 25.0f; fParams.accent = 25.0f;
fParams.volume = 75.0f; fParams.volume = 75.0f;
fParams.bypass = false;
// Internal stuff // Internal stuff
fSynth.waveform = 0.0f; fSynth.waveform = 0.0f;
@@ -232,6 +233,9 @@ void DistrhoPluginNekobi::initParameter(uint32_t index, Parameter& parameter)
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 100.0f; parameter.ranges.max = 100.0f;
break; break;
case paramBypass:
parameter.initDesignation(kParameterDesignationBypass);
break;
} }
} }
@@ -258,6 +262,8 @@ float DistrhoPluginNekobi::getParameterValue(uint32_t index) const
return fParams.accent; return fParams.accent;
case paramVolume: case paramVolume:
return fParams.volume; return fParams.volume;
case paramBypass:
return fParams.bypass ? 1.0f : 0.0f;
} }
return 0.0f; return 0.0f;
@@ -307,6 +313,14 @@ void DistrhoPluginNekobi::setParameterValue(uint32_t index, float value)
fSynth.volume = value/100.0f; fSynth.volume = value/100.0f;
DISTRHO_SAFE_ASSERT(fSynth.volume >= 0.0f && fSynth.volume <= 1.0f); DISTRHO_SAFE_ASSERT(fSynth.volume >= 0.0f && fSynth.volume <= 1.0f);
break; break;
case paramBypass: {
const bool bypass = (value > 0.5f);
if (fParams.bypass != bypass)
{
fParams.bypass = bypass;
nekobee_synth_all_voices_off(&fSynth);
}
} break;
} }
} }
@@ -342,6 +356,10 @@ void DistrhoPluginNekobi::run(const float**, float** outputs, uint32_t frames, c
return; return;
} }
// ignore midi input if bypassed
if (fParams.bypass)
midiEventCount = 0;
while (framesDone < frames) while (framesDone < frames)
{ {
if (fSynth.nugget_remains == 0) if (fSynth.nugget_remains == 0)


+ 3
- 1
plugins/Nekobi/DistrhoPluginNekobi.hpp View File

@@ -42,6 +42,7 @@ public:
paramDecay, paramDecay,
paramAccent, paramAccent,
paramVolume, paramVolume,
paramBypass,
paramCount paramCount
}; };
@@ -79,7 +80,7 @@ protected:
uint32_t getVersion() const noexcept override uint32_t getVersion() const noexcept override
{ {
return d_version(1, 0, 0);
return d_version(1, 1, 0);
} }
int64_t getUniqueId() const noexcept override int64_t getUniqueId() const noexcept override
@@ -117,6 +118,7 @@ private:
float decay; float decay;
float accent; float accent;
float volume; float volume;
bool bypass;
} fParams; } fParams;
nekobee_synth_t fSynth; nekobee_synth_t fSynth;


Loading…
Cancel
Save