src/JackHandler.h
branchv_0
changeset 16 d17d70731446
parent 15 b3239e4ad328
child 17 0fcd9944016a
equal deleted inserted replaced
15:b3239e4ad328 16:d17d70731446
   109 	 */
   109 	 */
   110 	class RelationContext {
   110 	class RelationContext {
   111 	public:
   111 	public:
   112 		bool skip = false;
   112 		bool skip = false;
   113 
   113 
   114 		size_t indexOfEvent = -1;
   114 		std::vector<relpipe::reader::handlers::AttributeMetadata> attributes;
   115 		size_t indexOfChannel = -1;
   115 
   116 		size_t indexOfNoteOn = -1;
   116 		bool hasAttribute(const relpipe::common::type::StringX& name) {
   117 		size_t indexOfNotePitch = -1;
   117 			for (auto a : attributes) if (a.getAttributeName() == name) return true;
   118 		size_t indexOfNoteVelocity = -1;
   118 			return false;
   119 		size_t indexOfControllerId = -1;
   119 		}
   120 		size_t indexOfControllerValue = -1;
       
   121 		size_t indexOfRaw = -1;
       
   122 
       
   123 		size_t attributeCount = 0;
       
   124 
   120 
   125 		class RecordContext {
   121 		class RecordContext {
   126 		public:
   122 		public:
   127 
   123 
   128 			enum class Event {
   124 			enum class Event {
   130 				CONTROL,
   126 				CONTROL,
   131 				SYSEX,
   127 				SYSEX,
   132 				UNKNOWN
   128 				UNKNOWN
   133 			};
   129 			};
   134 
   130 
   135 			static Event parseEventType(const relpipe::common::type::StringX name) {
   131 			static Event parseEventType(const relpipe::common::type::StringX& name) {
   136 				if (name == L"note") return Event::NOTE;
   132 				if (name == L"note") return Event::NOTE;
   137 				else if (name == L"control") return Event::CONTROL;
   133 				else if (name == L"control") return Event::CONTROL;
   138 				else if (name == L"sysex") return Event::SYSEX;
   134 				else if (name == L"sysex") return Event::SYSEX;
   139 				else return Event::UNKNOWN;
   135 				else return Event::UNKNOWN;
   140 			}
   136 			}
   199 
   195 
   200 	void startRelation(const relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
   196 	void startRelation(const relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
   201 		// TODO: validate metadata and prepare attribute mappings (names and types are important, order does not matter)
   197 		// TODO: validate metadata and prepare attribute mappings (names and types are important, order does not matter)
   202 
   198 
   203 		relationContext = RelationContext();
   199 		relationContext = RelationContext();
   204 		relationContext.attributeCount = attributes.size();
   200 		relationContext.attributes = attributes;
   205 
       
   206 		for (int i = 0; i < relationContext.attributeCount; i++) {
       
   207 			const relpipe::common::type::StringX attributeName = attributes[i].getAttributeName();
       
   208 			if (attributeName == L"event") relationContext.indexOfEvent = i;
       
   209 			else if (attributeName == L"channel") relationContext.indexOfChannel = i;
       
   210 			else if (attributeName == L"controller_id") relationContext.indexOfControllerId = i;
       
   211 			else if (attributeName == L"controller_value") relationContext.indexOfControllerValue = i;
       
   212 			else if (attributeName == L"note_on") relationContext.indexOfNoteOn = i;
       
   213 			else if (attributeName == L"note_pitch") relationContext.indexOfNotePitch = i;
       
   214 			else if (attributeName == L"note_velocity") relationContext.indexOfNoteVelocity = i;
       
   215 			else if (attributeName == L"raw") relationContext.indexOfRaw = i;
       
   216 		}
       
   217 
   201 
   218 		// TODO: check also data types and skipt relation if important attributes are missing
   202 		// TODO: check also data types and skipt relation if important attributes are missing
   219 		// TODO: configurable relation name
   203 		// TODO: configurable relation name
   220 
   204 
   221 		if (relationContext.indexOfRaw == -1) {
   205 		if (!relationContext.hasAttribute(L"raw")) {
   222 			relationContext.skip = true;
   206 			relationContext.skip = true;
   223 			fwprintf(stderr, L"Relation „%ls“ will be ignored because mandatory attribute „raw“ is missing.\n", name.c_str());
   207 			fwprintf(stderr, L"Relation „%ls“ will be ignored because mandatory attribute „raw“ is missing.\n", name.c_str());
   224 		}
   208 		}
   225 
   209 
   226 	}
   210 	}
   231 		// TODO: if (continueProcessing) {} ?
   215 		// TODO: if (continueProcessing) {} ?
   232 
   216 
   233 		RelationContext& rel = relationContext;
   217 		RelationContext& rel = relationContext;
   234 		RelationContext::RecordContext& rec = rel.recordContext;
   218 		RelationContext::RecordContext& rec = rel.recordContext;
   235 
   219 
   236 		if (rel.indexOfEvent == rec.attributeIndex) rec.event = rec.parseEventType(value);
   220 		const auto attributeName = rel.attributes[rec.attributeIndex].getAttributeName();
   237 		else if (rel.indexOfChannel == rec.attributeIndex) rec.channel = std::stoi(value);
   221 
   238 		else if (rel.indexOfControllerId == rec.attributeIndex) rec.controllerId = std::stoi(value);
   222 		if (attributeName == L"event") rec.event = rec.parseEventType(value);
   239 		else if (rel.indexOfControllerValue == rec.attributeIndex) rec.controllerValue = std::stoi(value);
   223 		else if (attributeName == L"channel") rec.channel = std::stoi(value);
   240 		else if (rel.indexOfNoteOn == rec.attributeIndex) rec.noteOn = value == L"true";
   224 		else if (attributeName == L"controller_id") rec.controllerId = std::stoi(value);
   241 		else if (rel.indexOfNotePitch == rec.attributeIndex) rec.notePitch = std::stoi(value);
   225 		else if (attributeName == L"controller_value") rec.controllerValue = std::stoi(value);
   242 		else if (rel.indexOfNoteVelocity == rec.attributeIndex) rec.noteVelocity = std::stoi(value);
   226 		else if (attributeName == L"note_on") rec.noteOn = value == L"true";
   243 		else if (rel.indexOfRaw == rec.attributeIndex) rec.raw = value;
   227 		else if (attributeName == L"note_pitch") rec.notePitch = std::stoi(value);
       
   228 		else if (attributeName == L"note_velocity") rec.noteVelocity = std::stoi(value);
       
   229 		else if (attributeName == L"raw") rec.raw = value;
   244 
   230 
   245 		rec.attributeIndex++;
   231 		rec.attributeIndex++;
   246 
   232 
   247 		if (rec.attributeIndex == rel.attributeCount) {
   233 		if (rec.attributeIndex == rel.attributes.size()) {
   248 
   234 
   249 			while (jack_ringbuffer_write_space(realTimeContext.ringBuffer) < sizeof (MidiMessage)) usleep(1000); // should not happen, the real-time thread should be faster
   235 			while (jack_ringbuffer_write_space(realTimeContext.ringBuffer) < sizeof (MidiMessage)) usleep(1000); // should not happen, the real-time thread should be faster
   250 
   236 
   251 			MidiMessage m;
   237 			MidiMessage m;
   252 
   238