Skip to content

Instantly share code, notes, and snippets.

@falkTX
Created February 18, 2015 21:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save falkTX/2da8087fd8dc3dd1380b to your computer and use it in GitHub Desktop.
Save falkTX/2da8087fd8dc3dd1380b to your computer and use it in GitHub Desktop.
eg-midigate c++
#include "lv2.hpp"
class EG_MidiGate : public LV2::Plugin,
private LV2::URID_Map
{
public:
EG_MidiGate(double sampleRate, const char* bundlePath, const LV2_Feature* const* features)
: LV2::Plugin(sampleRate, bundlePath, features),
LV2::URID_Map(features),
uris(this),
numActiveNotes(0),
programInverted(false) {}
protected:
void connectPort(uint32_t port, void* dataLocation) override
{
buffers.connectPort(port, dataLocation);
}
void activate() override
{
numActiveNotes = 0;
programInverted = false;
}
void run(uint32_t sampleCount) override
{
uint32_t offset = 0;
LV2_ATOM_SEQUENCE_FOREACH(buffers.control, ev)
{
if (ev->body.type == uris.midiEvent)
{
const uint8_t* const msg = (const uint8_t*)(ev + 1);
switch (lv2_midi_message_type(msg))
{
case LV2_MIDI_MSG_NOTE_ON:
++numActiveNotes;
break;
case LV2_MIDI_MSG_NOTE_OFF:
--numActiveNotes;
break;
case LV2_MIDI_MSG_PGM_CHANGE:
if (msg[1] == 0 || msg[1] == 1)
programInverted = msg[1] == 0;
break;
default:
break;
}
}
writeOutput(offset, ev->time.frames - offset);
offset = (uint32_t)ev->time.frames;
}
writeOutput(offset, sampleCount - offset);
}
private:
enum PortIndexes {
kPortControl = 0,
kPortIn = 1,
kPortOut = 2
};
struct PortBuffers {
const LV2_Atom_Sequence* control;
const float* in;
float* out;
PortBuffers()
: control(nullptr),
in(nullptr),
out(nullptr) {}
void connectPort(uint32_t port, void* dataLocation)
{
switch (port)
{
case kPortControl:
control = (const LV2_Atom_Sequence*)dataLocation;
break;
case kPortIn:
in = (const float*)dataLocation;
break;
case kPortOut:
out = (float*)dataLocation;
break;
}
}
};
struct URIs {
LV2_URID midiEvent;
URIs(LV2::URID_Map* uridMap)
: midiEvent(uridMap->uridMap(LV2_MIDI__MidiEvent)) {}
};
PortBuffers buffers;
URIs uris;
unsigned numActiveNotes;
bool programInverted;
void writeOutput(uint32_t offset, uint32_t len)
{
const bool active = programInverted ? (numActiveNotes == 0)
: (numActiveNotes > 0);
if (active)
std::memcpy(buffers.out + offset, buffers.in + offset, len * sizeof(float));
else
std::memset(buffers.out + offset, 0, len * sizeof(float));
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment