1 /* $NetBSD: midiio.h,v 1.15 2008/04/28 20:24:11 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (augustss@NetBSD.org) and (native API structures 9 * and macros) Chapman Flack (chap@NetBSD.org). 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef _SYS_MIDIIO_H_ 34 #define _SYS_MIDIIO_H_ 35 36 /* 37 * The API defined here produces events compatible with the OSS MIDI API at 38 * the binary level. 39 */ 40 41 #include <machine/endian_machdep.h> 42 43 /* 44 * ioctl() commands for /dev/midi## 45 * XXX is directly frobbing an MPU401 even supported? isn't it just run 46 * in UART mode? 47 */ 48 typedef struct { 49 unsigned char cmd; 50 char nr_args, nr_returns; 51 unsigned char data[30]; 52 } mpu_command_rec; 53 54 #define MIDI_PRETIME _IOWR('m', 0, int) 55 #define MIDI_MPUMODE _IOWR('m', 1, int) 56 #define MIDI_MPUCMD _IOWR('m', 2, mpu_command_rec) 57 58 59 /* The MPU401 command acknowledge and active sense command */ 60 #define MIDI_ACK 0xfe 61 62 63 /* Sequencer */ 64 #define SEQUENCER_RESET _IO ('Q', 0) 65 #define SEQUENCER_SYNC _IO ('Q', 1) 66 #define SEQUENCER_INFO _IOWR('Q', 2, struct synth_info) 67 #define SEQUENCER_CTRLRATE _IOWR('Q', 3, int) 68 #define SEQUENCER_GETOUTCOUNT _IOR ('Q', 4, int) 69 #define SEQUENCER_GETINCOUNT _IOR ('Q', 5, int) 70 /*#define SEQUENCER_PERCMODE _IOW ('Q', 6, int)*/ 71 /*#define SEQUENCER_TESTMIDI _IOW ('Q', 8, int)*/ 72 #define SEQUENCER_RESETSAMPLES _IOW ('Q', 9, int) 73 /* 74 * The sequencer at present makes no distinction between a 'synth' and a 'midi'. 75 * This is actually a cleaner layering than OSS: devices that are onboard 76 * synths just attach midi(4) via midisyn and present an ordinary MIDI face to 77 * the system. At present the same number is returned for NRSYNTHS and NRMIDIS 78 * but don't believe both, or you'll think you have twice as many devices as 79 * you really have. The MIDI_INFO ioctl isn't implemented; use SEQUENCER_INFO 80 * (which corresponds to OSS's SYNTH_INFO) to get information on any kind of 81 * device, though the struct synth_info it uses has some members that only 82 * pertain to synths (and get filled in with fixed, probably wrong values, 83 * anyway). 84 */ 85 #define SEQUENCER_NRSYNTHS _IOR ('Q',10, int) 86 #define SEQUENCER_NRMIDIS _IOR ('Q',11, int) 87 /*#define SEQUENCER_MIDI_INFO _IOWR('Q',12, struct midi_info)*/ 88 #define SEQUENCER_THRESHOLD _IOW ('Q',13, int) 89 #define SEQUENCER_MEMAVL _IOWR('Q',14, int) 90 /*#define SEQUENCER_FM_4OP_ENABLE _IOW ('Q',15, int)*/ 91 #define SEQUENCER_PANIC _IO ('Q',17) 92 #define SEQUENCER_OUTOFBAND _IOW ('Q',18, struct seq_event_rec) 93 #define SEQUENCER_GETTIME _IOR ('Q',19, int) 94 /*#define SEQUENCER_ID _IOWR('Q',20, struct synth_info)*/ 95 /*#define SEQUENCER_CONTROL _IOWR('Q',21, struct synth_control)*/ 96 /*#define SEQUENCER_REMOVESAMPLE _IOWR('Q',22, struct remove_sample)*/ 97 98 #if 0 99 typedef struct synth_control { 100 int devno; /* Synthesizer # */ 101 char data[4000]; /* Device specific command/data record */ 102 } synth_control; 103 104 typedef struct remove_sample { 105 int devno; /* Synthesizer # */ 106 int bankno; /* MIDI bank # (0=General MIDI) */ 107 int instrno; /* MIDI instrument number */ 108 } remove_sample; 109 #endif 110 111 #define CMDSIZE 8 112 typedef struct seq_event_rec { 113 u_char arr[CMDSIZE]; 114 } seq_event_rec; 115 116 struct synth_info { 117 char name[30]; 118 int device; 119 int synth_type; 120 #define SYNTH_TYPE_FM 0 121 #define SYNTH_TYPE_SAMPLE 1 122 #define SYNTH_TYPE_MIDI 2 123 124 int synth_subtype; 125 #define SYNTH_SUB_FM_TYPE_ADLIB 0x00 126 #define SYNTH_SUB_FM_TYPE_OPL3 0x01 127 #define SYNTH_SUB_MIDI_TYPE_MPU401 0x401 128 129 #define SYNTH_SUB_SAMPLE_TYPE_BASIC 0x10 130 #define SYNTH_SUB_SAMPLE_TYPE_GUS SAMPLE_TYPE_BASIC 131 132 int nr_voices; 133 int instr_bank_size; 134 u_int capabilities; 135 #define SYNTH_CAP_OPL3 0x00000002 136 #define SYNTH_CAP_INPUT 0x00000004 137 }; 138 139 /* Sequencer timer */ 140 #define SEQUENCER_TMR_TIMEBASE _IOWR('T', 1, int) 141 #define SEQUENCER_TMR_START _IO ('T', 2) 142 #define SEQUENCER_TMR_STOP _IO ('T', 3) 143 #define SEQUENCER_TMR_CONTINUE _IO ('T', 4) 144 #define SEQUENCER_TMR_TEMPO _IOWR('T', 5, int) 145 #define SEQUENCER_TMR_SOURCE _IOWR('T', 6, int) 146 # define SEQUENCER_TMR_INTERNAL 0x00000001 147 #if 0 148 # define SEQUENCER_TMR_EXTERNAL 0x00000002 149 # define SEQUENCER_TMR_MODE_MIDI 0x00000010 150 # define SEQUENCER_TMR_MODE_FSK 0x00000020 151 # define SEQUENCER_TMR_MODE_CLS 0x00000040 152 # define SEQUENCER_TMR_MODE_SMPTE 0x00000080 153 #endif 154 #define SEQUENCER_TMR_METRONOME _IOW ('T', 7, int) 155 #define SEQUENCER_TMR_SELECT _IOW ('T', 8, int) 156 157 158 #define MIDI_CTRL_BANK_SELECT_MSB 0 159 #define MIDI_CTRL_MODULATION_MSB 1 160 #define MIDI_CTRL_BREATH_MSB 2 161 #define MIDI_CTRL_FOOT_MSB 4 162 #define MIDI_CTRL_PORTAMENTO_TIME_MSB 5 163 #define MIDI_CTRL_DATA_ENTRY_MSB 6 164 #define MIDI_CTRL_CHANNEL_VOLUME_MSB 7 165 #define MIDI_CTRL_BALANCE_MSB 8 166 #define MIDI_CTRL_PAN_MSB 10 167 #define MIDI_CTRL_EXPRESSION_MSB 11 168 #define MIDI_CTRL_EFFECT_1_MSB 12 169 #define MIDI_CTRL_EFFECT_2_MSB 13 170 #define MIDI_CTRL_GENERAL_PURPOSE_1_MSB 16 171 #define MIDI_CTRL_GENERAL_PURPOSE_2_MSB 17 172 #define MIDI_CTRL_GENERAL_PURPOSE_3_MSB 18 173 #define MIDI_CTRL_GENERAL_PURPOSE_4_MSB 19 174 #define MIDI_CTRL_BANK_SELECT_LSB 32 175 #define MIDI_CTRL_MODULATION_LSB 33 176 #define MIDI_CTRL_BREATH_LSB 34 177 #define MIDI_CTRL_FOOT_LSB 36 178 #define MIDI_CTRL_PORTAMENTO_TIME_LSB 37 179 #define MIDI_CTRL_DATA_ENTRY_LSB 38 180 #define MIDI_CTRL_CHANNEL_VOLUME_LSB 39 181 #define MIDI_CTRL_BALANCE_LSB 40 182 #define MIDI_CTRL_PAN_LSB 42 183 #define MIDI_CTRL_EXPRESSION_LSB 43 184 #define MIDI_CTRL_EFFECT_1_LSB 44 185 #define MIDI_CTRL_EFFECT_2_LSB 45 186 #define MIDI_CTRL_GENERAL_PURPOSE_1_LSB 48 187 #define MIDI_CTRL_GENERAL_PURPOSE_2_LSB 49 188 #define MIDI_CTRL_GENERAL_PURPOSE_3_LSB 50 189 #define MIDI_CTRL_GENERAL_PURPOSE_4_LSB 51 190 #define MIDI_CTRL_HOLD_1 64 191 #define MIDI_CTRL_PORTAMENTO 65 192 #define MIDI_CTRL_SOSTENUTO 66 193 #define MIDI_CTRL_SOFT_PEDAL 67 194 #define MIDI_CTRL_LEGATO 68 195 #define MIDI_CTRL_HOLD_2 69 196 #define MIDI_CTRL_SOUND_VARIATION 70 197 #define MIDI_CTRL_HARMONIC_INTENSITY 71 198 #define MIDI_CTRL_RELEASE_TIME 72 199 #define MIDI_CTRL_ATTACK_TIME 73 200 #define MIDI_CTRL_BRIGHTNESS 74 201 #define MIDI_CTRL_DECAY_TIME 75 202 #define MIDI_CTRL_VIBRATO_RATE 76 203 #define MIDI_CTRL_VIBRATO_DEPTH 77 204 #define MIDI_CTRL_VIBRATO_DELAY 78 205 #define MIDI_CTRL_VIBRATO_DECAY MIDI_CTRL_VIBRATO_DELAY /*deprecated*/ 206 #define MIDI_CTRL_SOUND_10 79 207 #define MIDI_CTRL_GENERAL_PURPOSE_5 80 208 #define MIDI_CTRL_GENERAL_PURPOSE_6 81 209 #define MIDI_CTRL_GENERAL_PURPOSE_7 82 210 #define MIDI_CTRL_GENERAL_PURPOSE_8 83 211 #define MIDI_CTRL_PORTAMENTO_CONTROL 84 212 #define MIDI_CTRL_EFFECT_DEPTH_1 91 213 #define MIDI_CTRL_EFFECT_DEPTH_2 92 214 #define MIDI_CTRL_EFFECT_DEPTH_3 93 215 #define MIDI_CTRL_EFFECT_DEPTH_4 94 216 #define MIDI_CTRL_EFFECT_DEPTH_5 95 217 #define MIDI_CTRL_RPN_INCREMENT 96 218 #define MIDI_CTRL_RPN_DECREMENT 97 219 #define MIDI_CTRL_NRPN_LSB 98 220 #define MIDI_CTRL_NRPN_MSB 99 221 #define MIDI_CTRL_RPN_LSB 100 222 #define MIDI_CTRL_RPN_MSB 101 223 #define MIDI_CTRL_SOUND_OFF 120 224 #define MIDI_CTRL_RESET 121 225 #define MIDI_CTRL_LOCAL 122 226 #define MIDI_CTRL_NOTES_OFF 123 227 #define MIDI_CTRL_ALLOFF MIDI_CTRL_NOTES_OFF /*deprecated*/ 228 #define MIDI_CTRL_OMNI_OFF 124 229 #define MIDI_CTRL_OMNI_ON 125 230 #define MIDI_CTRL_POLY_OFF 126 231 #define MIDI_CTRL_POLY_ON 127 232 233 #define MIDI_BEND_NEUTRAL (1<<13) 234 235 #define MIDI_RPN_PITCH_BEND_SENSITIVITY 0 236 #define MIDI_RPN_CHANNEL_FINE_TUNING 1 237 #define MIDI_RPN_CHANNEL_COARSE_TUNING 2 238 #define MIDI_RPN_TUNING_PROGRAM_CHANGE 3 239 #define MIDI_RPN_TUNING_BANK_SELECT 4 240 #define MIDI_RPN_MODULATION_DEPTH_RANGE 5 241 242 #define MIDI_NOTEOFF 0x80 243 #define MIDI_NOTEON 0x90 244 #define MIDI_KEY_PRESSURE 0xA0 245 #define MIDI_CTL_CHANGE 0xB0 246 #define MIDI_PGM_CHANGE 0xC0 247 #define MIDI_CHN_PRESSURE 0xD0 248 #define MIDI_PITCH_BEND 0xE0 249 #define MIDI_SYSTEM_PREFIX 0xF0 250 251 #define MIDI_IS_STATUS(d) ((d) >= 0x80) 252 #define MIDI_IS_COMMON(d) ((d) >= 0xf0) 253 254 #define MIDI_SYSEX_START 0xF0 255 #define MIDI_SYSEX_END 0xF7 256 257 #define MIDI_GET_STATUS(d) ((d) & 0xf0) 258 #define MIDI_GET_CHAN(d) ((d) & 0x0f) 259 260 #define MIDI_HALF_VEL 64 261 262 #define SEQ_LOCAL 0x80 263 #define SEQ_TIMING 0x81 264 #define SEQ_CHN_COMMON 0x92 265 #define SEQ_CHN_VOICE 0x93 266 #define SEQ_SYSEX 0x94 267 #define SEQ_FULLSIZE 0xfd 268 269 #define SEQ_MK_CHN_VOICE(e, unit, cmd, chan, key, vel) (\ 270 (e)->arr[0] = SEQ_CHN_VOICE, (e)->arr[1] = (unit), (e)->arr[2] = (cmd),\ 271 (e)->arr[3] = (chan), (e)->arr[4] = (key), (e)->arr[5] = (vel),\ 272 (e)->arr[6] = 0, (e)->arr[7] = 0) 273 #define SEQ_MK_CHN_COMMON(e, unit, cmd, chan, p1, p2, w14) (\ 274 (e)->arr[0] = SEQ_CHN_COMMON, (e)->arr[1] = (unit), (e)->arr[2] = (cmd),\ 275 (e)->arr[3] = (chan), (e)->arr[4] = (p1), (e)->arr[5] = (p2),\ 276 *(short*)&(e)->arr[6] = (w14)) 277 278 #if _BYTE_ORDER == _BIG_ENDIAN 279 /* big endian */ 280 #define SEQ_PATCHKEY(id) (0xfd00|id) 281 #else 282 /* little endian */ 283 #define SEQ_PATCHKEY(id) ((id<<8)|0xfd) 284 #endif 285 struct sysex_info { 286 uint16_t key; /* Use SYSEX_PATCH or MAUI_PATCH here */ 287 #define SEQ_SYSEX_PATCH SEQ_PATCHKEY(0x05) 288 #define SEQ_MAUI_PATCH SEQ_PATCHKEY(0x06) 289 int16_t device_no; /* Synthesizer number */ 290 int32_t len; /* Size of the sysex data in bytes */ 291 u_char data[1]; /* Sysex data starts here */ 292 }; 293 #define SEQ_SYSEX_HDRSIZE ((u_long)((struct sysex_info *)0)->data) 294 295 typedef unsigned char sbi_instr_data[32]; 296 struct sbi_instrument { 297 uint16_t key; /* FM_PATCH or OPL3_PATCH */ 298 #define SBI_FM_PATCH SEQ_PATCHKEY(0x01) 299 #define SBI_OPL3_PATCH SEQ_PATCHKEY(0x03) 300 int16_t device; 301 int32_t channel; 302 sbi_instr_data operators; 303 }; 304 305 #define TMR_RESET 0 /* beware: not an OSS event */ 306 #define TMR_WAIT_REL 1 /* Time relative to the prev time */ 307 #define TMR_WAIT_ABS 2 /* Absolute time since TMR_START */ 308 #define TMR_STOP 3 309 #define TMR_START 4 310 #define TMR_CONTINUE 5 311 #define TMR_TEMPO 6 312 #define TMR_ECHO 8 313 #define TMR_CLOCK 9 /* MIDI clock */ 314 #define TMR_SPP 10 /* Song position pointer */ 315 #define TMR_TIMESIG 11 /* Time signature */ 316 317 /* Old sequencer definitions */ 318 #define SEQOLD_CMDSIZE 4 319 320 #define SEQOLD_NOTEOFF 0 321 #define SEQOLD_NOTEON 1 322 #define SEQOLD_WAIT TMR_WAIT_ABS 323 #define SEQOLD_PGMCHANGE 3 324 #define SEQOLD_SYNCTIMER TMR_START 325 #define SEQOLD_MIDIPUTC 5 326 #define SEQOLD_ECHO TMR_ECHO 327 #define SEQOLD_AFTERTOUCH 9 328 #define SEQOLD_CONTROLLER 10 329 #define SEQOLD_PRIVATE 0xfe 330 #define SEQOLD_EXTENDED 0xff 331 332 /* 333 * The 'midipitch' data type, used in the kernel between the midisyn layer and 334 * onboard synth drivers, and in userland as parameters to the MIDI Tuning Spec 335 * (RP-012) universal-system-exclusive messages. It is a MIDI key number shifted 336 * left to accommodate 14 bit sub-semitone resolution. In this representation, 337 * tuning and bending adjustments are simple addition and subtraction. 338 */ 339 typedef int32_t midipitch_t; 340 341 /* 342 * Nominal conversions between midipitches and key numbers. (Beware that these 343 * are the nominal, standard correspondences, but whole point of the MIDI Tuning 344 * Spec is that you can set things up so the hardware might render key N at 345 * actual pitch MIDIPITCH_FROM_KEY(N)+c for some correction c.) 346 */ 347 #define MIDIPITCH_FROM_KEY(k) ((k)<<14) 348 #define MIDIPITCH_TO_KEY(mp) (((mp)+(1<<13))>>14) 349 350 #define MIDIPITCH_MAX (MIDIPITCH_FROM_KEY(128)-2) /* ...(128)-1 is reserved */ 351 #define MIDIPITCH_OCTAVE 196608 352 #define MIDIPITCH_SEMITONE 16384 353 #define MIDIPITCH_CENT 164 /* this, regrettably, is inexact. */ 354 355 /* 356 * For rendering, convert a midipitch (after all tuning adjustments) to Hz. 357 * The conversion is DEFINED as MIDI key 69.00000 (A) === 440 Hz equal tempered 358 * always. Alternate tunings are obtained by adjusting midipitches. 359 * 360 * The midihz18_t (Hz shifted left for 18-bit sub-Hz resolution) covers the 361 * full midipitch range without losing 21-bit precision, as the lowest midipitch 362 * is ~8 Hz (~3 bits left of radix point, 18 right) and for the highest the 363 * result still fits in a uint32. 364 */ 365 typedef uint32_t midihz18_t; 366 367 #define MIDIHZ18_TO_HZ(h18) ((h18)>>18) /* truncates! ok for dbg msgs maybe */ 368 369 #ifndef _KERNEL 370 /* 371 * With floating point in userland, can also manipulate midipitches as 372 * floating-point fractional MIDI key numbers (tuning adjustments are still 373 * additive), and hz18 as fractional Hz (adjustments don't add in this form). 374 */ 375 #include <math.h> 376 #define MIDIPITCH_TO_FRKEY(mp) (scalbn((mp),-14)) 377 #define MIDIPITCH_FROM_FRKEY(frk) ((midipitch_t)round(scalbn((frk),14))) 378 #define MIDIHZ18_TO_FRHZ(h18) (scalbn((h18),-18)) 379 #define MIDIHZ18_FROM_FRHZ(frh) ((midihz18_t)round(scalbn((frh),18))) 380 381 #define MIDIPITCH_TO_FRHZ(mp) (440*pow(2,(MIDIPITCH_TO_FRKEY((mp))-69)/12)) 382 #define MIDIPITCH_FROM_FRHZ(fhz) \ 383 MIDIPITCH_FROM_FRKEY(69+12*log((fhz)/440)/log(2)) 384 #define MIDIPITCH_TO_HZ18(mp) MIDIHZ18_FROM_FRHZ(MIDIPITCH_TO_FRHZ((mp))) 385 #define MIDIPITCH_FROM_HZ18(h18) MIDIPITCH_FROM_FRHZ(MIDIHZ18_TO_FRHZ((h18))) 386 387 #else /* no fp in kernel; only an accurate to-hz18 conversion is implemented */ 388 389 extern midihz18_t midisyn_mp2hz18(midipitch_t); 390 #define MIDIPITCH_TO_HZ18(mp) (midisyn_mp2hz18((mp))) 391 392 #endif /* _KERNEL */ 393 394 395 /* 396 * A native API for the /dev/music sequencer device follows. The event 397 * structures are OSS events at the level of bytes, but for developing or 398 * porting applications some macros and documentation are needed to generate 399 * and dissect the events; here they are. For porting existing OSS applications, 400 * sys/soundcard.h can be extended to supply the usual OSS macros, defining them 401 * in terms of these. 402 */ 403 404 /* 405 * TODO: determine OSS compatible structures for TMR_RESET and TMR_CLOCK, 406 * OSS values of EV_SYSTEM, SNDCTL_SEQ_ACTSENSE_ENABLE, 407 * SNDCTL_SEQ_TIMING_ENABLE, and SNDCTL_SEQ_RT_ENABLE. 408 * (TMR_RESET may be a NetBSD extension: it is generated in sequencer.c and 409 * has no args. To be corrected if a different definition is found anywhere.) 410 */ 411 typedef union { 412 413 #define _EVT_HDR \ 414 uint8_t tag 415 416 _EVT_HDR; 417 418 #define _LOCAL_HDR \ 419 _EVT_HDR; \ 420 uint8_t op 421 422 struct { _LOCAL_HDR; } local; 423 424 struct { 425 _LOCAL_HDR; 426 uint16_t _zero; 427 uint32_t devmask; 428 } l_startaudio; 429 430 /* define a constructor for local evts - someday when we support any */ 431 432 #define _TIMING_HDR \ 433 _LOCAL_HDR; \ 434 uint16_t _zeroh 435 struct { _TIMING_HDR; } timing; 436 437 struct { 438 _TIMING_HDR; 439 uint32_t divisions; 440 } t_WAIT_REL, t_WAIT_ABS; 441 442 struct { 443 _TIMING_HDR; 444 uint32_t _zero; 445 } t_STOP, t_START, t_CONTINUE, t_RESET; 446 447 struct { 448 _TIMING_HDR; 449 uint32_t bpm; /* unambiguously, (MIDI clocks/minute)/24 */ 450 } t_TEMPO; 451 452 struct { 453 _TIMING_HDR; 454 uint32_t cookie; 455 } t_ECHO; 456 457 struct { 458 _TIMING_HDR; 459 uint32_t midibeat; /* in low 14 bits; midibeat: 6 MIDI clocks */ 460 } t_SPP; 461 462 struct { 463 _TIMING_HDR; 464 #if _BYTE_ORDER == _BIG_ENDIAN 465 uint8_t numerator; 466 uint8_t lg2denom; 467 uint8_t clks_per_click; 468 uint8_t dsq_per_24clks; 469 #elif _BYTE_ORDER == _LITTLE_ENDIAN 470 uint8_t dsq_per_24clks; 471 uint8_t clks_per_click; 472 uint8_t lg2denom; 473 uint8_t numerator; 474 #else 475 #error "unexpected _BYTE_ORDER" 476 #endif 477 } t_TIMESIG; 478 479 struct { /* use this only to implement OSS compatibility macro */ 480 _TIMING_HDR; 481 uint32_t signature; 482 } t_osscompat_timesig; 483 484 485 #define _COMMON_HDR \ 486 _EVT_HDR; \ 487 uint8_t device; \ 488 uint8_t op; \ 489 uint8_t channel 490 491 struct { _COMMON_HDR; } common; 492 493 struct { 494 _COMMON_HDR; 495 uint8_t controller; 496 uint8_t _zero; 497 uint16_t value; 498 } c_CTL_CHANGE; 499 500 struct { 501 _COMMON_HDR; 502 uint8_t program; 503 uint8_t _zero0; 504 uint16_t _zero1; 505 } c_PGM_CHANGE; 506 507 struct { 508 _COMMON_HDR; 509 uint8_t pressure; 510 uint8_t _zero0; 511 uint16_t _zero1; 512 } c_CHN_PRESSURE; 513 514 struct { 515 _COMMON_HDR; 516 uint8_t _zero0; 517 uint8_t _zero1; 518 uint16_t value; 519 } c_PITCH_BEND; 520 521 #define _VOICE_HDR \ 522 _COMMON_HDR; \ 523 uint8_t key 524 525 struct { _VOICE_HDR; } voice; 526 527 struct { 528 _VOICE_HDR; 529 uint8_t velocity; 530 uint16_t _zero; 531 } c_NOTEOFF, c_NOTEON; 532 533 struct { 534 _VOICE_HDR; 535 uint8_t pressure; 536 uint16_t _zero; 537 } c_KEY_PRESSURE; 538 539 struct { 540 _EVT_HDR; 541 uint8_t device; 542 uint8_t buffer[6]; 543 } sysex; 544 545 struct { 546 _EVT_HDR; 547 uint8_t device; 548 uint8_t status; 549 uint8_t data[2]; 550 } system; 551 552 struct { 553 _EVT_HDR; 554 uint8_t byte; 555 uint8_t device; 556 uint8_t _zero0; 557 uint32_t _zero1; 558 } putc; /* a seqold event that's still needed at times, ugly as 'tis */ 559 560 struct { 561 _EVT_HDR; 562 uint8_t byte[7]; 563 } unknown; /* for debug/display */ 564 565 #undef _VOICE_HDR 566 #undef _COMMON_HDR 567 #undef _TIMING_HDR 568 #undef _LOCAL_HDR 569 #undef _EVT_HDR 570 571 } __packed seq_event_t; 572 573 #define _SEQ_TAG_NOTEOFF SEQ_CHN_VOICE 574 #define _SEQ_TAG_NOTEON SEQ_CHN_VOICE 575 #define _SEQ_TAG_KEY_PRESSURE SEQ_CHN_VOICE 576 577 #define _SEQ_TAG_CTL_CHANGE SEQ_CHN_COMMON 578 #define _SEQ_TAG_PGM_CHANGE SEQ_CHN_COMMON 579 #define _SEQ_TAG_CHN_PRESSURE SEQ_CHN_COMMON 580 #define _SEQ_TAG_PITCH_BEND SEQ_CHN_COMMON 581 582 #if __STDC_VERSION__ >= 199901L 583 584 #define SEQ_MK_EVENT(_member,_tag,...) \ 585 (seq_event_t){ ._member = { .tag = (_tag), __VA_ARGS__ } } 586 587 #define SEQ_MK_TIMING(_op,...) \ 588 SEQ_MK_EVENT(t_##_op, SEQ_TIMING, .op = TMR_##_op, __VA_ARGS__) 589 590 #define SEQ_MK_CHN(_op,...) \ 591 SEQ_MK_EVENT(c_##_op, _SEQ_TAG_##_op, .op = MIDI_##_op, __VA_ARGS__) 592 593 #define SEQ_MK_SYSEX(_dev,...) \ 594 SEQ_MK_EVENT(sysex, 0x94, .device=(_dev), \ 595 .buffer={0xff, 0xff, 0xff, 0xff, 0xff, 0xff, __VA_ARGS__}) 596 597 #else /* assume gcc 2.95.3 */ 598 599 #define SEQ_MK_EVENT(_member,_tag,_args...) \ 600 (seq_event_t){ ._member = { .tag = (_tag), _args } } 601 602 #define SEQ_MK_TIMING(_op,_args...) \ 603 SEQ_MK_EVENT(t_##_op, SEQ_TIMING, .op = TMR_##_op, _args) 604 605 #define SEQ_MK_CHN(_op,_args...) \ 606 SEQ_MK_EVENT(c_##_op, _SEQ_TAG_##_op, .op = MIDI_##_op, _args) 607 608 #define SEQ_MK_SYSEX(_dev,_args...) \ 609 SEQ_MK_EVENT(sysex, 0x94, .device=(_dev), \ 610 .buffer={0xff, 0xff, 0xff, 0xff, 0xff, 0xff, _args}) 611 612 #endif /* c99 vs. gcc 2.95.3 */ 613 614 #if 0 615 #include <fcntl.h> 616 #include <stdio.h> 617 int 618 main(int argc, char **argv) 619 { 620 int i; 621 int fd; 622 seq_event_t e; 623 624 /* simple usage example (add a buffer to reduce syscall overhead) */ 625 fd = open("/dev/music", O_RDWR); 626 write(fd, &SEQ_MK_TIMING(START), sizeof (seq_event_t)); 627 628 read(fd, &e, sizeof e); 629 switch ( e.tag ) { 630 case SEQ_CHN_VOICE: 631 switch ( e.voice.op ) { 632 case MIDI_NOTEON: 633 printf("Note on, dev=%d chn=%d key=%d vel=%d\n", 634 e.c_NOTEON.device, e.c_NOTEON.channel, 635 e.c_NOTEON.key, e.c_NOTEON.velocity); 636 } 637 } 638 639 /* all the macros: */ 640 e = SEQ_MK_TIMING(START); 641 e = SEQ_MK_TIMING(STOP); 642 e = SEQ_MK_TIMING(CONTINUE); 643 /* 644 * Wait until the specified number of divisions from the timer start 645 * (abs) or the preceding event (rel). The number of divisions to a 646 * beat or to a MIDI clock is determined by the timebase (set by 647 * ioctl). The tempo is expressed in beats per minute, where a beat 648 * is always 24 MIDI clocks (and usually equated to a quarter note, 649 * but that can be changed with timesig)--that is, tempo is 650 * (MIDI clocks per minute)/24. The timebase is the number of divisions 651 * in a beat--that is, the number of divisions that make up 24 MIDI 652 * clocks--so the timebase is 24*(divisions per MIDI clock). The MThd 653 * header in a SMF gives the 'natural' timebase for the file; if the 654 * timebase is set accordingly, then the delay values appearing in the 655 * tracks are in terms of divisions, and can be used as WAIT_REL 656 * arguments without modification. 657 */ 658 e = SEQ_MK_TIMING(WAIT_ABS, .divisions=192); 659 e = SEQ_MK_TIMING(WAIT_REL, .divisions=192); 660 /* 661 * The 'beat' in bpm is 24 MIDI clocks (usually a quarter note but 662 * changeable with timesig). 663 */ 664 e = SEQ_MK_TIMING(TEMPO, .bpm=84); 665 /* 666 * An ECHO event on output appears on input at the appointed time; the 667 * cookie can be anything of interest to the application. Can be used 668 * in schemes to get some control over latency. 669 */ 670 e = SEQ_MK_TIMING(ECHO, .cookie=0xfeedface); 671 /* 672 * A midibeat is smaller than a beat. It is six MIDI clocks, or a fourth 673 * of a beat, or a sixteenth note if the beat is a quarter. SPP is a 674 * request to position at the requested midibeat from the start of the 675 * sequence. [sequencer does not at present implement SPP] 676 */ 677 e = SEQ_MK_TIMING(SPP, .midibeat=128); 678 /* 679 * numerator and lg2denom describe the time signature as it would 680 * appear on a staff, where lg2denom of 0,1,2,3... corresponds to 681 * denominator of 1,2,4,8... respectively. So the example below 682 * corresponds to 4/4. dsq_per_24clks defines the relationship of 683 * MIDI clocks to note values, by specifying the number of 684 * demisemiquavers (32nd notes) represented by 24 MIDI clocks. 685 * The default is 8 demisemiquavers, or a quarter note. 686 * clks_per_click can configure a metronome (for example, the MPU401 687 * had such a feature in intelligent mode) to click every so many 688 * MIDI clocks. The 24 in this example would give a click every quarter 689 * note. [sequencer does not at present implement TIMESIG] 690 */ 691 e = SEQ_MK_TIMING(TIMESIG, .numerator=4, .lg2denom=2, 692 .clks_per_click=24, .dsq_per_24clks=8); 693 /* 694 * This example declares 6/8 time where the beat (24 clocks) is the 695 * eighth note, but the metronome clicks every dotted quarter (twice 696 * per measure): 697 */ 698 e = SEQ_MK_TIMING(TIMESIG, .numerator=6, .lg2denom=3, 699 .clks_per_click=72, .dsq_per_24clks=4); 700 /* 701 * An alternate declaration for 6/8 where the beat (24 clocks) is now 702 * the dotted quarter and corresponds to the metronome click: 703 */ 704 e = SEQ_MK_TIMING(TIMESIG, .numerator=6, .lg2denom=3, 705 .clks_per_click=24, .dsq_per_24clks=12); 706 /* 707 * It would also be possible to keep the default correspondence of 708 * 24 clocks to the quarter note (8 dsq), and still click the metronome 709 * each dotted quarter: 710 */ 711 e = SEQ_MK_TIMING(TIMESIG, .numerator=6, .lg2denom=3, 712 .clks_per_click=36, .dsq_per_24clks=8); 713 714 e = SEQ_MK_CHN(NOTEON, .device=1, .channel=0, .key=60, .velocity=64); 715 e = SEQ_MK_CHN(NOTEOFF, .device=1, .channel=0, .key=60, .velocity=64); 716 e = SEQ_MK_CHN(KEY_PRESSURE, .device=1, .channel=0, .key=60, 717 .pressure=64); 718 719 /* 720 * sequencer does not at present implement CTL_CHANGE well. The API 721 * provides for a 14-bit value where you give the controller index 722 * of the controller MSB and sequencer will split the 14-bit value to 723 * the controller MSB and LSB for you--but it doesn't; it ignores the 724 * high bits of value and writes the low bits whether you have specified 725 * MSB or LSB. That would not be hard to fix but for the fact that OSS 726 * itself seems to suffer from the same mixup (and its behavior differs 727 * with whether the underlying device is an onboard synth or a MIDI 728 * link!) so there is surely a lot of code that relies on it being 729 * broken :(. 730 * (Note: as the OSS developers have ceased development of the 731 * /dev/music API as of OSS4, it would be possible given a complete 732 * list of the events defined in OSS4 to add some new ones for native 733 * use without fear of future conflict, such as a better ctl_change.) 734 */ 735 e = SEQ_MK_CHN(CTL_CHANGE, .device=1, .channel=0, 736 .controller=MIDI_CTRL_EXPRESSION_MSB, .value=8192);/*XX*/ 737 /* 738 * The way you really have to do it: 739 */ 740 e = SEQ_MK_CHN(CTL_CHANGE, .device=1, .channel=0, 741 .controller=MIDI_CTRL_EXPRESSION_MSB, .value=8192>>7); 742 e = SEQ_MK_CHN(CTL_CHANGE, .device=1, .channel=0, 743 .controller=MIDI_CTRL_EXPRESSION_LSB, .value=8192&0x7f); 744 745 e = SEQ_MK_CHN(PGM_CHANGE, .device=1, .channel=0, .program=51); 746 e = SEQ_MK_CHN(CHN_PRESSURE, .device=1, .channel=0, .pressure=64); 747 e = SEQ_MK_CHN(PITCH_BEND, .device=1, .channel=0, .value=8192); 748 749 /* 750 * A SYSEX event carries up to six bytes of a system exclusive message. 751 * The first such message must begin with MIDI_SYSEX_START (0xf0), the 752 * last must end with MIDI_SYSEX_END (0xf7), and only the last may carry 753 * fewer than 6 bytes. To supply message bytes in the macro, you must 754 * prefix the first with [0]= as shown. The macro's first argument is 755 * the device. 756 */ 757 e = SEQ_MK_SYSEX(1,[0]=MIDI_SYSEX_START,1,2,MIDI_SYSEX_END); 758 /* 759 * In some cases it may be easier to use the macro only to initialize 760 * the event, and fill in the message bytes later. The code that fills 761 * in the message does not need to store 0xff following the SYSEX_END. 762 */ 763 e = SEQ_MK_SYSEX(1); 764 for ( i = 0; i < 3; ++ i ) 765 e.sysex.buffer[i] = i; 766 /* 767 * It would be nice to think the old /dev/sequencer MIDIPUTC event 768 * obsolete, but it is still needed (absent any better API) by any MIDI 769 * file player that will implement the ESCAPED events that may occur in 770 * SMF. Sorry. Here's how to use it: 771 */ 772 e = SEQ_MK_EVENT(putc, SEQOLD_MIDIPUTC, .device=1, .byte=42); 773 774 printf("confirm event size: %d (should be 8)\n", sizeof (seq_event_t)); 775 return 0; 776 } 777 #endif /* 0 */ 778 779 #endif /* !_SYS_MIDIIO_H_ */ 780