1 /*-
2 * Copyright (c) 2006-2020 Hans Petter Selasky. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "umidi20.h"
31
32 /*
33 * This file implements simple MIDI music generator functions.
34 *
35 * Recommended software synths:
36 * - Fluidsynth
37 * - Timidity++
38 */
39
40 static const uint8_t mid_next_key_tab[12] = {
41 2, 2, 2, 3, 1,
42 2, 2, 2, 2, 2, 3, 1,
43 };
44
45 static const uint8_t mid_prev_key_tab[12] = {
46 1, 3, 2, 2, 2,
47 1, 3, 2, 2, 2, 2, 2,
48 };
49
50 const char *mid_key_str[128] = {
51 "C0", "D0B", "D0", "E0B", "E0", "F0", "G0B", "G0", "A0B", "A0", "H0B", "H0",
52 "C1", "D1B", "D1", "E1B", "E1", "F1", "G1B", "G1", "A1B", "A1", "H1B", "H1",
53 "C2", "D2B", "D2", "E2B", "E2", "F2", "G2B", "G2", "A2B", "A2", "H2B", "H2",
54 "C3", "D3B", "D3", "E3B", "E3", "F3", "G3B", "G3", "A3B", "A3", "H3B", "H3",
55 "C4", "D4B", "D4", "E4B", "E4", "F4", "G4B", "G4", "A4B", "A4", "H4B", "H4",
56 "C5", "D5B", "D5", "E5B", "E5", "F5", "G5B", "G5", "A5B", "A5", "H5B", "H5",
57 "C6", "D6B", "D6", "E6B", "E6", "F6", "G6B", "G6", "A6B", "A6", "H6B", "H6",
58 "C7", "D7B", "D7", "E7B", "E7", "F7", "G7B", "G7", "A7B", "A7", "H7B", "H7",
59 "C8", "D8B", "D8", "E8B", "E8", "F8", "G8B", "G8", "A8B", "A8", "H8B", "H8",
60 "C9", "D9B", "D9", "E9B", "E9", "F9", "G9B", "G9", "A9B", "A9", "H9B", "H9",
61 "C10", "D10B", "D10", "E10B", "E10", "F10", "G10B", "G10",
62 };
63
64 void
mid_set_device_no(struct mid_data * d,uint8_t device_no)65 mid_set_device_no(struct mid_data *d, uint8_t device_no)
66 {
67 uint8_t enable;
68
69 if (device_no >= UMIDI20_N_DEVICES)
70 enable = 0;
71 else
72 enable = 1;
73
74 d->cc_enabled = enable;
75 d->cc_device_no = device_no;
76 }
77
78 void
mid_sort(uint8_t * pk,uint8_t nk)79 mid_sort(uint8_t *pk, uint8_t nk)
80 {
81 uint8_t a;
82 uint8_t b;
83 uint8_t c;
84
85 for (a = 0; a != nk; a++) {
86 for (b = a + 1; b != nk; b++) {
87 if (pk[a] > pk[b]) {
88 c = pk[b];
89 pk[b] = pk[a];
90 pk[a] = c;
91 }
92 }
93 }
94 }
95
96 void
mid_trans(uint8_t * pk,uint8_t nk,int8_t nt)97 mid_trans(uint8_t *pk, uint8_t nk, int8_t nt)
98 {
99 uint8_t temp;
100
101 if (nk == 0)
102 return;
103
104 mid_sort(pk, nk);
105
106 if (nt < 0) {
107 while (nt++) {
108 temp = pk[nk - 1];
109 do {
110 temp = mid_sub(temp, 12);
111 if (temp == UMIDI20_KEY_INVALID)
112 return;
113 } while (temp >= pk[0]);
114 pk[nk - 1] = temp;
115 mid_sort(pk, nk);
116 }
117 } else {
118 while (nt--) {
119 temp = pk[0];
120 do {
121 temp = mid_add(temp, 12);
122 if (temp == UMIDI20_KEY_INVALID)
123 return;
124 } while (temp <= pk[nk - 1]);
125 pk[0] = temp;
126 mid_sort(pk, nk);
127 }
128 }
129 }
130
131 uint8_t
mid_add(uint8_t a,uint8_t b)132 mid_add(uint8_t a, uint8_t b)
133 {
134 int16_t t = a + b;
135
136 if (t > 127)
137 t = UMIDI20_KEY_INVALID;
138 return (t);
139 }
140
141 uint8_t
mid_sub(uint8_t a,uint8_t b)142 mid_sub(uint8_t a, uint8_t b)
143 {
144 int16_t t = a - b;
145
146 if (t < 0)
147 t = UMIDI20_KEY_INVALID;
148 return (t);
149 }
150
151 uint8_t
mid_next_key(uint8_t key,int8_t n)152 mid_next_key(uint8_t key, int8_t n)
153 {
154 uint8_t temp;
155 if (n > 0) {
156 while (n--) {
157 temp = mid_add(key, mid_next_key_tab[key % 12]);
158 if (temp == UMIDI20_KEY_INVALID)
159 break;
160 key = temp;
161 }
162 } else {
163 while (n++) {
164 temp = mid_sub(key, mid_prev_key_tab[key % 12]);
165 if (temp == UMIDI20_KEY_INVALID)
166 break;
167 key = temp;
168 }
169 }
170 return (key);
171 }
172
173 void
mid_dump(struct mid_data * d)174 mid_dump(struct mid_data *d)
175 {
176 struct umidi20_event *event;
177
178 uint32_t last_pos = 0;
179 uint32_t delta;
180 uint8_t new_pedal;
181 uint8_t pedal_down = 0;
182
183 umidi20_track_compute_max_min(d->track);
184
185 UMIDI20_QUEUE_FOREACH(event, &(d->track->queue)) {
186
187 delta = event->position - last_pos;
188
189 if (umidi20_event_get_channel(event) != 0) {
190 continue;
191 }
192 if (umidi20_event_is_key_start(event)) {
193
194 if (delta > 30) {
195 last_pos = event->position;
196 printf("\t" "mid_delay(d,%d);\n", delta);
197 }
198 printf("\t" "mid_key_press(d,%s,%d,%d);\n",
199 mid_key_str[umidi20_event_get_key(event)],
200 umidi20_event_get_velocity(event),
201 event->duration);
202 } else if (umidi20_event_get_control_address(event) == 0x40) {
203
204 /* pedal */
205
206 new_pedal = (umidi20_event_get_control_value(event) >= 0x40);
207
208 if (new_pedal != pedal_down) {
209 pedal_down = new_pedal;
210
211 if (delta > 30) {
212 last_pos = event->position;
213 printf("\t" "mid_delay(d,%d);\n", delta);
214 }
215 printf("\t" "mid_pedal(d,%d);\n", new_pedal);
216 }
217 }
218 }
219 }
220
221 void
mid_add_raw(struct mid_data * d,const uint8_t * buf,uint32_t len,uint32_t offset)222 mid_add_raw(struct mid_data *d, const uint8_t *buf,
223 uint32_t len, uint32_t offset)
224 {
225 struct umidi20_event *event;
226
227 event = umidi20_event_from_data(buf, len, 0);
228 if (event) {
229 event->position = d->position[d->channel] + offset;
230
231 /* set channel, if any */
232 umidi20_event_set_channel(event, d->channel);
233
234 if (d->cc_enabled) {
235 /*
236 * Need to lock the root device before adding
237 * entries to the play queue:
238 */
239 pthread_mutex_lock(&(root_dev.mutex));
240 umidi20_event_queue_insert(&(root_dev.play[d->cc_device_no].queue),
241 event, UMIDI20_CACHE_INPUT);
242 pthread_mutex_unlock(&(root_dev.mutex));
243
244 } else {
245 umidi20_event_queue_insert(&d->track->queue,
246 event, UMIDI20_CACHE_INPUT);
247 }
248
249 } else {
250 printf("Lost event: Out of memory\n");
251 }
252 return;
253 }
254
255 uint32_t
mid_get_position(struct mid_data * d)256 mid_get_position(struct mid_data *d)
257 {
258 return d->position[d->channel];
259 }
260
261 void
mid_set_position(struct mid_data * d,uint32_t pos)262 mid_set_position(struct mid_data *d, uint32_t pos)
263 {
264 d->position[d->channel] = pos;
265 }
266
267 uint32_t
mid_delay(struct mid_data * d,int32_t off)268 mid_delay(struct mid_data *d, int32_t off)
269 {
270 return (d->position[d->channel] += off);
271 }
272
273 void
mid_position_ceil(struct mid_data * d,uint16_t channel_mask)274 mid_position_ceil(struct mid_data *d, uint16_t channel_mask)
275 {
276 uint32_t min = 0;
277 uint8_t x;
278
279 for (x = 0; x < 16; x++) {
280 if ((channel_mask & (1 << x)) &&
281 (d->position[x] > min)) {
282 min = d->position[x];
283 }
284 }
285
286 for (x = 0; x < 16; x++) {
287 if ((channel_mask & (1 << x))) {
288 d->position[x] = min;
289 }
290 }
291 }
292
293 void
mid_position_floor(struct mid_data * d,uint16_t channel_mask)294 mid_position_floor(struct mid_data *d, uint16_t channel_mask)
295 {
296 uint32_t max = 0 - 1;
297 uint8_t x;
298
299 for (x = 0; x < 16; x++) {
300 if ((channel_mask & (1 << x)) &&
301 (d->position[x] < max)) {
302 max = d->position[x];
303 }
304 }
305
306 for (x = 0; x < 16; x++) {
307 if ((channel_mask & (1 << x))) {
308 d->position[x] = max;
309 }
310 }
311 }
312
313 void
mid_delay_all(struct mid_data * d,int32_t off)314 mid_delay_all(struct mid_data *d, int32_t off)
315 {
316 mid_delay(d, off);
317
318 if (off >= 0)
319 mid_position_ceil(d, 0 - 1);
320 else
321 mid_position_floor(d, 0 - 1);
322 }
323
324 void
mid_key_press(struct mid_data * d,uint8_t key,int8_t vel,uint32_t duration)325 mid_key_press(struct mid_data *d, uint8_t key, int8_t vel, uint32_t duration)
326 {
327 uint8_t buf[3];
328
329 if (vel <= 0) {
330 buf[0] = 0x80;
331 buf[1] = key & 0x7F;
332 buf[2] = (-vel) & 0x7F;
333 } else {
334 buf[0] = 0x90;
335 buf[1] = key & 0x7F;
336 buf[2] = vel & 0x7F;
337 }
338 mid_add_raw(d, buf, sizeof(buf), 0);
339
340 if (duration != 0 && vel > 0) {
341 buf[0] = 0x80;
342 buf[1] = key & 0x7F;
343 buf[2] = vel & 0x7F;
344 mid_add_raw(d, buf, sizeof(buf), duration);
345 }
346 }
347
348 void
mid_extended_key_press(struct mid_data * d,uint8_t key,uint32_t freq,int8_t vel,uint32_t duration)349 mid_extended_key_press(struct mid_data *d, uint8_t key, uint32_t freq, int8_t vel, uint32_t duration)
350 {
351 uint8_t buf0[11];
352 uint8_t buf1[3];
353
354 if (vel <= 0) {
355 buf1[0] = 0x80;
356 buf1[1] = key & 0x7F;
357 buf1[2] = (-vel) & 0x7F;
358
359 mid_add_raw(d, buf1, sizeof(buf1), 0);
360 } else {
361 buf0[0] = 0xF0;
362 buf0[1] = 0x0A;
363 buf0[2] = 0x55; /* XXX */
364 buf0[3] = d->channel & 0x0F;
365 buf0[4] = key & 0x7F;
366 buf0[5] = vel & 0x7F;
367
368 buf0[9] = freq & 0x7F;
369 freq >>= 7;
370 buf0[8] = freq & 0x7F;
371 freq >>= 7;
372 buf0[7] = freq & 0x7F;
373 freq >>= 7;
374 buf0[6] = freq & 0x7F;
375
376 buf0[10] = 0xF7;
377
378 mid_add_raw(d, buf0, sizeof(buf0), 0);
379 }
380
381 if (duration != 0 && vel > 0) {
382 buf1[0] = 0x80;
383 buf1[1] = key & 0x7F;
384 buf1[2] = vel & 0x7F;
385 mid_add_raw(d, buf1, sizeof(buf1), duration);
386 }
387 }
388
389 void
mid_extended_key_pitch(struct mid_data * d,uint8_t key,uint32_t freq)390 mid_extended_key_pitch(struct mid_data *d, uint8_t key, uint32_t freq)
391 {
392 uint8_t buf0[11];
393
394 buf0[0] = 0xF0;
395 buf0[1] = 0x0A;
396 buf0[2] = 0x55; /* XXX */
397 buf0[3] = (d->channel & 0x0F) | 0x30;
398 buf0[4] = key & 0x7F;
399 buf0[5] = 0;
400
401 buf0[9] = freq & 0x7F;
402 freq >>= 7;
403 buf0[8] = freq & 0x7F;
404 freq >>= 7;
405 buf0[7] = freq & 0x7F;
406 freq >>= 7;
407 buf0[6] = freq & 0x7F;
408
409 buf0[10] = 0xF7;
410
411 mid_add_raw(d, buf0, sizeof(buf0), 0);
412 }
413
414 void
mid_extended_key_control(struct mid_data * d,uint8_t key,uint8_t control,uint32_t value)415 mid_extended_key_control(struct mid_data *d, uint8_t key, uint8_t control, uint32_t value)
416 {
417 uint8_t buf0[11];
418
419 buf0[0] = 0xF0;
420 buf0[1] = 0x0A;
421 buf0[2] = 0x55; /* XXX */
422 buf0[3] = (d->channel & 0x0F) | 0x20;
423 buf0[4] = key & 0x7F;
424 buf0[5] = control & 0x7F;
425
426 buf0[9] = value & 0x7F;
427 value >>= 7;
428 buf0[8] = value & 0x7F;
429 value >>= 7;
430 buf0[7] = value & 0x7F;
431 value >>= 7;
432 buf0[6] = value & 0x7F;
433
434 buf0[10] = 0xF7;
435
436 mid_add_raw(d, buf0, sizeof(buf0), 0);
437 }
438
439 void
mid_key_press_n(struct mid_data * d,const uint8_t * pkey,uint8_t nkey,int8_t vel,uint32_t duration)440 mid_key_press_n(struct mid_data *d, const uint8_t *pkey, uint8_t nkey,
441 int8_t vel, uint32_t duration)
442 {
443 uint8_t n;
444
445 for (n = 0; n != nkey; n++)
446 mid_key_press(d, pkey[n], vel, duration);
447 }
448
449 void
mid_set_channel(struct mid_data * d,uint8_t channel)450 mid_set_channel(struct mid_data *d, uint8_t channel)
451 {
452 d->channel = channel & 0xF;
453 }
454
455 uint8_t
mid_get_channel(struct mid_data * d)456 mid_get_channel(struct mid_data *d)
457 {
458 return (d->channel & 0xF);
459 }
460
461 void
mid_control(struct mid_data * d,uint8_t ctrl,uint8_t val)462 mid_control(struct mid_data *d, uint8_t ctrl, uint8_t val)
463 {
464 uint8_t buf[4];
465
466 buf[0] = 0xB0;
467 buf[1] = ctrl & 0x7F;
468 buf[2] = val & 0x7F;
469
470 mid_add_raw(d, buf, 3, 0);
471 }
472
473 void
mid_pitch_bend(struct mid_data * d,uint16_t val)474 mid_pitch_bend(struct mid_data *d, uint16_t val)
475 {
476 uint8_t buf[4];
477
478 buf[0] = 0xE0;
479 buf[1] = val & 0x7F;
480 buf[2] = (val >> 7) & 0x7F;
481
482 mid_add_raw(d, buf, 3, 0);
483 }
484
485 void
mid_pedal(struct mid_data * d,uint8_t on)486 mid_pedal(struct mid_data *d, uint8_t on)
487 {
488 uint8_t buf[4];
489
490 buf[0] = 0xB0;
491 buf[1] = 0x40;
492 buf[2] = on ? 127 : 0;
493
494 mid_add_raw(d, buf, 3, 0);
495 }
496
497 void
mid_s_pedal(struct mid_data * d,int32_t db,int32_t dm,int32_t da,uint8_t on)498 mid_s_pedal(struct mid_data *d, int32_t db, int32_t dm, int32_t da,
499 uint8_t on)
500 {
501 if (db > 0) {
502 mid_delay(d, db);
503 }
504 mid_pedal(d, !on);
505 mid_delay(d, dm);
506 mid_pedal(d, on);
507 if (da > 0) {
508 mid_delay(d, da);
509 }
510 }
511
512 void
mid_init(struct mid_data * d,struct umidi20_track * track)513 mid_init(struct mid_data *d, struct umidi20_track *track)
514 {
515 #if 0
516 uint8_t buf[4];
517 uint8_t x;
518 #endif
519 memset(d, 0, sizeof(*d));
520
521 d->track = track;
522
523 #if 0
524 buf[0] = 0xFE;
525
526 for (x = 0; x < 16; x++) {
527 mid_set_channel(d, x);
528 mid_add_raw(d, buf, 1, 0);
529 }
530
531 buf[0] = 0xB0;
532 buf[1] = 0x79;
533 buf[2] = 0;
534
535 for (x = 0; x < 16; x++) {
536 mid_set_channel(d, x);
537 mid_add_raw(d, buf, 3, 2);
538 }
539 #endif
540 }
541
542 void
mid_set_bank_program(struct mid_data * d,uint8_t channel,uint16_t bank,uint8_t prog)543 mid_set_bank_program(struct mid_data *d, uint8_t channel, uint16_t bank,
544 uint8_t prog)
545 {
546 uint8_t buf[4];
547
548 mid_set_channel(d, channel);
549
550 /* Select the correct Bank and Program Number */
551
552 buf[0] = 0xB0;
553 buf[1] = 0x00;
554 buf[2] = (bank >> 7) & 0x7F;
555
556 mid_add_raw(d, buf, 3, 0);
557
558 buf[0] = 0xB0;
559 buf[1] = 0x20;
560 buf[2] = bank & 0x7F;
561
562 mid_add_raw(d, buf, 3, 1);
563
564 buf[0] = 0xC0;
565 buf[1] = prog & 0x7F;
566
567 mid_add_raw(d, buf, 2, 2);
568 }
569