src/JackCommand.h
branchv_0
changeset 11 07247893054e
parent 10 ded44e94147c
child 12 e8aae4d42c01
--- a/src/JackCommand.h	Tue Oct 06 16:55:22 2020 +0200
+++ b/src/JackCommand.h	Wed Oct 07 01:45:30 2020 +0200
@@ -26,6 +26,7 @@
 #include <pthread.h>
 #include <functional>
 #include <iomanip>
+#include <regex>
 
 #include <jack/jack.h>
 #include <jack/midiport.h>
@@ -171,6 +172,50 @@
 		return result.str();
 	}
 
+	void listPorts(std::shared_ptr<relpipe::writer::RelationalWriter> writer) {
+		using namespace relpipe::writer;
+		vector<AttributeMetadata> metadata;
+
+		metadata.push_back({L"name", TypeId::STRING});
+		metadata.push_back({L"input", TypeId::BOOLEAN});
+		metadata.push_back({L"output", TypeId::BOOLEAN});
+		metadata.push_back({L"physical", TypeId::BOOLEAN});
+		metadata.push_back({L"terminal", TypeId::BOOLEAN});
+		metadata.push_back({L"mine", TypeId::BOOLEAN});
+		metadata.push_back({L"midi", TypeId::BOOLEAN});
+		metadata.push_back({L"type", TypeId::STRING});
+		writer->startRelation(L"port", metadata, true);
+
+		const char** portNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, 0);
+		
+		std::regex midiTypePattern(".*midi$");
+
+		for (const char** portName = portNames; *portName; portName++) {
+			jack_port_t* port = jack_port_by_name(realTimeContext.jackClient, *portName);
+
+			const char* portType = jack_port_type(port);
+			int portFlags = jack_port_flags(port);
+
+			bool isInput = portFlags & JackPortFlags::JackPortIsInput;
+			bool isOuputput = portFlags & JackPortFlags::JackPortIsOutput;
+			bool isPhysical = portFlags & JackPortFlags::JackPortIsPhysical;
+			bool isTerminal = portFlags & JackPortFlags::JackPortIsTerminal;
+			bool isMine = jack_port_is_mine(realTimeContext.jackClient, port);
+			bool isMidi = std::regex_search(portType, midiTypePattern);
+
+			writer->writeAttribute(convertor.from_bytes(*portName));
+			writer->writeAttribute(&isInput, typeid (isInput));
+			writer->writeAttribute(&isOuputput, typeid (isOuputput));
+			writer->writeAttribute(&isPhysical, typeid (isPhysical));
+			writer->writeAttribute(&isTerminal, typeid (isTerminal));
+			writer->writeAttribute(&isMine, typeid (isMine));
+			writer->writeAttribute(&isMidi, typeid (isMidi));
+			writer->writeAttribute(convertor.from_bytes(portType));
+		}
+
+		jack_free(portNames);
+	}
+
 	static void jackErrorCallback(const char * message) {
 		std::wstring_convert < std::codecvt_utf8<wchar_t>> convertor; // TODO: local system encoding
 		std::wcerr << L"JACK: " << convertor.from_bytes(message) << std::endl;
@@ -235,6 +280,10 @@
 		// Relation headers:
 		using namespace relpipe::writer;
 		vector<AttributeMetadata> metadata;
+
+		if (configuration.listJackPorts) listPorts(writer);
+		if (!configuration.listMidiMessages) return;
+
 		metadata.push_back({L"event", TypeId::STRING});
 		metadata.push_back({L"channel", TypeId::INTEGER});
 		metadata.push_back({L"note_on", TypeId::BOOLEAN});