src/JackHandler.h
branchv_0
changeset 23 d2ad84dcf249
parent 21 70b252d02a92
child 24 427b8d799a4a
equal deleted inserted replaced
22:eebc16b7c3e4 23:d2ad84dcf249
   184 
   184 
   185 	JackHandler(Configuration& configuration) : configuration(configuration) {
   185 	JackHandler(Configuration& configuration) : configuration(configuration) {
   186 		pthread_mutex_lock(&realTimeContext.processingLock);
   186 		pthread_mutex_lock(&realTimeContext.processingLock);
   187 
   187 
   188 		// Initialize JACK connection:
   188 		// Initialize JACK connection:
   189 		std::string clientName = convertor.to_bytes(configuration.jackClientName);
   189 		std::string clientName = convertor.to_bytes(configuration.client);
   190 		realTimeContext.jackClient = jack_client_open(clientName.c_str(), JackNullOption, nullptr);
   190 		realTimeContext.jackClient = jack_client_open(clientName.c_str(), JackNullOption, nullptr);
   191 		if (realTimeContext.jackClient == nullptr) failInConstructor(L"Could not create JACK client.");
   191 		if (realTimeContext.jackClient == nullptr) failInConstructor(L"Could not create JACK client.");
   192 
   192 
   193 		realTimeContext.ringBuffer = jack_ringbuffer_create(realTimeContext.RING_BUFFER_SIZE * sizeof (MidiMessage));
   193 		realTimeContext.ringBuffer = jack_ringbuffer_create(realTimeContext.RING_BUFFER_SIZE * sizeof (MidiMessage));
   194 
   194 
   196 		jack_set_sync_callback(realTimeContext.jackClient, RealTimeContext::syncCallback, &realTimeContext);
   196 		jack_set_sync_callback(realTimeContext.jackClient, RealTimeContext::syncCallback, &realTimeContext);
   197 		// TODO: report also other events (connections etc.)
   197 		// TODO: report also other events (connections etc.)
   198 		jack_set_error_function(jackErrorCallback);
   198 		jack_set_error_function(jackErrorCallback);
   199 		jack_set_info_function(jackErrorCallback);
   199 		jack_set_info_function(jackErrorCallback);
   200 
   200 
   201 		realTimeContext.jackPort = jack_port_register(realTimeContext.jackClient, "output", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
   201 		realTimeContext.jackPort = jack_port_register(realTimeContext.jackClient, convertor.to_bytes(configuration.port).c_str(), JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
   202 		if (realTimeContext.jackPort == nullptr) failInConstructor(L"Could not register the JACK port.");
   202 		if (realTimeContext.jackPort == nullptr) failInConstructor(L"Could not register the JACK port.");
   203 
   203 
   204 		if (mlockall(MCL_CURRENT | MCL_FUTURE)) fwprintf(stderr, L"Warning: Can not lock memory.\n");
   204 		if (mlockall(MCL_CURRENT | MCL_FUTURE)) fwprintf(stderr, L"Warning: Can not lock memory.\n");
   205 
   205 
   206 		int jackError = jack_activate(realTimeContext.jackClient);
   206 		int jackError = jack_activate(realTimeContext.jackClient);
   207 		if (jackError) failInConstructor(L"Could not activate the JACK client.");
   207 		if (jackError) failInConstructor(L"Could not activate the JACK client.");
   208 
   208 
   209 
   209 
   210 		// Connect to configured destination ports:
   210 		// Connect to configured destination ports:
   211 		const char* jackPortName = jack_port_name(realTimeContext.jackPort);
   211 		const char* jackPortName = jack_port_name(realTimeContext.jackPort);
   212 		for (auto destinationPort : configuration.portsToConnect) {
   212 		for (auto destinationPort : configuration.connectTo) {
   213 			int error = jack_connect(realTimeContext.jackClient, jackPortName, convertor.to_bytes(destinationPort).c_str());
   213 			int error = jack_connect(realTimeContext.jackClient, jackPortName, convertor.to_bytes(destinationPort).c_str());
   214 			if (error) failInConstructor(L"Connection to the JACK port failed: " + destinationPort);
   214 			if (error) failInConstructor(L"Connection to the JACK port failed: " + destinationPort);
   215 		}
   215 		}
   216 
   216 
   217 		// Wait for a port connection, because it does not make much sense to send MIDI events nowhere:
   217 		// Wait for a port connection, because it does not make much sense to send MIDI events nowhere:
   218 		while (jack_port_connected(realTimeContext.jackPort) < configuration.requiredJackConnections) usleep(10000);
   218 		while (jack_port_connected(realTimeContext.jackPort) < configuration.requiredConnections) usleep(10000);
   219 
   219 
   220 	}
   220 	}
   221 
   221 
   222 	void startRelation(const relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
   222 	void startRelation(const relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
   223 		relationContext = RelationContext();
   223 		relationContext = RelationContext();