src/JackHandler.h
branchv_0
changeset 8 27579c5cdc51
parent 7 b2fc99295546
child 9 14cf28d7681c
equal deleted inserted replaced
7:b2fc99295546 8:27579c5cdc51
    95 
    95 
    96 		int jackError = jack_activate(jackClient);
    96 		int jackError = jack_activate(jackClient);
    97 		if (jackError) throw JackException(L"Could not activate client.");
    97 		if (jackError) throw JackException(L"Could not activate client.");
    98 
    98 
    99 		// Wait for a port connection, because it does not make much sense to send MIDI events nowhere:
    99 		// Wait for a port connection, because it does not make much sense to send MIDI events nowhere:
   100 		// TODO: configurable waiting?
   100 		// TODO: configurable waiting (number of connections)
   101 		while (jack_port_connected(jackPort) == 0) usleep(10000);
   101 		while (jack_port_connected(jackPort) == 0) usleep(10000);
       
   102 
       
   103 		// TODO: configurable auto-connection to another client/port
   102 	}
   104 	}
   103 
   105 
   104 	void startRelation(const relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
   106 	void startRelation(const relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
   105 		// TODO: validate metadata and prepare attribute mappings (names and types are important, order does not matter)
   107 		// TODO: validate metadata and prepare attribute mappings (names and types are important, order does not matter)
   106 
   108 
   109 
   111 
   110 	void attribute(const relpipe::common::type::StringX& value) override {
   112 	void attribute(const relpipe::common::type::StringX& value) override {
   111 		// TODO: append to current message + if this is last attribute, put whole message to the ring buffer
   113 		// TODO: append to current message + if this is last attribute, put whole message to the ring buffer
   112 		// TODO: if (continueProcessing) {} ?
   114 		// TODO: if (continueProcessing) {} ?
   113 
   115 
   114 		if (currentAttributeIndex < currentAttributeCount) {
   116 		// memcpy(currentMidiMessage.buffer, ….buffer, ….size);
   115 			// memcpy(currentMidiMessage.buffer, ….buffer, ….size);
   117 		// currentMidiMessage.size = …;
   116 			// currentMidiMessage.size = …;
   118 		// currentMidiMessage.time = …;
   117 			// currentMidiMessage.time = …;
       
   118 
   119 
   119 			// TODO: correct timing?
   120 		// TODO: correct timing?
   120 			// TODO: real data
   121 		// TODO: real data
   121 			currentMidiMessage.time = 0;
   122 		currentMidiMessage.time = 0;
   122 			currentMidiMessage.size = 3;
   123 		currentMidiMessage.size = 3;
   123 			currentMidiMessage.buffer[0] = 0x80;
   124 		currentMidiMessage.buffer[0] = 0x90;
   124 			currentMidiMessage.buffer[1] = 0x34;
   125 		currentMidiMessage.buffer[1] = 0x24;
   125 			currentMidiMessage.buffer[2] = 0x40;
   126 		currentMidiMessage.buffer[2] = 0x40;
   126 
   127 
   127 			currentAttributeIndex++;
   128 		currentAttributeIndex++;
   128 		} else {
   129 
       
   130 		if (currentAttributeIndex == currentAttributeCount) {
   129 			if (jack_ringbuffer_write_space(ringBuffer) >= sizeof (MidiMessage)) {
   131 			if (jack_ringbuffer_write_space(ringBuffer) >= sizeof (MidiMessage)) {
   130 				jack_ringbuffer_write(ringBuffer, (const char *) &currentMidiMessage, sizeof (MidiMessage));
   132 				jack_ringbuffer_write(ringBuffer, (const char *) &currentMidiMessage, sizeof (MidiMessage));
   131 				std::cout << "jack_ringbuffer_write" << std::endl;
   133 				std::cout << "jack_ringbuffer_write" << std::endl;
   132 			} else {
   134 			} else {
   133 				fwprintf(stderr, L"Error: ring buffer is full → skipping event.\n");
   135 				fwprintf(stderr, L"Error: ring buffer is full → skipping event.\n");
   144 
   146 
   145 		// Wait until the ring buffer is empty
   147 		// Wait until the ring buffer is empty
   146 		while (continueProcessing && jack_ringbuffer_read_space(ringBuffer)) usleep(1000);
   148 		while (continueProcessing && jack_ringbuffer_read_space(ringBuffer)) usleep(1000);
   147 		usleep(1000000);
   149 		usleep(1000000);
   148 		// TODO: better waiting (ringBuffer might be empty, but events have not been sent to JACK yet)
   150 		// TODO: better waiting (ringBuffer might be empty, but events have not been sent to JACK yet)
       
   151 		// TODO: optionally mute all; probably enabled by default
   149 	}
   152 	}
   150 
   153 
   151 	int dequeueMessages(jack_nframes_t frames) {
   154 	int dequeueMessages(jack_nframes_t frames) {
   152 		const size_t queuedMessages = jack_ringbuffer_read_space(ringBuffer) / sizeof (MidiMessage);
   155 		const size_t queuedMessages = jack_ringbuffer_read_space(ringBuffer) / sizeof (MidiMessage);
   153 		void* jackPortBuffer = jack_port_get_buffer(jackPort, frames); // jack_port_get_buffer() must be called outside the loop, otherwise it will multiply the MIDI events
   156 		void* jackPortBuffer = jack_port_get_buffer(jackPort, frames); // jack_port_get_buffer() must be called outside the loop, otherwise it will multiply the MIDI events