Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / sys / midiio.h @ 13

History | View | Annotate | Download (25.3 KB)

1 13 up20180614
/*        $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_ */