src/JackCommand.h
branchv_0
changeset 15 463ce61415f1
parent 14 cde9bb07ea0a
child 16 79520ded76f0
equal deleted inserted replaced
14:cde9bb07ea0a 15:463ce61415f1
    27 #include <functional>
    27 #include <functional>
    28 #include <iomanip>
    28 #include <iomanip>
    29 #include <regex>
    29 #include <regex>
    30 
    30 
    31 #include <jack/jack.h>
    31 #include <jack/jack.h>
       
    32 #include <jack/metadata.h>
       
    33 #include <jack/uuid.h>
    32 #include <jack/midiport.h>
    34 #include <jack/midiport.h>
    33 #include <jack/ringbuffer.h>
    35 #include <jack/ringbuffer.h>
    34 
    36 
    35 #include <relpipe/common/type/typedefs.h>
    37 #include <relpipe/common/type/typedefs.h>
    36 #include <relpipe/writer/RelationalWriter.h>
    38 #include <relpipe/writer/RelationalWriter.h>
   175 	void listPorts(std::shared_ptr<relpipe::writer::RelationalWriter> writer) {
   177 	void listPorts(std::shared_ptr<relpipe::writer::RelationalWriter> writer) {
   176 		using namespace relpipe::writer;
   178 		using namespace relpipe::writer;
   177 		vector<AttributeMetadata> metadata;
   179 		vector<AttributeMetadata> metadata;
   178 
   180 
   179 		metadata.push_back({L"name", TypeId::STRING});
   181 		metadata.push_back({L"name", TypeId::STRING});
       
   182 		metadata.push_back({L"uuid", TypeId::STRING});
   180 		metadata.push_back({L"input", TypeId::BOOLEAN});
   183 		metadata.push_back({L"input", TypeId::BOOLEAN});
   181 		metadata.push_back({L"output", TypeId::BOOLEAN});
   184 		metadata.push_back({L"output", TypeId::BOOLEAN});
   182 		metadata.push_back({L"physical", TypeId::BOOLEAN});
   185 		metadata.push_back({L"physical", TypeId::BOOLEAN});
   183 		metadata.push_back({L"terminal", TypeId::BOOLEAN});
   186 		metadata.push_back({L"terminal", TypeId::BOOLEAN});
   184 		metadata.push_back({L"mine", TypeId::BOOLEAN});
   187 		metadata.push_back({L"mine", TypeId::BOOLEAN});
   202 			bool isTerminal = portFlags & JackPortFlags::JackPortIsTerminal;
   205 			bool isTerminal = portFlags & JackPortFlags::JackPortIsTerminal;
   203 			bool isMine = jack_port_is_mine(realTimeContext.jackClient, port);
   206 			bool isMine = jack_port_is_mine(realTimeContext.jackClient, port);
   204 			bool isMidi = std::regex_search(portType, midiTypePattern);
   207 			bool isMidi = std::regex_search(portType, midiTypePattern);
   205 
   208 
   206 			writer->writeAttribute(convertor.from_bytes(*portName));
   209 			writer->writeAttribute(convertor.from_bytes(*portName));
       
   210 			writer->writeAttribute(convertor.from_bytes(uuidToString(jack_port_uuid(port))));
   207 			writer->writeAttribute(&isInput, typeid (isInput));
   211 			writer->writeAttribute(&isInput, typeid (isInput));
   208 			writer->writeAttribute(&isOuputput, typeid (isOuputput));
   212 			writer->writeAttribute(&isOuputput, typeid (isOuputput));
   209 			writer->writeAttribute(&isPhysical, typeid (isPhysical));
   213 			writer->writeAttribute(&isPhysical, typeid (isPhysical));
   210 			writer->writeAttribute(&isTerminal, typeid (isTerminal));
   214 			writer->writeAttribute(&isTerminal, typeid (isTerminal));
   211 			writer->writeAttribute(&isMine, typeid (isMine));
   215 			writer->writeAttribute(&isMine, typeid (isMine));
   244 		}
   248 		}
   245 
   249 
   246 		jack_free(sourcePortNames);
   250 		jack_free(sourcePortNames);
   247 	}
   251 	}
   248 
   252 
       
   253 	std::string uuidToString(jack_uuid_t uuid) {
       
   254 		char buffer[JACK_UUID_STRING_SIZE] = {0};
       
   255 		jack_uuid_unparse(uuid, buffer);
       
   256 		return buffer;
       
   257 	}
       
   258 
       
   259 	void listProperties(std::shared_ptr<relpipe::writer::RelationalWriter> writer) {
       
   260 		using namespace relpipe::writer;
       
   261 		vector<AttributeMetadata> metadata;
       
   262 
       
   263 		metadata.push_back({L"uuid", TypeId::STRING});
       
   264 		//metadata.push_back({L"port", TypeId::STRING}); // TODO: port name
       
   265 		metadata.push_back({L"name", TypeId::STRING});
       
   266 		metadata.push_back({L"type", TypeId::STRING});
       
   267 		metadata.push_back({L"value", TypeId::STRING});
       
   268 		writer->startRelation(L"property", metadata, true);
       
   269 
       
   270 		jack_description_t* descriptions = nullptr;
       
   271 
       
   272 		int descriptionsCount = jack_get_all_properties(&descriptions);
       
   273 
       
   274 		for (int i = 0; i < descriptionsCount; i++) {
       
   275 			jack_description_t* description = &descriptions[i];
       
   276 			for (uint32_t j = 0; j < description->property_cnt; j++) {
       
   277 				jack_property_t* property = &description->properties[j];
       
   278 				writer->writeAttribute(convertor.from_bytes(uuidToString(description->subject)));
       
   279 				//writer->writeAttribute(L"TODO: port name"); // TODO: port name
       
   280 				writer->writeAttribute(convertor.from_bytes(property->key));
       
   281 				writer->writeAttribute(convertor.from_bytes(property->type));
       
   282 				writer->writeAttribute(convertor.from_bytes(property->data)); // TODO: format value (some in HEX), according to .type
       
   283 			}
       
   284 			jack_free_description(description, false);
       
   285 		}
       
   286 		jack_free(descriptions);
       
   287 	}
       
   288 
   249 	void applyConnectionRecipes() {
   289 	void applyConnectionRecipes() {
   250 		for (Configuration::ConnectionRecipe recipe : configuration.connectionRecipes) {
   290 		for (Configuration::ConnectionRecipe recipe : configuration.connectionRecipes) {
   251 			auto operation = recipe.connected ? jack_connect : jack_disconnect;
   291 			auto operation = recipe.connected ? jack_connect : jack_disconnect;
   252 			int result = operation(realTimeContext.jackClient, convertor.to_bytes(recipe.sourcePort).c_str(), convertor.to_bytes(recipe.destinationPort).c_str());
   292 			int result = operation(realTimeContext.jackClient, convertor.to_bytes(recipe.sourcePort).c_str(), convertor.to_bytes(recipe.destinationPort).c_str());
   253 			if (result != 0 && result != EEXIST) std::wcerr << L"Unable to " << (recipe.connected ? L"connect" : L"disconnect") << L": „" << recipe.sourcePort << L"“ to: „" << recipe.destinationPort << L"“." << std::endl;
   293 			if (result != 0 && result != EEXIST) std::wcerr << L"Unable to " << (recipe.connected ? L"connect" : L"disconnect") << L": „" << recipe.sourcePort << L"“ to: „" << recipe.destinationPort << L"“." << std::endl;
   321 
   361 
   322 		applyConnectionRecipes();
   362 		applyConnectionRecipes();
   323 
   363 
   324 		if (configuration.listPorts) listPorts(writer);
   364 		if (configuration.listPorts) listPorts(writer);
   325 		if (configuration.listConnections) listConnections(writer);
   365 		if (configuration.listConnections) listConnections(writer);
       
   366 		if (configuration.listProperties) listProperties(writer);
   326 		if (!configuration.listMidiMessages) return;
   367 		if (!configuration.listMidiMessages) return;
   327 
   368 
   328 		metadata.push_back({L"event", TypeId::STRING});
   369 		metadata.push_back({L"event", TypeId::STRING});
   329 		metadata.push_back({L"channel", TypeId::INTEGER});
   370 		metadata.push_back({L"channel", TypeId::INTEGER});
   330 		metadata.push_back({L"note_on", TypeId::BOOLEAN});
   371 		metadata.push_back({L"note_on", TypeId::BOOLEAN});