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 *) ¤tMidiMessage, sizeof (MidiMessage)); |
132 jack_ringbuffer_write(ringBuffer, (const char *) ¤tMidiMessage, 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 |