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