src/JackHandler.h
branchv_0
changeset 24 427b8d799a4a
parent 23 d2ad84dcf249
child 25 e0627da77dad
equal deleted inserted replaced
23:d2ad84dcf249 24:427b8d799a4a
   128 
   128 
   129 			enum class Event {
   129 			enum class Event {
   130 				NOTE,
   130 				NOTE,
   131 				CONTROL,
   131 				CONTROL,
   132 				SYSEX,
   132 				SYSEX,
       
   133 				CONNECT,
       
   134 				DISCONNECT,
   133 				UNKNOWN
   135 				UNKNOWN
   134 			};
   136 			};
   135 
   137 
   136 			static Event parseEventType(const relpipe::common::type::StringX& name) {
   138 			static Event parseEventType(const relpipe::common::type::StringX& name) {
   137 				if (name == L"note") return Event::NOTE;
   139 				if (name == L"note") return Event::NOTE;
   138 				else if (name == L"control") return Event::CONTROL;
   140 				else if (name == L"control") return Event::CONTROL;
   139 				else if (name == L"sysex") return Event::SYSEX;
   141 				else if (name == L"sysex") return Event::SYSEX;
       
   142 				else if (name == L"connect") return Event::CONNECT;
       
   143 				else if (name == L"disconnect") return Event::DISCONNECT;
   140 				else return Event::UNKNOWN;
   144 				else return Event::UNKNOWN;
   141 			}
   145 			}
   142 
   146 
   143 			Event event = Event::UNKNOWN;
   147 			Event event = Event::UNKNOWN;
   144 			relpipe::common::type::Integer channel;
   148 			relpipe::common::type::Integer channel;
   146 			relpipe::common::type::Integer notePitch;
   150 			relpipe::common::type::Integer notePitch;
   147 			relpipe::common::type::Integer noteVelocity;
   151 			relpipe::common::type::Integer noteVelocity;
   148 			relpipe::common::type::Integer controllerId;
   152 			relpipe::common::type::Integer controllerId;
   149 			relpipe::common::type::Integer controllerValue;
   153 			relpipe::common::type::Integer controllerValue;
   150 			relpipe::common::type::StringX raw;
   154 			relpipe::common::type::StringX raw;
       
   155 			relpipe::common::type::StringX connectionSourcePort;
       
   156 			relpipe::common::type::StringX connectionDestinationPort;
   151 
   157 
   152 			size_t attributeIndex = 0;
   158 			size_t attributeIndex = 0;
   153 
   159 
   154 		} recordContext;
   160 		} recordContext;
   155 
   161 
   223 		relationContext = RelationContext();
   229 		relationContext = RelationContext();
   224 		relationContext.attributes = attributes;
   230 		relationContext.attributes = attributes;
   225 
   231 
   226 		// TODO: configurable relation name
   232 		// TODO: configurable relation name
   227 
   233 
   228 		if (!relationContext.hasAttribute(L"raw")) {
   234 		if (!relationContext.hasAttribute(L"event")) {
   229 			relationContext.skip = true;
   235 			relationContext.skip = true;
   230 			fwprintf(stderr, L"Relation „%ls“ will be ignored because mandatory attribute „raw“ is missing.\n", name.c_str());
   236 			fwprintf(stderr, L"Relation „%ls“ will be ignored because mandatory attribute „event“ is missing.\n", name.c_str());
   231 		}
   237 		}
   232 
   238 
   233 	}
   239 	}
   234 
   240 
   235 	void attribute(const relpipe::common::type::StringX& value) override {
   241 	void attribute(const relpipe::common::type::StringX& value) override {
   247 		else if (attributeName == L"controller_value") rec.controllerValue = std::stoi(value);
   253 		else if (attributeName == L"controller_value") rec.controllerValue = std::stoi(value);
   248 		else if (attributeName == L"note_on") rec.noteOn = value == L"true";
   254 		else if (attributeName == L"note_on") rec.noteOn = value == L"true";
   249 		else if (attributeName == L"note_pitch") rec.notePitch = std::stoi(value);
   255 		else if (attributeName == L"note_pitch") rec.notePitch = std::stoi(value);
   250 		else if (attributeName == L"note_velocity") rec.noteVelocity = std::stoi(value);
   256 		else if (attributeName == L"note_velocity") rec.noteVelocity = std::stoi(value);
   251 		else if (attributeName == L"raw") rec.raw = value;
   257 		else if (attributeName == L"raw") rec.raw = value;
       
   258 		else if (attributeName == L"source_port") rec.connectionSourcePort = value;
       
   259 		else if (attributeName == L"destination_port") rec.connectionDestinationPort = value;
   252 
   260 
   253 		rec.attributeIndex++;
   261 		rec.attributeIndex++;
   254 
   262 
   255 		if (rec.attributeIndex == rel.attributes.size()) {
   263 		if (rec.attributeIndex == rel.attributes.size()) {
   256 
   264 
   259 
   267 
   260 			MidiMessage m;
   268 			MidiMessage m;
   261 
   269 
   262 			// TODO: correct timing?
   270 			// TODO: correct timing?
   263 			m.time = 0;
   271 			m.time = 0;
       
   272 			m.size = 0;
   264 
   273 
   265 			if (rec.event == RelationContext::RecordContext::Event::NOTE) {
   274 			if (rec.event == RelationContext::RecordContext::Event::NOTE) {
   266 				m.size = 3;
   275 				m.size = 3;
   267 				m.buffer[0] = (rec.noteOn ? 0x90 : 0x80) | rec.channel;
   276 				m.buffer[0] = (rec.noteOn ? 0x90 : 0x80) | rec.channel;
   268 				m.buffer[1] = rec.notePitch;
   277 				m.buffer[1] = rec.notePitch;
   270 			} else if (rec.event == RelationContext::RecordContext::Event::CONTROL) {
   279 			} else if (rec.event == RelationContext::RecordContext::Event::CONTROL) {
   271 				m.size = 3;
   280 				m.size = 3;
   272 				m.buffer[0] = 0xB0 | rec.channel;
   281 				m.buffer[0] = 0xB0 | rec.channel;
   273 				m.buffer[1] = rec.controllerId;
   282 				m.buffer[1] = rec.controllerId;
   274 				m.buffer[2] = rec.controllerValue;
   283 				m.buffer[2] = rec.controllerValue;
       
   284 			} else if (rec.event == RelationContext::RecordContext::Event::CONNECT) {
       
   285 				int result = jack_connect(realTimeContext.jackClient, convertor.to_bytes(rec.connectionSourcePort).c_str(), convertor.to_bytes(rec.connectionDestinationPort).c_str());
       
   286 				if (result != 0 && result != EEXIST) std::wcerr << L"Unable to connect: „" << rec.connectionSourcePort << L"“ to: „" << rec.connectionDestinationPort << L"“." << std::endl;
       
   287 			} else if (rec.event == RelationContext::RecordContext::Event::DISCONNECT) {
       
   288 				int result = jack_disconnect(realTimeContext.jackClient, convertor.to_bytes(rec.connectionSourcePort).c_str(), convertor.to_bytes(rec.connectionDestinationPort).c_str());
       
   289 				if (result != 0) std::wcerr << L"Unable to disconnect: „" << rec.connectionSourcePort << L"“ from: „" << rec.connectionDestinationPort << L"“." << std::endl;
   275 			} else { // SysEx and other raw messages
   290 			} else { // SysEx and other raw messages
   276 				m.size = 0;
       
   277 				size_t nibble = 0;
   291 				size_t nibble = 0;
   278 				for (int i = 0; i < rec.raw.size() && m.size < sizeof (m.buffer); i++) {
   292 				for (int i = 0; i < rec.raw.size() && m.size < sizeof (m.buffer); i++) {
   279 					wchar_t ch = rec.raw[i];
   293 					wchar_t ch = rec.raw[i];
   280 
   294 
   281 					if (ch == L' ') continue;
   295 					if (ch == L' ') continue;
   287 					nibble++;
   301 					nibble++;
   288 					if (nibble % 2 == 0) m.size++;
   302 					if (nibble % 2 == 0) m.size++;
   289 				}
   303 				}
   290 			}
   304 			}
   291 
   305 
   292 			// TODO: if (m.size == 0) fwprintf(stderr, L"Missing data\n");
   306 			if (m.size > 0) jack_ringbuffer_write(realTimeContext.ringBuffer, (const char *) &m, sizeof (m));
   293 
       
   294 			jack_ringbuffer_write(realTimeContext.ringBuffer, (const char *) &m, sizeof (m));
       
   295 
   307 
   296 			relationContext.recordContext = RelationContext::RecordContext();
   308 			relationContext.recordContext = RelationContext::RecordContext();
   297 		}
   309 		}
   298 
   310 
   299 	}
   311 	}