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@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 #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