# HG changeset patch # User František Kučera # Date 1602105028 -7200 # Node ID 427b8d799a4a449e19b075c8907bda2ee2ff81fc # Parent d2ad84dcf249710a02dea856452bec37519591ab add „connect“ and „disconnect“ events + „source_port“ and „destination_port“ attributes to allow connecting and disconnecting arbitrary JACK ports diff -r d2ad84dcf249 -r 427b8d799a4a src/JackHandler.h --- a/src/JackHandler.h Wed Oct 07 22:30:09 2020 +0200 +++ b/src/JackHandler.h Wed Oct 07 23:10:28 2020 +0200 @@ -130,6 +130,8 @@ NOTE, CONTROL, SYSEX, + CONNECT, + DISCONNECT, UNKNOWN }; @@ -137,6 +139,8 @@ if (name == L"note") return Event::NOTE; else if (name == L"control") return Event::CONTROL; else if (name == L"sysex") return Event::SYSEX; + else if (name == L"connect") return Event::CONNECT; + else if (name == L"disconnect") return Event::DISCONNECT; else return Event::UNKNOWN; } @@ -148,6 +152,8 @@ relpipe::common::type::Integer controllerId; relpipe::common::type::Integer controllerValue; relpipe::common::type::StringX raw; + relpipe::common::type::StringX connectionSourcePort; + relpipe::common::type::StringX connectionDestinationPort; size_t attributeIndex = 0; @@ -225,9 +231,9 @@ // TODO: configurable relation name - if (!relationContext.hasAttribute(L"raw")) { + if (!relationContext.hasAttribute(L"event")) { relationContext.skip = true; - fwprintf(stderr, L"Relation „%ls“ will be ignored because mandatory attribute „raw“ is missing.\n", name.c_str()); + fwprintf(stderr, L"Relation „%ls“ will be ignored because mandatory attribute „event“ is missing.\n", name.c_str()); } } @@ -249,6 +255,8 @@ 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; + else if (attributeName == L"source_port") rec.connectionSourcePort = value; + else if (attributeName == L"destination_port") rec.connectionDestinationPort = value; rec.attributeIndex++; @@ -261,6 +269,7 @@ // TODO: correct timing? m.time = 0; + m.size = 0; if (rec.event == RelationContext::RecordContext::Event::NOTE) { m.size = 3; @@ -272,8 +281,13 @@ m.buffer[0] = 0xB0 | rec.channel; m.buffer[1] = rec.controllerId; m.buffer[2] = rec.controllerValue; + } else if (rec.event == RelationContext::RecordContext::Event::CONNECT) { + int result = jack_connect(realTimeContext.jackClient, convertor.to_bytes(rec.connectionSourcePort).c_str(), convertor.to_bytes(rec.connectionDestinationPort).c_str()); + if (result != 0 && result != EEXIST) std::wcerr << L"Unable to connect: „" << rec.connectionSourcePort << L"“ to: „" << rec.connectionDestinationPort << L"“." << std::endl; + } else if (rec.event == RelationContext::RecordContext::Event::DISCONNECT) { + int result = jack_disconnect(realTimeContext.jackClient, convertor.to_bytes(rec.connectionSourcePort).c_str(), convertor.to_bytes(rec.connectionDestinationPort).c_str()); + if (result != 0) std::wcerr << L"Unable to disconnect: „" << rec.connectionSourcePort << L"“ from: „" << rec.connectionDestinationPort << L"“." << std::endl; } else { // SysEx and other raw messages - m.size = 0; size_t nibble = 0; for (int i = 0; i < rec.raw.size() && m.size < sizeof (m.buffer); i++) { wchar_t ch = rec.raw[i]; @@ -289,9 +303,7 @@ } } - // TODO: if (m.size == 0) fwprintf(stderr, L"Missing data\n"); - - jack_ringbuffer_write(realTimeContext.ringBuffer, (const char *) &m, sizeof (m)); + if (m.size > 0) jack_ringbuffer_write(realTimeContext.ringBuffer, (const char *) &m, sizeof (m)); relationContext.recordContext = RelationContext::RecordContext(); }