113 |
113 |
114 if (currentAttributeIndex < currentAttributeCount) { |
114 if (currentAttributeIndex < currentAttributeCount) { |
115 // memcpy(currentMidiMessage.buffer, ….buffer, ….size); |
115 // memcpy(currentMidiMessage.buffer, ….buffer, ….size); |
116 // currentMidiMessage.size = …; |
116 // currentMidiMessage.size = …; |
117 // currentMidiMessage.time = …; |
117 // currentMidiMessage.time = …; |
118 |
118 |
119 // TODO: correct timing? |
119 // TODO: correct timing? |
120 // TODO: real data |
120 // TODO: real data |
|
121 currentMidiMessage.time = 0; |
121 currentMidiMessage.size = 3; |
122 currentMidiMessage.size = 3; |
122 currentMidiMessage.buffer[0] = 0x80; |
123 currentMidiMessage.buffer[0] = 0x80; |
123 currentMidiMessage.buffer[1] = 0x34; |
124 currentMidiMessage.buffer[1] = 0x34; |
124 currentMidiMessage.buffer[2] = 0x40; |
125 currentMidiMessage.buffer[2] = 0x40; |
125 |
126 |
126 currentAttributeIndex++; |
127 currentAttributeIndex++; |
127 } else { |
128 } else { |
128 if (jack_ringbuffer_write_space(ringBuffer) >= sizeof (MidiMessage)) { |
129 if (jack_ringbuffer_write_space(ringBuffer) >= sizeof (MidiMessage)) { |
129 jack_ringbuffer_write(ringBuffer, (const char *) ¤tMidiMessage, sizeof (MidiMessage)); |
130 jack_ringbuffer_write(ringBuffer, (const char *) ¤tMidiMessage, sizeof (MidiMessage)); |
|
131 std::cout << "jack_ringbuffer_write" << std::endl; |
130 } else { |
132 } else { |
131 fwprintf(stderr, L"Error: ring buffer is full → skipping event.\n"); |
133 fwprintf(stderr, L"Error: ring buffer is full → skipping event.\n"); |
132 } |
134 } |
133 |
135 |
134 currentMidiMessage = MidiMessage(); |
136 currentMidiMessage = MidiMessage(); |
140 void endOfPipe() { |
142 void endOfPipe() { |
141 // TODO: send optional (configurable) MIDI events |
143 // TODO: send optional (configurable) MIDI events |
142 |
144 |
143 // Wait until the ring buffer is empty |
145 // Wait until the ring buffer is empty |
144 while (continueProcessing && jack_ringbuffer_read_space(ringBuffer)) usleep(1000); |
146 while (continueProcessing && jack_ringbuffer_read_space(ringBuffer)) usleep(1000); |
|
147 usleep(1000000); |
|
148 // TODO: better waiting (ringBuffer might be empty, but events have not been sent to JACK yet) |
145 } |
149 } |
146 |
150 |
147 int dequeueMessages(jack_nframes_t frames) { |
151 int dequeueMessages(jack_nframes_t frames) { |
148 const size_t queuedMessages = jack_ringbuffer_read_space(ringBuffer) / sizeof (MidiMessage); |
152 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 |
|
154 jack_midi_clear_buffer(jackPortBuffer); // TODO: clean buffer? |
149 for (size_t i = 0; i < queuedMessages && i < frames; i++) { |
155 for (size_t i = 0; i < queuedMessages && i < frames; i++) { |
150 // TODO: correct timing? |
156 // TODO: correct timing? |
151 MidiMessage m; |
157 MidiMessage m; |
152 jack_ringbuffer_read(ringBuffer, (char*) &m, sizeof (MidiMessage)); |
158 jack_ringbuffer_read(ringBuffer, (char*) &m, sizeof (MidiMessage)); |
153 void* jackPortBuffer = jack_port_get_buffer(jackPort, frames); |
|
154 jack_midi_data_t* midiData = jack_midi_event_reserve(jackPortBuffer, m.time, m.size); |
159 jack_midi_data_t* midiData = jack_midi_event_reserve(jackPortBuffer, m.time, m.size); |
155 memcpy(midiData, m.buffer, m.size); |
160 memcpy(midiData, m.buffer, m.size); |
|
161 std::cout << "jack_midi_event_reserve" << std::endl; |
156 } |
162 } |
157 return 0; |
163 return 0; |
158 } |
164 } |
159 |
165 |
160 void finish(int sig) { |
166 void finish(int sig) { |