1 /*- 2 * Copyright (c) 2006-2019 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 #ifndef _UMIDI20_H_ 27 #define _UMIDI20_H_ 28 29 #include <sys/cdefs.h> 30 #include <sys/param.h> 31 #include <sys/queue.h> 32 33 #include <pthread.h> 34 #include <signal.h> 35 #include <stdint.h> 36 37 __BEGIN_DECLS 38 39 #define UMIDI20_BPM 60000 /* Beats Per Minute */ 40 41 #define UMIDI20_COMMAND_LEN 8 /* bytes, max */ 42 #define UMIDI20_BUF_EVENTS 1024 /* units */ 43 44 #define UMIDI20_N_DEVICES 16 /* units */ 45 46 #define UMIDI20_FLAG_PLAY 0x01 47 #define UMIDI20_FLAG_RECORD 0x02 48 49 #define UMIDI20_MAX_OFFSET 0x80000000 50 51 #define UMIDI20_BAND_SIZE 24 52 #define UMIDI20_KEY_TO_BAND_OFFSET(n) (((n) + 12) % UMIDI20_BAND_SIZE) 53 #define UMIDI20_KEY_TO_BAND_NUMBER(n) (((n) + 12) / UMIDI20_BAND_SIZE) 54 55 #define UMIDI20_KEY_INVALID 255 56 57 enum { 58 UMIDI20_FILE_DIVISION_TYPE_PPQ, 59 UMIDI20_FILE_DIVISION_TYPE_SMPTE24, 60 UMIDI20_FILE_DIVISION_TYPE_SMPTE25, 61 UMIDI20_FILE_DIVISION_TYPE_SMPTE30DROP, 62 UMIDI20_FILE_DIVISION_TYPE_SMPTE30 63 }; 64 65 enum { 66 UMIDI20_FILE_FORMAT_TYPE_0, 67 UMIDI20_FILE_FORMAT_TYPE_1, 68 UMIDI20_FILE_FORMAT_TYPE_2, 69 }; 70 71 #define UMIDI20_WHAT_CHANNEL 0x0001 72 #define UMIDI20_WHAT_KEY 0x0002 73 #define UMIDI20_WHAT_VELOCITY 0x0004 74 #define UMIDI20_WHAT_KEY_PRESSURE 0x0008 75 #define UMIDI20_WHAT_CONTROL_VALUE 0x0010 76 #define UMIDI20_WHAT_CONTROL_ADDRESS 0x0020 77 #define UMIDI20_WHAT_PROGRAM_VALUE 0x0040 78 #define UMIDI20_WHAT_CHANNEL_PRESSURE 0x0080 79 #define UMIDI20_WHAT_PITCH_BEND 0x0100 80 #define UMIDI20_WHAT_BEAT_EVENT 0x0200 81 #define UMIDI20_WHAT_SONG_EVENT 0x0400 82 #define UMIDI20_WHAT_EXTENDED_KEY 0x0800 83 84 struct timespec; 85 struct umidi20_event; 86 struct umidi20_track; 87 struct umidi20_song; 88 struct umidi20_timer_entry; 89 90 typedef void (umidi20_event_callback_t)(uint8_t unit, void *arg, struct umidi20_event *event, uint8_t *drop_event); 91 typedef void (umidi20_timer_callback_t)(void *arg); 92 93 /*--------------------------------------------------------------------------* 94 * queue structures and macros 95 *--------------------------------------------------------------------------*/ 96 97 #define UMIDI20_CACHE_INPUT 0 98 #define UMIDI20_CACHE_OUTPUT 1 99 #define UMIDI20_CACHE_EDIT 2 100 #define UMIDI20_CACHE_OTHER 3 101 #define UMIDI20_CACHE_MAX 4 102 103 struct umidi20_event_queue { 104 struct umidi20_event *ifq_head; 105 struct umidi20_event *ifq_tail; 106 struct umidi20_event *ifq_cache[UMIDI20_CACHE_MAX]; 107 108 int32_t ifq_len; 109 int32_t ifq_maxlen; 110 }; 111 112 struct umidi20_track_queue { 113 struct umidi20_track *ifq_head; 114 struct umidi20_track *ifq_tail; 115 struct umidi20_track *ifq_cache[UMIDI20_CACHE_MAX]; 116 117 int32_t ifq_len; 118 int32_t ifq_maxlen; 119 }; 120 121 struct umidi20_song_queue { 122 struct umidi20_song *ifq_head; 123 struct umidi20_song *ifq_tail; 124 struct umidi20_song *ifq_cache[UMIDI20_CACHE_MAX]; 125 126 int32_t ifq_len; 127 int32_t ifq_maxlen; 128 }; 129 130 #define UMIDI20_IF_CHECK_CACHE_ONE(ifq,m,n) \ 131 if ((ifq)->ifq_cache[n] == (m)) { \ 132 (ifq)->ifq_cache[n] = (m)->p_nextpkt; \ 133 if ((ifq)->ifq_cache[n] == NULL) { \ 134 (ifq)->ifq_cache[n] = (m)->p_prevpkt; \ 135 } \ 136 } 137 138 #define UMIDI20_IF_CHECK_CACHE(ifq, m) do { \ 139 UMIDI20_IF_CHECK_CACHE_ONE(ifq,m,0); \ 140 UMIDI20_IF_CHECK_CACHE_ONE(ifq,m,1); \ 141 UMIDI20_IF_CHECK_CACHE_ONE(ifq,m,2); \ 142 UMIDI20_IF_CHECK_CACHE_ONE(ifq,m,3); \ 143 } while (0) 144 145 #define UMIDI20_IF_REMOVE(ifq, m) do { \ 146 UMIDI20_IF_CHECK_CACHE(ifq, m); \ 147 if ((m)->p_nextpkt) { \ 148 (m)->p_nextpkt->p_prevpkt = (m)->p_prevpkt; \ 149 } else { \ 150 (ifq)->ifq_tail = (m)->p_prevpkt; \ 151 } \ 152 if ((m)->p_prevpkt) { \ 153 (m)->p_prevpkt->p_nextpkt = (m)->p_nextpkt; \ 154 } else { \ 155 (ifq)->ifq_head = (m)->p_nextpkt; \ 156 } \ 157 (m)->p_nextpkt = NULL; \ 158 (m)->p_prevpkt = NULL; \ 159 (ifq)->ifq_len--; \ 160 } while (0) 161 162 #define UMIDI20_IF_DEQUEUE(ifq, m) do { \ 163 (m) = (ifq)->ifq_head; \ 164 if (m) { \ 165 UMIDI20_IF_CHECK_CACHE(ifq, m); \ 166 if (((ifq)->ifq_head = (m)->p_nextpkt) == NULL) { \ 167 (ifq)->ifq_tail = NULL; \ 168 } else { \ 169 (ifq)->ifq_head->p_prevpkt = NULL; \ 170 } \ 171 (m)->p_nextpkt = NULL; \ 172 (m)->p_prevpkt = NULL; \ 173 (ifq)->ifq_len--; \ 174 } \ 175 } while (0) 176 177 #define UMIDI20_IF_ENQUEUE_AFTER(ifq, m1, m2) do { \ 178 (m2)->p_nextpkt = (m1)->p_nextpkt; \ 179 (m2)->p_prevpkt = (m1); \ 180 if ((m1) == (ifq)->ifq_tail) { \ 181 (ifq)->ifq_tail = (m2); \ 182 } else { \ 183 (m1)->p_nextpkt->p_prevpkt = (m2); \ 184 } \ 185 (m1)->p_nextpkt = (m2); \ 186 (ifq)->ifq_len++; \ 187 } while (0) 188 189 #define UMIDI20_IF_ENQUEUE_BEFORE(ifq, m1, m2) do { \ 190 (m2)->p_nextpkt = (m1); \ 191 (m2)->p_prevpkt = (m1)->p_prevpkt; \ 192 if ((m1) == (ifq)->ifq_head) { \ 193 (ifq)->ifq_head = (m2); \ 194 } else { \ 195 (m1)->p_prevpkt->p_nextpkt = (m2); \ 196 } \ 197 (m1)->p_prevpkt = (m2); \ 198 (ifq)->ifq_len++; \ 199 } while (0) 200 201 #define UMIDI20_IF_ENQUEUE_LAST(ifq, m) do { \ 202 (m)->p_nextpkt = NULL; \ 203 (m)->p_prevpkt = (ifq)->ifq_tail; \ 204 if ((ifq)->ifq_tail == NULL) { \ 205 (ifq)->ifq_head = (m); \ 206 } else { \ 207 (ifq)->ifq_tail->p_nextpkt = (m); \ 208 } \ 209 (ifq)->ifq_tail = (m); \ 210 (ifq)->ifq_len++; \ 211 } while (0) 212 213 #define UMIDI20_IF_ENQUEUE_FIRST(ifq, m) do { \ 214 (m)->p_nextpkt = (ifq)->ifq_head; \ 215 (m)->p_prevpkt = NULL; \ 216 if ((ifq)->ifq_tail == NULL) { \ 217 (ifq)->ifq_tail = (m); \ 218 } else { \ 219 (ifq)->ifq_head->p_prevkt = (m); \ 220 } \ 221 (ifq)->ifq_head = (m); \ 222 (ifq)->ifq_len++; \ 223 } while (0) 224 225 #define UMIDI20_IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) 226 #define UMIDI20_IF_QLEN(ifq) ((ifq)->ifq_len) 227 #define UMIDI20_IF_POLL_HEAD(ifq, m) ((m) = (ifq)->ifq_head) 228 #define UMIDI20_IF_POLL_TAIL(ifq, m) ((m) = (ifq)->ifq_tail) 229 230 #define UMIDI20_QUEUE_FOREACH(m, ifq) \ 231 for ((m) = (ifq)->ifq_head; \ 232 (m); \ 233 (m) = (m)->p_nextpkt) 234 235 #define UMIDI20_QUEUE_FOREACH_SAFE(m, ifq, m_next) \ 236 for ((m) = (ifq)->ifq_head; \ 237 (m) && ((m_next) = (m)->p_nextpkt, 1); \ 238 (m) = (m_next)) 239 240 241 /*--------------------------------------------------------------------------* 242 * MIDI command converter 243 *--------------------------------------------------------------------------*/ 244 struct umidi20_converter { 245 struct umidi20_event **pp_next; 246 struct umidi20_event *p_next; 247 248 uint8_t *temp_cmd; 249 uint8_t temp_0[UMIDI20_COMMAND_LEN]; 250 uint8_t temp_1[UMIDI20_COMMAND_LEN]; 251 uint8_t state; 252 #define UMIDI20_ST_UNKNOWN 0 /* scan for command */ 253 #define UMIDI20_ST_1PARAM 1 254 #define UMIDI20_ST_2PARAM_1 2 255 #define UMIDI20_ST_2PARAM_2 3 256 #define UMIDI20_ST_SYSEX_0 4 257 #define UMIDI20_ST_SYSEX_1 5 258 #define UMIDI20_ST_SYSEX_2 6 259 #define UMIDI20_ST_SYSEX_3 7 260 #define UMIDI20_ST_SYSEX_4 8 261 #define UMIDI20_ST_SYSEX_5 9 262 #define UMIDI20_ST_SYSEX_6 10 263 }; 264 265 /*--------------------------------------------------------------------------* 266 * MIDI event structure 267 *--------------------------------------------------------------------------*/ 268 struct umidi20_event { 269 struct umidi20_event *p_nextpkt; 270 struct umidi20_event *p_prevpkt; 271 struct umidi20_event *p_next; 272 uint32_t position; /* milliseconds */ 273 uint32_t tick; /* units */ 274 uint32_t duration; /* milliseconds */ 275 uint16_t revision; /* unit */ 276 uint8_t device_no; /* device number */ 277 uint8_t unused; 278 uint8_t cmd[UMIDI20_COMMAND_LEN]; 279 }; 280 281 /*--------------------------------------------------------------------------* 282 * MIDI config structures 283 *--------------------------------------------------------------------------*/ 284 struct umidi20_config_dev { 285 char rec_fname[128]; 286 char play_fname[128]; 287 uint8_t rec_enabled_cfg; 288 uint8_t play_enabled_cfg; 289 #define UMIDI20_DISABLE_CFG 0 290 #define UMIDI20_ENABLED_CFG_DEV 1 291 #define UMIDI20_ENABLED_CFG_JACK 2 292 #define UMIDI20_ENABLED_CFG_COREMIDI 3 293 #define UMIDI20_ENABLED_CFG_ANDROID 4 294 }; 295 296 struct umidi20_config { 297 struct umidi20_config_dev cfg_dev[UMIDI20_N_DEVICES]; 298 }; 299 300 /*--------------------------------------------------------------------------* 301 * MIDI device structure 302 *--------------------------------------------------------------------------*/ 303 struct umidi20_device { 304 305 struct umidi20_event_queue queue; 306 struct umidi20_converter conv; 307 308 umidi20_event_callback_t *event_callback_func; 309 void *event_callback_arg; 310 311 uint32_t start_position; 312 uint32_t end_offset; 313 314 int file_no; /* file number */ 315 316 uint8_t device_no; /* device number */ 317 318 uint8_t any_key_start; /* a key start was transmitted */ 319 uint8_t enabled_usr; /* enabled by user */ 320 uint8_t enabled_cfg; /* enabled by config */ 321 uint8_t enabled_cfg_last; /* last enabled by config */ 322 uint8_t update; 323 char fname[128]; 324 }; 325 326 /*--------------------------------------------------------------------------* 327 * MIDI root-device structure 328 *--------------------------------------------------------------------------*/ 329 struct umidi20_root_device { 330 struct umidi20_device rec[UMIDI20_N_DEVICES]; 331 struct umidi20_device play[UMIDI20_N_DEVICES]; 332 struct umidi20_event_queue free_queue; 333 struct timespec curr_time; 334 struct timespec start_time; 335 pthread_mutex_t mutex; 336 pthread_cond_t cond; 337 338 TAILQ_HEAD(, umidi20_timer_entry) timers; 339 340 pthread_t thread_alloc; 341 pthread_t thread_play_rec; 342 pthread_t thread_files; 343 344 uint32_t curr_position; 345 }; 346 347 extern struct umidi20_root_device root_dev; 348 349 /*--------------------------------------------------------------------------* 350 * MIDI track structure 351 *--------------------------------------------------------------------------*/ 352 struct umidi20_track { 353 struct umidi20_event_queue queue; 354 355 struct umidi20_track *p_nextpkt; 356 struct umidi20_track *p_prevpkt; 357 358 uint32_t position_max; 359 360 uint8_t mute_flag; 361 uint8_t selected_flag; 362 uint8_t draw_flag; 363 uint8_t temp_flag; 364 365 uint8_t key_min; 366 uint8_t key_max; 367 368 uint8_t band_min; 369 uint8_t band_max; 370 371 uint8_t name[256]; 372 uint8_t instrument[256]; 373 }; 374 375 /*--------------------------------------------------------------------------* 376 * MIDI song structure 377 *--------------------------------------------------------------------------*/ 378 struct umidi20_song { 379 struct umidi20_track_queue queue; 380 struct timespec play_start_time; 381 382 struct umidi20_song *p_nextpkt; 383 struct umidi20_song *p_prevpkt; 384 struct umidi20_track *rec_track; 385 386 pthread_mutex_t *p_mtx; 387 pthread_t thread_io; 388 389 uint32_t play_start_position; 390 uint32_t play_end_offset; 391 uint32_t play_start_offset; 392 uint32_t play_last_offset; 393 uint32_t position_max; 394 uint32_t track_max; 395 uint32_t band_max; 396 397 uint16_t midi_file_format; 398 uint16_t midi_resolution; 399 uint16_t record_track; 400 401 uint8_t midi_division_type; 402 403 uint8_t play_enabled; 404 uint8_t rec_enabled; 405 406 uint8_t pc_flags; /* play and record flags */ 407 }; 408 409 /*--------------------------------------------------------------------------* 410 * prototypes from "umidi20.c" 411 *--------------------------------------------------------------------------*/ 412 413 extern uint32_t umidi20_get_curr_position(void); 414 extern void umidi20_set_record_event_callback(uint8_t device_no, umidi20_event_callback_t *func, void *arg); 415 extern void umidi20_set_play_event_callback(uint8_t device_no, umidi20_event_callback_t *func, void *arg); 416 extern void umidi20_init(void); 417 extern void umidi20_uninit(void); 418 extern struct umidi20_event *umidi20_event_alloc(struct umidi20_event ***ppp_next, uint8_t flag); 419 extern void umidi20_event_free(struct umidi20_event *event); 420 extern struct umidi20_event *umidi20_event_copy(struct umidi20_event *event, uint8_t flag); 421 extern struct umidi20_event *umidi20_event_from_data(const uint8_t *data_ptr, uint32_t data_len, uint8_t flag); 422 extern uint8_t *umidi20_event_pointer(struct umidi20_event *event, uint32_t offset); 423 extern uint32_t umidi20_event_get_what(struct umidi20_event *event); 424 extern uint8_t umidi20_event_is_meta(struct umidi20_event *event); 425 extern uint8_t umidi20_event_is_pitch_bend(struct umidi20_event *event); 426 extern uint8_t umidi20_event_is_key_start(struct umidi20_event *event); 427 extern uint8_t umidi20_event_is_key_end(struct umidi20_event *event); 428 extern uint8_t umidi20_event_is_tempo(struct umidi20_event *event); 429 extern uint8_t umidi20_event_is_voice(struct umidi20_event *event); 430 extern uint8_t umidi20_event_is_sysex(struct umidi20_event *event); 431 extern uint8_t umidi20_event_get_channel(struct umidi20_event *event); 432 extern void umidi20_event_set_channel(struct umidi20_event *event, uint8_t c); 433 extern uint8_t umidi20_event_get_key(struct umidi20_event *event); 434 extern void umidi20_event_set_key(struct umidi20_event *event, uint8_t k); 435 extern uint32_t umidi20_event_get_extended_key(struct umidi20_event *event); 436 extern void umidi20_event_set_extended_key(struct umidi20_event *event, uint32_t k); 437 extern uint8_t umidi20_event_get_velocity(struct umidi20_event *event); 438 extern void umidi20_event_set_velocity(struct umidi20_event *event, uint8_t v); 439 extern uint8_t umidi20_event_get_pressure(struct umidi20_event *event); 440 extern void umidi20_event_set_pressure(struct umidi20_event *event, uint8_t p); 441 extern uint8_t umidi20_event_get_control_address(struct umidi20_event *event); 442 extern void umidi20_event_set_control_address(struct umidi20_event *event, uint8_t a); 443 extern uint8_t umidi20_event_get_control_value(struct umidi20_event *event); 444 extern void umidi20_event_set_control_value(struct umidi20_event *event, uint8_t a); 445 extern uint8_t umidi20_event_get_program_number(struct umidi20_event *event); 446 extern void umidi20_event_set_program_number(struct umidi20_event *event, uint8_t n); 447 extern uint16_t umidi20_event_get_pitch_value(struct umidi20_event *event); 448 extern void umidi20_event_set_pitch_value(struct umidi20_event *event, uint16_t n); 449 extern uint32_t umidi20_event_get_length_first(struct umidi20_event *event); 450 extern uint32_t umidi20_event_get_length(struct umidi20_event *event); 451 extern void umidi20_event_copy_out(struct umidi20_event *event, uint8_t *dst, uint32_t offset, uint32_t len); 452 extern uint8_t umidi20_event_get_meta_number(struct umidi20_event *event); 453 extern void umidi20_event_set_meta_number(struct umidi20_event *event, uint8_t n); 454 extern uint32_t umidi20_event_get_tempo(struct umidi20_event *event); 455 extern void umidi20_event_set_tempo(struct umidi20_event *event, uint32_t tempo); 456 extern struct umidi20_event *umidi20_event_queue_search(struct umidi20_event_queue *queue, uint32_t position, uint8_t cache_no); 457 extern void umidi20_event_queue_copy(struct umidi20_event_queue *src, struct umidi20_event_queue *dst, uint32_t pos_a, uint32_t pos_b, uint16_t rev_a, uint16_t rev_b, uint8_t cache_no, uint8_t flag); 458 extern void umidi20_event_queue_move(struct umidi20_event_queue *src, struct umidi20_event_queue *dst, uint32_t pos_a, uint32_t pos_b, uint16_t rev_a, uint16_t rev_b, uint8_t cache_no); 459 extern void umidi20_event_queue_insert(struct umidi20_event_queue *dst, struct umidi20_event *event_n, uint8_t cache_no); 460 extern void umidi20_event_queue_drain(struct umidi20_event_queue *src); 461 extern uint8_t umidi20_convert_to_command(struct umidi20_converter *conv, uint8_t b); 462 struct umidi20_event *umidi20_convert_to_event(struct umidi20_converter *conv, uint8_t b, uint8_t flag); 463 void umidi20_convert_reset(struct umidi20_converter *conv); 464 extern const uint8_t umidi20_command_to_len[16]; 465 extern void umidi20_gettime(struct timespec *ts); 466 extern uint32_t umidi20_difftime(struct timespec *a, struct timespec *b); 467 extern int umidi20_mutex_init(pthread_mutex_t *pmutex); 468 extern void umidi20_start(uint32_t start_position, uint32_t end_position, uint8_t flag); 469 extern void umidi20_stop(uint8_t flag); 470 struct umidi20_song *umidi20_song_alloc(pthread_mutex_t *p_mtx, uint16_t file_format, uint16_t resolution, uint8_t div_type); 471 extern void umidi20_song_free(struct umidi20_song *song); 472 extern struct umidi20_track *umidi20_song_track_by_unit(struct umidi20_song *song, uint16_t unit); 473 extern void umidi20_song_set_record_track(struct umidi20_song *song, struct umidi20_track *track); 474 extern void umidi20_song_start(struct umidi20_song *song, uint32_t start_offset, uint32_t end_offset, uint8_t flags); 475 extern void umidi20_song_stop(struct umidi20_song *song, uint8_t flags); 476 extern uint8_t umidi20_all_dev_off(uint8_t flag); 477 extern void umidi20_song_track_add(struct umidi20_song *song, struct umidi20_track *track_ref, struct umidi20_track *track_new, uint8_t is_before_ref); 478 extern void umidi20_song_track_remove(struct umidi20_song *song, struct umidi20_track *track); 479 extern void umidi20_song_recompute_position(struct umidi20_song *song); 480 extern void umidi20_song_recompute_tick(struct umidi20_song *song); 481 extern void umidi20_song_compute_max_min(struct umidi20_song *song); 482 extern void umidi20_config_export(struct umidi20_config *cfg); 483 extern void umidi20_config_import(struct umidi20_config *cfg); 484 extern struct umidi20_track *umidi20_track_alloc(void); 485 extern void umidi20_track_free(struct umidi20_track *track); 486 extern void umidi20_track_compute_max_min(struct umidi20_track *track); 487 extern void umidi20_set_timer(umidi20_timer_callback_t *fn, void *arg, uint32_t ms_interval); 488 extern void umidi20_update_timer(umidi20_timer_callback_t *fn, void *arg, uint32_t ms_interval, uint8_t do_sync); 489 extern void umidi20_unset_timer(umidi20_timer_callback_t *fn, void *arg); 490 extern int umidi20_pipe(int [2]); 491 492 /*--------------------------------------------------------------------------* 493 * prototypes from "umidi20_file.c" 494 *--------------------------------------------------------------------------*/ 495 extern struct umidi20_song *umidi20_load_file(pthread_mutex_t *p_mtx, const uint8_t *ptr, uint32_t len); 496 extern uint8_t umidi20_save_file(struct umidi20_song *song, uint8_t **pptr, uint32_t *plen); 497 498 /*--------------------------------------------------------------------------* 499 * prototypes from "umidi20_assert.c" 500 *--------------------------------------------------------------------------*/ 501 #define pthread_mutex_assert(mtx, flags) do { } while (0) 502 503 /*--------------------------------------------------------------------------* 504 * prototypes from "umidi20_jack.c" 505 *--------------------------------------------------------------------------*/ 506 const char **umidi20_jack_alloc_inputs(void); 507 const char **umidi20_jack_alloc_outputs(void); 508 void umidi20_jack_free_inputs(const char **); 509 void umidi20_jack_free_outputs(const char **); 510 511 int umidi20_jack_rx_open(uint8_t n, const char *name); 512 int umidi20_jack_tx_open(uint8_t n, const char *name); 513 int umidi20_jack_rx_close(uint8_t n); 514 int umidi20_jack_tx_close(uint8_t n); 515 int umidi20_jack_init(const char *name); 516 517 /*--------------------------------------------------------------------------* 518 * prototypes from "umidi20_coremidi.c" 519 *--------------------------------------------------------------------------*/ 520 const char **umidi20_coremidi_alloc_inputs(void); 521 const char **umidi20_coremidi_alloc_outputs(void); 522 void umidi20_coremidi_free_inputs(const char **); 523 void umidi20_coremidi_free_outputs(const char **); 524 525 int umidi20_coremidi_rx_open(uint8_t n, const char *name); 526 int umidi20_coremidi_tx_open(uint8_t n, const char *name); 527 int umidi20_coremidi_rx_close(uint8_t n); 528 int umidi20_coremidi_tx_close(uint8_t n); 529 int umidi20_coremidi_init(const char *name); 530 531 /*--------------------------------------------------------------------------* 532 * prototypes from "umidi20_android.c" 533 *--------------------------------------------------------------------------*/ 534 const char **umidi20_android_alloc_inputs(void); 535 const char **umidi20_android_alloc_outputs(void); 536 void umidi20_android_free_inputs(const char **); 537 void umidi20_android_free_outputs(const char **); 538 539 int umidi20_android_rx_open(uint8_t n, const char *name); 540 int umidi20_android_tx_open(uint8_t n, const char *name); 541 int umidi20_android_rx_close(uint8_t n); 542 int umidi20_android_tx_close(uint8_t n); 543 int umidi20_android_init(const char *name, void *context); 544 545 /*--------------------------------------------------------------------------* 546 * MIDI generator code 547 *--------------------------------------------------------------------------*/ 548 #define C0 0 549 #define D0B 1 550 #define D0 2 551 #define E0B 3 552 #define E0 4 553 #define F0 5 554 #define G0B 6 555 #define G0 7 556 #define A0B 8 557 #define A0 9 558 #define H0B 10 559 #define H0 11 560 561 #define C1 12 562 #define D1B 13 563 #define D1 14 564 #define E1B 15 565 #define E1 16 566 #define F1 17 567 #define G1B 18 568 #define G1 19 569 #define A1B 20 570 #define A1 21 571 #define H1B 22 572 #define H1 23 573 574 #define C2 24 575 #define D2B 25 576 #define D2 26 577 #define E2B 27 578 #define E2 28 579 #define F2 29 580 #define G2B 30 581 #define G2 31 582 #define A2B 32 583 #define A2 33 584 #define H2B 34 585 #define H2 35 586 587 #define C3 36 588 #define D3B 37 589 #define D3 38 590 #define E3B 39 591 #define E3 40 592 #define F3 41 593 #define G3B 42 594 #define G3 43 595 #define A3B 44 596 #define A3 45 597 #define H3B 46 598 #define H3 47 599 600 #define C4 48 601 #define D4B 49 602 #define D4 50 603 #define E4B 51 604 #define E4 52 605 #define F4 53 606 #define G4B 54 607 #define G4 55 608 #define A4B 56 609 #define A4 57 610 #define H4B 58 611 #define H4 59 612 613 #define C5 60 614 #define D5B 61 615 #define D5 62 616 #define E5B 63 617 #define E5 64 618 #define F5 65 619 #define G5B 66 620 #define G5 67 621 #define A5B 68 622 #define A5 69 623 #define H5B 70 624 #define H5 71 625 626 #define C6 72 627 #define D6B 73 628 #define D6 74 629 #define E6B 75 630 #define E6 76 631 #define F6 77 632 #define G6B 78 633 #define G6 79 634 #define A6B 80 635 #define A6 81 636 #define H6B 82 637 #define H6 83 638 639 #define C7 84 640 #define D7B 85 641 #define D7 86 642 #define E7B 87 643 #define E7 88 644 #define F7 89 645 #define G7B 90 646 #define G7 91 647 #define A7B 92 648 #define A7 93 649 #define H7B 94 650 #define H7 95 651 652 #define C8 96 653 #define D8B 97 654 #define D8 98 655 #define E8B 99 656 #define E8 100 657 #define F8 101 658 #define G8B 102 659 #define G8 103 660 #define A8B 104 661 #define A8 105 662 #define H8B 106 663 #define H8 107 664 665 #define C9 108 666 #define D9B 109 667 #define D9 110 668 #define E9B 111 669 #define E9 112 670 #define F9 113 671 #define G9B 114 672 #define G9 115 673 #define A9B 116 674 #define A9 117 675 #define H9B 118 676 #define H9 119 677 678 #define C10 120 679 #define D10B 121 680 #define D10 122 681 #define E10B 123 682 #define E10 124 683 #define F10 125 684 #define G10B 126 685 #define G10 127 686 687 /* Definition of channel numbers */ 688 689 #define TRACK_R 0 /* recording track */ 690 #define TRACK_A 1 691 #define TRACK_B 2 692 #define TRACK_C 3 693 #define TRACK_D 4 694 #define TRACK_E 5 695 #define TRACK_F 6 696 #define TRACK_G 7 697 #define TRACK_H 8 698 #define TRACK_P 9 /* percussion */ 699 700 struct mid_data { 701 struct umidi20_track *track; /* track we are generating */ 702 uint32_t position[16]; /* track position */ 703 uint32_t priv[16]; /* client counters */ 704 uint8_t channel; /* currently selected MIDI channel */ 705 uint8_t cc_enabled; /* carbon copy enabled */ 706 uint8_t cc_device_no; /* carbon copy device number */ 707 }; 708 709 extern const char *mid_key_str[128]; 710 void mid_set_device_no(struct mid_data *d, uint8_t device_no); 711 void mid_sort(uint8_t *pk, uint8_t nk); 712 void mid_trans(uint8_t *pk, uint8_t nk, int8_t nt); 713 uint8_t mid_add(uint8_t a, uint8_t b); 714 uint8_t mid_sub(uint8_t a, uint8_t b); 715 uint8_t mid_next_key(uint8_t a, int8_t n); 716 void mid_dump(struct mid_data *d); 717 void mid_add_raw(struct mid_data *d, const uint8_t *buf, uint32_t len, uint32_t offset); 718 uint32_t mid_get_position(struct mid_data *d); 719 void mid_set_position(struct mid_data *d, uint32_t pos); 720 uint32_t mid_delay(struct mid_data *d, int32_t off); 721 void mid_position_ceil(struct mid_data *d, uint16_t channel_mask); 722 void mid_position_floor(struct mid_data *d, uint16_t channel_mask); 723 void mid_delay_all(struct mid_data *d, int32_t off); 724 void mid_key_press(struct mid_data *d, uint8_t key, int8_t vel, uint32_t duration); 725 void mid_extended_key_press(struct mid_data *d, uint8_t key, uint32_t freq, int8_t vel, uint32_t duration); 726 void mid_extended_key_pitch(struct mid_data *d, uint8_t key, uint32_t freq); 727 void mid_extended_key_control(struct mid_data *d, uint8_t key, uint8_t control, uint32_t value); 728 void mid_key_press_n(struct mid_data *d, const uint8_t *pkey, uint8_t nkey, int8_t vel, uint32_t duration); 729 void mid_set_channel(struct mid_data *d, uint8_t channel); 730 uint8_t mid_get_channel(struct mid_data *d); 731 void mid_control(struct mid_data *d, uint8_t ctrl, uint8_t val); 732 void mid_pitch_bend(struct mid_data *d, uint16_t val); 733 void mid_pedal(struct mid_data *d, uint8_t on); 734 void mid_s_pedal(struct mid_data *d, int32_t db, int32_t dm, int32_t da, uint8_t on); 735 void mid_init(struct mid_data *d, struct umidi20_track *track); 736 void mid_set_bank_program(struct mid_data *d, uint8_t channel, uint16_t bank, uint8_t prog); 737 738 __END_DECLS 739 740 #endif /* _UMIDI20_H_ */ 741