The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sys/midiio.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 08e91af1742a6697b2c7db69beca2f81


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.