src/JackCommand.h
branchv_0
changeset 11 07247893054e
parent 10 ded44e94147c
child 12 e8aae4d42c01
equal deleted inserted replaced
10:ded44e94147c 11:07247893054e
    24 #include <sys/mman.h>
    24 #include <sys/mman.h>
    25 #include <unistd.h>
    25 #include <unistd.h>
    26 #include <pthread.h>
    26 #include <pthread.h>
    27 #include <functional>
    27 #include <functional>
    28 #include <iomanip>
    28 #include <iomanip>
       
    29 #include <regex>
    29 
    30 
    30 #include <jack/jack.h>
    31 #include <jack/jack.h>
    31 #include <jack/midiport.h>
    32 #include <jack/midiport.h>
    32 #include <jack/ringbuffer.h>
    33 #include <jack/ringbuffer.h>
    33 
    34 
   169 		}
   170 		}
   170 
   171 
   171 		return result.str();
   172 		return result.str();
   172 	}
   173 	}
   173 
   174 
       
   175 	void listPorts(std::shared_ptr<relpipe::writer::RelationalWriter> writer) {
       
   176 		using namespace relpipe::writer;
       
   177 		vector<AttributeMetadata> metadata;
       
   178 
       
   179 		metadata.push_back({L"name", TypeId::STRING});
       
   180 		metadata.push_back({L"input", TypeId::BOOLEAN});
       
   181 		metadata.push_back({L"output", TypeId::BOOLEAN});
       
   182 		metadata.push_back({L"physical", TypeId::BOOLEAN});
       
   183 		metadata.push_back({L"terminal", TypeId::BOOLEAN});
       
   184 		metadata.push_back({L"mine", TypeId::BOOLEAN});
       
   185 		metadata.push_back({L"midi", TypeId::BOOLEAN});
       
   186 		metadata.push_back({L"type", TypeId::STRING});
       
   187 		writer->startRelation(L"port", metadata, true);
       
   188 
       
   189 		const char** portNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, 0);
       
   190 		
       
   191 		std::regex midiTypePattern(".*midi$");
       
   192 
       
   193 		for (const char** portName = portNames; *portName; portName++) {
       
   194 			jack_port_t* port = jack_port_by_name(realTimeContext.jackClient, *portName);
       
   195 
       
   196 			const char* portType = jack_port_type(port);
       
   197 			int portFlags = jack_port_flags(port);
       
   198 
       
   199 			bool isInput = portFlags & JackPortFlags::JackPortIsInput;
       
   200 			bool isOuputput = portFlags & JackPortFlags::JackPortIsOutput;
       
   201 			bool isPhysical = portFlags & JackPortFlags::JackPortIsPhysical;
       
   202 			bool isTerminal = portFlags & JackPortFlags::JackPortIsTerminal;
       
   203 			bool isMine = jack_port_is_mine(realTimeContext.jackClient, port);
       
   204 			bool isMidi = std::regex_search(portType, midiTypePattern);
       
   205 
       
   206 			writer->writeAttribute(convertor.from_bytes(*portName));
       
   207 			writer->writeAttribute(&isInput, typeid (isInput));
       
   208 			writer->writeAttribute(&isOuputput, typeid (isOuputput));
       
   209 			writer->writeAttribute(&isPhysical, typeid (isPhysical));
       
   210 			writer->writeAttribute(&isTerminal, typeid (isTerminal));
       
   211 			writer->writeAttribute(&isMine, typeid (isMine));
       
   212 			writer->writeAttribute(&isMidi, typeid (isMidi));
       
   213 			writer->writeAttribute(convertor.from_bytes(portType));
       
   214 		}
       
   215 
       
   216 		jack_free(portNames);
       
   217 	}
       
   218 
   174 	static void jackErrorCallback(const char * message) {
   219 	static void jackErrorCallback(const char * message) {
   175 		std::wstring_convert < std::codecvt_utf8<wchar_t>> convertor; // TODO: local system encoding
   220 		std::wstring_convert < std::codecvt_utf8<wchar_t>> convertor; // TODO: local system encoding
   176 		std::wcerr << L"JACK: " << convertor.from_bytes(message) << std::endl;
   221 		std::wcerr << L"JACK: " << convertor.from_bytes(message) << std::endl;
   177 	}
   222 	}
   178 
   223 
   233 
   278 
   234 	void processJackStream(std::shared_ptr<relpipe::writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
   279 	void processJackStream(std::shared_ptr<relpipe::writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
   235 		// Relation headers:
   280 		// Relation headers:
   236 		using namespace relpipe::writer;
   281 		using namespace relpipe::writer;
   237 		vector<AttributeMetadata> metadata;
   282 		vector<AttributeMetadata> metadata;
       
   283 
       
   284 		if (configuration.listJackPorts) listPorts(writer);
       
   285 		if (!configuration.listMidiMessages) return;
       
   286 
   238 		metadata.push_back({L"event", TypeId::STRING});
   287 		metadata.push_back({L"event", TypeId::STRING});
   239 		metadata.push_back({L"channel", TypeId::INTEGER});
   288 		metadata.push_back({L"channel", TypeId::INTEGER});
   240 		metadata.push_back({L"note_on", TypeId::BOOLEAN});
   289 		metadata.push_back({L"note_on", TypeId::BOOLEAN});
   241 		metadata.push_back({L"note_pitch", TypeId::INTEGER});
   290 		metadata.push_back({L"note_pitch", TypeId::INTEGER});
   242 		metadata.push_back({L"note_velocity", TypeId::INTEGER});
   291 		metadata.push_back({L"note_velocity", TypeId::INTEGER});