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