master
  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 */
 49typedef 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
100typedef struct synth_control {
101	int	devno;		/* Synthesizer # */
102	char	data[4000];	/* Device specific command/data record */
103} synth_control;
104
105typedef 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
113typedef struct seq_event_rec {
114	u_char	arr[CMDSIZE];
115} seq_event_rec;
116
117struct 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
286struct 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
296typedef unsigned char sbi_instr_data[32];
297struct 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 */
340typedef 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 */
366typedef 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
390extern 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 */
412typedef 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,...)						\
589SEQ_MK_EVENT(t_##_op, SEQ_TIMING, .op = TMR_##_op, __VA_ARGS__)
590
591#define SEQ_MK_CHN(_op,...)						\
592SEQ_MK_EVENT(c_##_op, _SEQ_TAG_##_op, .op = MIDI_##_op, __VA_ARGS__)
593
594#define SEQ_MK_SYSEX(_dev,...)						\
595SEQ_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...)						\
604SEQ_MK_EVENT(t_##_op, SEQ_TIMING, .op = TMR_##_op, _args)
605
606#define SEQ_MK_CHN(_op,_args...)					\
607SEQ_MK_EVENT(c_##_op, _SEQ_TAG_##_op, .op = MIDI_##_op, _args)
608
609#define SEQ_MK_SYSEX(_dev,_args...)						\
610SEQ_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>
618int
619main(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_ */