10 #include <jack/midiport.h>
12 #include "evoral/midi_events.h"
22 second_simultaneous_midi_byte_is_first (uint8_t a, uint8_t b)
26 /* two events at identical times. we need to determine
27 the order in which they should occur.
40 if ((a) >= 0xf0 || (b) >= 0xf0 || ((a & 0xf) != (b & 0xf))) {
42 /* if either message is not a channel message, or if the channels are
43 * different, we don't care about the type.
51 case MIDI_CMD_CONTROL:
55 case MIDI_CMD_PGM_CHANGE:
57 case MIDI_CMD_CONTROL:
59 case MIDI_CMD_PGM_CHANGE:
60 case MIDI_CMD_NOTE_OFF:
61 case MIDI_CMD_NOTE_ON:
62 case MIDI_CMD_NOTE_PRESSURE:
63 case MIDI_CMD_CHANNEL_PRESSURE:
69 case MIDI_CMD_NOTE_OFF:
71 case MIDI_CMD_CONTROL:
72 case MIDI_CMD_PGM_CHANGE:
74 case MIDI_CMD_NOTE_OFF:
75 case MIDI_CMD_NOTE_ON:
76 case MIDI_CMD_NOTE_PRESSURE:
77 case MIDI_CMD_CHANNEL_PRESSURE:
83 case MIDI_CMD_NOTE_ON:
85 case MIDI_CMD_CONTROL:
86 case MIDI_CMD_PGM_CHANGE:
87 case MIDI_CMD_NOTE_OFF:
89 case MIDI_CMD_NOTE_ON:
90 case MIDI_CMD_NOTE_PRESSURE:
91 case MIDI_CMD_CHANNEL_PRESSURE:
96 case MIDI_CMD_NOTE_PRESSURE:
98 case MIDI_CMD_CONTROL:
99 case MIDI_CMD_PGM_CHANGE:
100 case MIDI_CMD_NOTE_OFF:
101 case MIDI_CMD_NOTE_ON:
103 case MIDI_CMD_NOTE_PRESSURE:
104 case MIDI_CMD_CHANNEL_PRESSURE:
105 case MIDI_CMD_BENDER:
110 case MIDI_CMD_CHANNEL_PRESSURE:
112 case MIDI_CMD_CONTROL:
113 case MIDI_CMD_PGM_CHANGE:
114 case MIDI_CMD_NOTE_OFF:
115 case MIDI_CMD_NOTE_ON:
116 case MIDI_CMD_NOTE_PRESSURE:
118 case MIDI_CMD_CHANNEL_PRESSURE:
119 case MIDI_CMD_BENDER:
123 case MIDI_CMD_BENDER:
125 case MIDI_CMD_CONTROL:
126 case MIDI_CMD_PGM_CHANGE:
127 case MIDI_CMD_NOTE_OFF:
128 case MIDI_CMD_NOTE_ON:
129 case MIDI_CMD_NOTE_PRESSURE:
130 case MIDI_CMD_CHANNEL_PRESSURE:
132 case MIDI_CMD_BENDER:
142 BeatBox::BeatBox (int sr)
143 : _start_requested (false)
149 , _meter_beat_type (4)
155 , whole_note_superclocks (0)
156 , beat_superclocks (0)
157 , measure_superclocks (0)
158 , _quantize_divisor (4)
159 , clear_pending (false)
161 for (uint32_t n = 0; n < 1024; ++n) {
162 event_pool.push_back (new Event());
171 BeatBox::register_ports (jack_client_t* jack)
173 if ((_input = jack_port_register (jack, "midi-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0)) == 0) {
174 cerr << "no input port\n";
177 if ((_output = jack_port_register (jack, "midi-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0)) == 0) {
178 cerr << "no output port\n";
179 jack_port_unregister (jack, _input);
187 BeatBox::compute_tempo_clocks ()
189 whole_note_superclocks = (superclock_ticks_per_second * 60) / (_tempo / _meter_beat_type);
190 beat_superclocks = whole_note_superclocks / _meter_beat_type;
191 measure_superclocks = beat_superclocks * _meter_beats;
197 /* compute tempo, beat steps etc. */
199 compute_tempo_clocks ();
203 _start_requested = true;
209 _start_requested = false;
213 BeatBox::set_tempo (float bpm)
215 _tempo_request = bpm;
219 BeatBox::process (int nsamples)
222 if (_start_requested) {
224 last_start = superclock_cnt;
228 if (!_start_requested) {
233 superclock_t superclocks = samples_to_superclock (nsamples, _sample_rate);
236 superclock_cnt += superclocks;
240 if (_tempo_request) {
241 double ratio = _tempo / _tempo_request;
242 _tempo = _tempo_request;
245 compute_tempo_clocks ();
247 for (Events::iterator ee = _current_events.begin(); ee != _current_events.end(); ++ee) {
248 (*ee)->time = llrintf ((*ee)->time * ratio);
252 superclock_t process_start = superclock_cnt - last_start;
253 superclock_t process_end = process_start + superclocks;
254 const superclock_t loop_length = _measures * measure_superclocks;
255 const superclock_t orig_superclocks = superclocks;
257 process_start %= loop_length;
258 process_end %= loop_length;
260 bool two_pass_required;
261 superclock_t offset = 0;
263 if (process_end < process_start) {
264 two_pass_required = true;
265 process_end = loop_length;
266 superclocks = process_end - process_start;
268 two_pass_required = false;
271 unsigned char* buffer;
274 jack_midi_event_t in_event;
275 jack_nframes_t event_index;
276 jack_nframes_t event_count;
278 /* do this on the first pass only */
279 out_buf = jack_port_get_buffer (_output, nsamples);
280 jack_midi_clear_buffer (out_buf);
288 for (Events::iterator ee = _current_events.begin(); ee != _current_events.end(); ++ee) {
289 event_pool.push_back (*ee);
291 _current_events.clear ();
292 clear_pending = false;
295 for (Events::iterator ee = _current_events.begin(); ee != _current_events.end(); ++ee) {
298 if (e->size && (e->time >= process_start && e->time < process_end)) {
299 if ((buffer = jack_midi_event_reserve (out_buf, superclock_to_samples (offset + e->time - process_start, _sample_rate), e->size)) != 0) {
300 memcpy (buffer, e->buf, e->size);
302 cerr << "Could not reserve space for output event @ " << e << " of size " << e->size << " @ " << offset + e->time - process_start
303 << " (samples: " << superclock_to_samples (offset + e->time - process_start, _sample_rate) << ") offset is " << offset
308 if (e->time >= process_end) {
315 in_buf = jack_port_get_buffer (_input, nsamples);
318 while (jack_midi_event_get (&in_event, in_buf, event_index++) == 0) {
320 superclock_t event_time = superclock_cnt + samples_to_superclock (in_event.time, _sample_rate);
321 superclock_t elapsed_time = event_time - last_start;
322 superclock_t in_loop_time = elapsed_time % loop_length;
323 superclock_t quantized_time;
325 if (_quantize_divisor != 0) {
326 const superclock_t time_per_beat = whole_note_superclocks / _quantize_divisor;
327 quantized_time = (in_loop_time / time_per_beat) * time_per_beat;
329 quantized_time = elapsed_time;
332 if (in_event.size > 24) {
333 cerr << "Ignored large MIDI event\n";
337 if (event_pool.empty()) {
338 cerr << "No more events, grow pool\n";
342 Event* e = event_pool.back();
343 event_pool.pop_back ();
345 e->time = quantized_time;
346 e->whole_note_superclocks = whole_note_superclocks;
347 e->size = in_event.size;
348 memcpy (e->buf, in_event.buffer, in_event.size);
350 _current_events.insert (e);
353 superclock_cnt += superclocks;
355 if (two_pass_required) {
356 offset = superclocks;
357 superclocks = orig_superclocks - superclocks;
359 process_end = superclocks;
360 two_pass_required = false;
368 BeatBox::set_quantize (int divisor)
370 _quantize_divisor = divisor;
376 clear_pending = true;
380 BeatBox::EventComparator::operator() (Event const * a, Event const *b) const
382 if (a->time == b->time) {
383 if (a->buf[0] == b->buf[0]) {
386 return !second_simultaneous_midi_byte_is_first (a->buf[0], b->buf[0]);
388 return a->time < b->time;
392 process (jack_nframes_t nsamples, void* arg)
394 BeatBox* bbox = static_cast<BeatBox*> (arg);
395 return bbox->process (nsamples);
399 main (int argc, char* argv[])
402 const char *server_name = NULL;
403 jack_options_t options = JackNullOption;
404 jack_status_t status;
406 if ((jack = jack_client_open ("beatbox", options, &status, server_name)) == 0) {
407 cerr << "Could not connect to JACK\n";
411 BeatBox* bbox = new BeatBox (jack_get_sample_rate (jack));
412 BBGUI* gui = new BBGUI (&argc, &argv, jack, bbox);
414 bbox->register_ports (jack);
416 jack_set_process_callback (jack, process, bbox);
417 jack_activate (jack);