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

Cache object: e5ead6430bc5da32dda70eb63aaa9901


[ 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.