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 |
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 } |