--- a/src/JackHandler.h Sun Oct 04 00:04:28 2020 +0200
+++ b/src/JackHandler.h Sun Oct 04 12:40:00 2020 +0200
@@ -111,16 +111,12 @@
public:
bool skip = false;
- size_t indexOfEvent = -1;
- size_t indexOfChannel = -1;
- size_t indexOfNoteOn = -1;
- size_t indexOfNotePitch = -1;
- size_t indexOfNoteVelocity = -1;
- size_t indexOfControllerId = -1;
- size_t indexOfControllerValue = -1;
- size_t indexOfRaw = -1;
+ std::vector<relpipe::reader::handlers::AttributeMetadata> attributes;
- size_t attributeCount = 0;
+ bool hasAttribute(const relpipe::common::type::StringX& name) {
+ for (auto a : attributes) if (a.getAttributeName() == name) return true;
+ return false;
+ }
class RecordContext {
public:
@@ -132,7 +128,7 @@
UNKNOWN
};
- static Event parseEventType(const relpipe::common::type::StringX name) {
+ static Event parseEventType(const relpipe::common::type::StringX& name) {
if (name == L"note") return Event::NOTE;
else if (name == L"control") return Event::CONTROL;
else if (name == L"sysex") return Event::SYSEX;
@@ -201,24 +197,12 @@
// TODO: validate metadata and prepare attribute mappings (names and types are important, order does not matter)
relationContext = RelationContext();
- relationContext.attributeCount = attributes.size();
-
- for (int i = 0; i < relationContext.attributeCount; i++) {
- const relpipe::common::type::StringX attributeName = attributes[i].getAttributeName();
- if (attributeName == L"event") relationContext.indexOfEvent = i;
- else if (attributeName == L"channel") relationContext.indexOfChannel = i;
- else if (attributeName == L"controller_id") relationContext.indexOfControllerId = i;
- else if (attributeName == L"controller_value") relationContext.indexOfControllerValue = i;
- else if (attributeName == L"note_on") relationContext.indexOfNoteOn = i;
- else if (attributeName == L"note_pitch") relationContext.indexOfNotePitch = i;
- else if (attributeName == L"note_velocity") relationContext.indexOfNoteVelocity = i;
- else if (attributeName == L"raw") relationContext.indexOfRaw = i;
- }
+ relationContext.attributes = attributes;
// TODO: check also data types and skipt relation if important attributes are missing
// TODO: configurable relation name
- if (relationContext.indexOfRaw == -1) {
+ if (!relationContext.hasAttribute(L"raw")) {
relationContext.skip = true;
fwprintf(stderr, L"Relation „%ls“ will be ignored because mandatory attribute „raw“ is missing.\n", name.c_str());
}
@@ -233,18 +217,20 @@
RelationContext& rel = relationContext;
RelationContext::RecordContext& rec = rel.recordContext;
- if (rel.indexOfEvent == rec.attributeIndex) rec.event = rec.parseEventType(value);
- else if (rel.indexOfChannel == rec.attributeIndex) rec.channel = std::stoi(value);
- else if (rel.indexOfControllerId == rec.attributeIndex) rec.controllerId = std::stoi(value);
- else if (rel.indexOfControllerValue == rec.attributeIndex) rec.controllerValue = std::stoi(value);
- else if (rel.indexOfNoteOn == rec.attributeIndex) rec.noteOn = value == L"true";
- else if (rel.indexOfNotePitch == rec.attributeIndex) rec.notePitch = std::stoi(value);
- else if (rel.indexOfNoteVelocity == rec.attributeIndex) rec.noteVelocity = std::stoi(value);
- else if (rel.indexOfRaw == rec.attributeIndex) rec.raw = value;
+ const auto attributeName = rel.attributes[rec.attributeIndex].getAttributeName();
+
+ if (attributeName == L"event") rec.event = rec.parseEventType(value);
+ else if (attributeName == L"channel") rec.channel = std::stoi(value);
+ else if (attributeName == L"controller_id") rec.controllerId = std::stoi(value);
+ else if (attributeName == L"controller_value") rec.controllerValue = std::stoi(value);
+ else if (attributeName == L"note_on") rec.noteOn = value == L"true";
+ else if (attributeName == L"note_pitch") rec.notePitch = std::stoi(value);
+ else if (attributeName == L"note_velocity") rec.noteVelocity = std::stoi(value);
+ else if (attributeName == L"raw") rec.raw = value;
rec.attributeIndex++;
- if (rec.attributeIndex == rel.attributeCount) {
+ if (rec.attributeIndex == rel.attributes.size()) {
while (jack_ringbuffer_write_space(realTimeContext.ringBuffer) < sizeof (MidiMessage)) usleep(1000); // should not happen, the real-time thread should be faster