src/JackCommand.h
branchv_0
changeset 12 e8aae4d42c01
parent 11 07247893054e
child 13 326935d1bfab
equal deleted inserted replaced
11:07247893054e 12:e8aae4d42c01
   245 
   245 
   246 	JackCommand(Configuration& configuration) : configuration(configuration) {
   246 	JackCommand(Configuration& configuration) : configuration(configuration) {
   247 		pthread_mutex_lock(&realTimeContext.processingLock);
   247 		pthread_mutex_lock(&realTimeContext.processingLock);
   248 
   248 
   249 		// Initialize JACK connection:
   249 		// Initialize JACK connection:
   250 		std::string clientName = convertor.to_bytes(configuration.jackClientName);
   250 		std::string clientName = convertor.to_bytes(configuration.client);
   251 		realTimeContext.jackClient = jack_client_open(clientName.c_str(), JackNullOption, nullptr);
   251 		realTimeContext.jackClient = jack_client_open(clientName.c_str(), JackNullOption, nullptr);
   252 		if (realTimeContext.jackClient == nullptr) failInConstructor(L"Could not create JACK client.");
   252 		if (realTimeContext.jackClient == nullptr) failInConstructor(L"Could not create JACK client.");
   253 
   253 
   254 		realTimeContext.ringBuffer = jack_ringbuffer_create(realTimeContext.RING_BUFFER_SIZE * sizeof (MidiMessage));
   254 		realTimeContext.ringBuffer = jack_ringbuffer_create(realTimeContext.RING_BUFFER_SIZE * sizeof (MidiMessage));
   255 
   255 
   256 		jack_set_process_callback(realTimeContext.jackClient, RealTimeContext::processCallback, &realTimeContext);
   256 		jack_set_process_callback(realTimeContext.jackClient, RealTimeContext::processCallback, &realTimeContext);
   257 		// TODO: report also other events (connections etc.)
   257 		// TODO: report also other events (connections etc.)
   258 		jack_set_error_function(jackErrorCallback);
   258 		jack_set_error_function(jackErrorCallback);
   259 		jack_set_info_function(jackErrorCallback);
   259 		jack_set_info_function(jackErrorCallback);
   260 
   260 
   261 		realTimeContext.jackPort = jack_port_register(realTimeContext.jackClient, "input", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
   261 		realTimeContext.jackPort = jack_port_register(realTimeContext.jackClient, convertor.to_bytes(configuration.port).c_str(), JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
   262 		if (realTimeContext.jackPort == nullptr) failInConstructor(L"Could not register the JACK port.");
   262 		if (realTimeContext.jackPort == nullptr) failInConstructor(L"Could not register the JACK port.");
   263 
   263 
   264 		if (mlockall(MCL_CURRENT | MCL_FUTURE)) fwprintf(stderr, L"Warning: Can not lock memory.\n");
   264 		if (mlockall(MCL_CURRENT | MCL_FUTURE)) fwprintf(stderr, L"Warning: Can not lock memory.\n");
   265 
   265 
   266 		int jackError = jack_activate(realTimeContext.jackClient);
   266 		int jackError = jack_activate(realTimeContext.jackClient);
   267 		if (jackError) failInConstructor(L"Could not activate the JACK client.");
   267 		if (jackError) failInConstructor(L"Could not activate the JACK client.");
   268 
   268 
   269 
   269 
   270 		// Connect to configured destination ports:
   270 		// Connect to configured destination ports:
   271 		const char* jackPortName = jack_port_name(realTimeContext.jackPort);
   271 		const char* jackPortName = jack_port_name(realTimeContext.jackPort);
   272 		for (auto sourcePort : configuration.portsToConnect) {
   272 		for (auto sourcePort : configuration.connectTo) {
   273 			int error = jack_connect(realTimeContext.jackClient, convertor.to_bytes(sourcePort).c_str(), jackPortName);
   273 			int error = jack_connect(realTimeContext.jackClient, convertor.to_bytes(sourcePort).c_str(), jackPortName);
   274 			if (error) failInConstructor(L"Connection to the JACK port failed: " + sourcePort);
   274 			if (error) failInConstructor(L"Connection to the JACK port failed: " + sourcePort);
   275 		}
   275 		}
   276 
   276 
   277 	}
   277 	}
   279 	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) {
   280 		// Relation headers:
   280 		// Relation headers:
   281 		using namespace relpipe::writer;
   281 		using namespace relpipe::writer;
   282 		vector<AttributeMetadata> metadata;
   282 		vector<AttributeMetadata> metadata;
   283 
   283 
   284 		if (configuration.listJackPorts) listPorts(writer);
   284 		if (configuration.listPorts) listPorts(writer);
   285 		if (!configuration.listMidiMessages) return;
   285 		if (!configuration.listMidiMessages) return;
   286 
   286 
   287 		metadata.push_back({L"event", TypeId::STRING});
   287 		metadata.push_back({L"event", TypeId::STRING});
   288 		metadata.push_back({L"channel", TypeId::INTEGER});
   288 		metadata.push_back({L"channel", TypeId::INTEGER});
   289 		metadata.push_back({L"note_on", TypeId::BOOLEAN});
   289 		metadata.push_back({L"note_on", TypeId::BOOLEAN});
   304 				relationalWriterFlush();
   304 				relationalWriterFlush();
   305 			}
   305 			}
   306 			waitForRTCycle();
   306 			waitForRTCycle();
   307 
   307 
   308 			// Once the Configuration::requiredJackConnections count was reached, we will disconnect if the count drops under this level.
   308 			// Once the Configuration::requiredJackConnections count was reached, we will disconnect if the count drops under this level.
   309 			if (configuration.requiredJackConnections) {
   309 			if (configuration.requiredConnections) {
   310 				int currentConnectionCount = jack_port_connected(realTimeContext.jackPort);
   310 				int currentConnectionCount = jack_port_connected(realTimeContext.jackPort);
   311 				if (currentConnectionCount > maxJackPortConnections) maxJackPortConnections = currentConnectionCount;
   311 				if (currentConnectionCount > maxJackPortConnections) maxJackPortConnections = currentConnectionCount;
   312 				else if (maxJackPortConnections >= configuration.requiredJackConnections && currentConnectionCount < configuration.requiredJackConnections) break;
   312 				else if (maxJackPortConnections >= configuration.requiredConnections && currentConnectionCount < configuration.requiredConnections) break;
   313 			}
   313 			}
   314 		}
   314 		}
   315 	}
   315 	}
   316 
   316 
   317 	void finish(int sig) {
   317 	void finish(int sig) {